$ sqlplus "sys/password as sysdba"

SQL> alter system set processes=150 scope=spfile;
System altered.

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup
ORACLE instance started.

Total System Global Area  603979776 bytes
Fixed Size                  1260292 bytes
Variable Size             163579132 bytes
Database Buffers          436207616 bytes
Redo Buffers                2932736 bytes
Database mounted.
Database opened.

Sitemesh 2.4.1 버전은 기존의 PageFilter가 SitemeshFilter로 바뀌었다.

이번 버전에서는 아래와 같은 에러가 데코레이션 되는 URL에서는 발생하지 않지만 데코레이션 되지 않는 URL에서는 여전히 발생한다.

ProtocolException : Didn't meet stated Content-Length

Sitemesh 이전 버전에서의 해결방법은 http://finkle.tistory.com/56 게시글 참조

Sitemesh 2.4.1 버전에서 해결방법은 아래와 같다.
com.opensymphony.sitemesh.webapp.decorator.NoDecorator 클래스를 아래와 같이 수정한다.

if (Container.get() != Container.WEBLOGIC) {
    response.setContentLength(content.originalLength());
}

또 하나, 보통 SpringMVC 3.0에서 Annotation을 통해 JSTL View를 지정하여 화면을 렌더링 하는데 Sitemesh 데코레이션 파일에 설정된 URL을 Weblogic에서는 제대로 인식하지 못한다.

아래 설정정보는 Tomcat에서 잘 작동하는 데코레이션 설정인데 Weblogic에서는 데코레이션 되지 않는다.

decoration.xml

<decorator name="xxxx_manage" page="xxxx/common/decorator/xxxx_manage.jsp">
    <pattern>/manage/**/xxxx_*.do</pattern>
</decorator>

해결방법은 아래와 같다.

<decorator name="xxxx_manage" page="manage/common/decorator/xxxx_manage.jsp">
    <pattern>/manage/**/xxxx_*.do</pattern>
    <pattern>/WEB-INF/view/manage/**/xxxx_*</pattern> <!-- For weblogic -->
</decorator>


ANT 빌드 스크립트에서 아래와 같이 Tomcat 재기동 작업을 설정 후 Hudson에 연결했을 경우 생성되는 Hudosn 하위 프로세스가 종료되지 않고 대기하는 문제가 발생한다.

<target name="tomcat.stop" >
    <echo>Stopping Tomcat server instance</echo>
    <exec executable="/etc/init.d/tomcat6">
       <arg value="stop" />
    </exec>
</target>

<target name="tomcat.restart" depends="tomcat.stop">
    <sleep seconds="2" />
    <echo>Starting Tomcat server instance</echo>
    <exec executable="/etc/init.d/tomcat6" spawn="true">
        <arg value="start" />
    </exec>
</target>

spawn :  하위 프로세스를 생성해서 실행하는 옵션

이런 경우에는 hudson 실행 스크립트에서 아래와 같은 옵션을 주어 해결하자.

-Dhudson.util.ProcessTreeKiller.disable=true

10g XE에서 잘 돌아가던 넘이 운영서버 환경에 올리자 CLOB 등록이 안된다.

iBatis 단독 사용 시 CLOB 넣기

sqlmap-config.xml

<typeHandler javaType="string" jdbcType="CLOB" callback="test.OracleClobStringTypeHandler"/>
 
<transactionManager type="JDBC">
    <dataSource type="SIMPLE">
        <property name="JDBC.Driver" value="oracle.jdbc.driver.OracleDriver" />
        <property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@xxxxx:1521:SID" />
        <property name="JDBC.Username" value="${ID}" />
        <property name="JDBC.Password" value="${PASS}" />
    </dataSource>
</transactionManager>

logic-sqlmap.xml

INSERT INTO TABLE_NAME (
    SEQ, TITLE, CONTENTS
)
VALUES(
    #seq#, #title#, #contents:CLOB#
)

iBatis + Spring단독 사용 시 CLOB 넣기

application-context.xml

<bean id="dataSource"
    class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="java:comp/env/jdbc/jndiNameDS"/>
</bean>

<bean id="sqlMapClient"
    class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    <property name="configLocation" value="WEB-INF/conf/sqlmap-config.xml" />
    <property name="dataSource" ref="dataSource" />
    <property name="lobHandler"><ref bean="oracleLobhandler"/></property>
</bean>

<bean id="nativeJdbcExtractor"
    class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor"
    lazy-init="true" />

<bean id="oracleLobhandler"
    class="org.springframework.jdbc.support.lob.OracleLobHandler"
    lazy-init="true">
    <property name="nativeJdbcExtractor">
        <ref local="nativeJdbcExtractor" />
    </property>
</bean>

sqlmap-config.xml

<typeHandler
    callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler"
    jdbcType="CLOB" javaType="java.lang.String" />

logic-sqlmap.xml

INSERT INTO TABLE_NAME (
    SEQ, TITLE, CONTENTS
)
VALUES(
    #seq#, #title#, #contents:CLOB#
)

java.lang.NullPointerException at org.springframework.jdbc.support.lob.OracleLobHandler.initOracleDriverClasses(OracleLobHandler.java:150
) 에러 발생 시


application-context.xml

JNDI -> DBCP로 변경
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
     <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
     <property name="url" value="jdbc:oracle:thin:@xxxx:1521:SID" />
     <property name="username" value="${ID}" />
     <property name="password" value="${PASS}" />
     <parameter name="maxActive" value="20" />
     <parameter name="maxIdle" value="5" />
     <parameter name="maxWait" value="5000" />
     <property name="validationQuery" value="SELECT 1 FROM DUAL" />
</bean>

Oracle JDBC 드라이버는 ojdbc14.jar (최신버전)으로 적용.

ExtJS를 실무에 적용하고자 기술검토를 통해 파일럿 프로그램을 개발하고, 실무(회사 솔루션)에 적용해본 지 약 2개월이 지나가고 있다. 그간 개발하면서 ExtJS에 대해 느껴왔던 점에 대해 기록해본다.

제일 처음에는 GWT(Google Web Toolkit)에 기반한 GXT를 내려받아 적용해 봤는데 아래와 같은 문제점이 있었다.

GXT 적용기

1. 소스 변경 후 화면을 통해 바로바로 확인하는 웹 프로그램의 특성상 기본적으로 JavaScript로의 컴파일을 통해 화면을 생성하는 GXT는 일반 JSP 작업보다 생산성면에서 불편했다. - 물론 이것은 GWT 기반이기 때문에 피할 수 없는 문제다.
(특히 내 컴터의 512MB + 256MB 메모리로는 이클립스와 같이 돌리기에는 쿨러돌아가는 소리가 너무 크다 ㅠㅠ)

2. 화면 레이아웃을 잡는데 너무 많은 고통이 수반된다.
GXT에서 모든 화면 레이아웃은 Layout 클래스를 이용해 만들어야 한다. 예전에 Swing이나 AWT 이용해 화면 UI를 만들어봤던 나도 이 작업은 너무 어렵고 힘들었다. 복잡한 화면을 표현해야 하는 웹 프로그램의 특성 상 어찌보면 이 부분은 GXT를 이용해 개발해야 할 경우 넘어야할 가장 큰 산인듯 싶다.

3. 크로스 브라우징 - 국내 웹 개발자에게 늘 삽질의 은공(?)를 제공하는 IE가 항상 문제다. 파이어폭스하고 크롬에서는 정상으로 보이나 IE는 6, 7, 8 버전별로 모양새가 다 다르게 나온다. ㅠㅠ  CSS 삽질이 필수로 요구된다.

도입하는데 부닥친 가장 큰 문제는 크게 위 3개로 요약된다. 기타 자잘한 문제는 GWT가 기본적으로 가지고 있는 문제이므로 별도 언급하지는 않겠다.

ExtJS 적용기

ExtJS는 그 자체가 JavaScript 이기 때문에 GXT가진 1번 문제는 해결된다.
아울러, 화면 레이아웃은 JSON(JavaScript Object Notaion) 형식으로 꾸며나가면 되는데 초기 학습비용은 높은 편이나 몇개의 산을 넘다보면 익숙해지는데 오랜 시간이 걸리지는 않는다.

역시나 크로스 브라우징 문제는 ExtJS에서도 발생했다. 그러나 몇가지 수동으로 패치작업을 해주면 IE에서도 원하는 모양으로 표시되도록 할 수 있는데 배포사에서 이 부분을 좀 신경써 주었으면 좋겠다. (ExtJS 상용 라이센스를 구입하는 사람도 있으므로 ....)

다음은 ExtJS에 익숙해지기 위한 필수 지식이다.

1. JavaScript - 너무 당연하다.
2. JSON - ExtJS에서는 거의 대부분의 코딩작업을 JSON 형식으로 선언하며, 심지어 서버에서 처리한 결과 조차도 JSON으로 받아 화면에 표시하게 된다. (물론 사용자가 선택할 수는 있다.)
3. ExtJS API - 항상 곁에두고 참조해야 한다. 특정 객체의 프로퍼티, 메소드, 이벤트 등을 알고 사용하기 위해서는 어쩔 수 없다. Java 프로그래밍 할때의 Code Insight 기능은 JSON 형식을 사용하는 ExtJS에서 한계가 있기 때문에 API는 개발을 마칠때까지 수시로 참고해야 된다.

다음은 내가 느꼈던 ExtJS의 장점이다.

1. 초기 학습비용은 매우 높은 편이나 익숙해지면 개발생산성이 약 2배이상 향상된다.
2. 지저분한 UI 코드가 사라지고, 장문의 HTML 코드를 이용하는 일이 거의 없어진다.
3. ExtJS 배포 컴포넌트 만으로 다양한 UI를 구현하는데에는 한계가 분명히 있다. 그러나, 수많은 이용자들이 공개한 다양한 플러그인을 사용한다면 웬만한 UI 나 업무처리를 구현하는데 문제가 없다.

결론

시간이 충분치 않거나 팀원들의 학습능력이 받쳐주지 않을 경우 함부로 ExtJS를 도입하지 말 것을 권장한다. Java프로그래밍을 잘 하는 것과 JavaScript를 잘하는 것은 전혀 별개의 영역이다.
그러나, 개발시간에 여유가 있고 참여하는 팀원들의 지적욕구가 충만하다면 ExtJS는 충분히 도입할 만한 가치가 있는 UI 기술이다.

초기 학습비용이 다른 기술에 비해 높은 편이지만 일단 JSON 형식과 API에 익숙해지면 기존에 MVC 프레임웍의 View 기술을 대체할만한 매력이 충분한 녀석이다. 특히 UI 개발시간이 단축된다는 점과 지저분한 UI 코드가 사라진다는 점이 특히 매력적이다. (노파심에 언급하자면 ExtJS는 Model, Controller 영역하고는 무관한 기술이다)

자, 당신의 선택은 무엇인가?


※ 참고 : 회사에서 적용한 ExtJS 기반의 솔루션 기술 일람

UI단 : ExtJS, JSP(with taglib, Sitemesh)
Server단 : Spring, iBatis (MVC 컨트롤러는 ExtJS에 맞게 별도로 개발함)
WAS : Tomcat 5.X
DB : Oracle 10g XE
기타 : Jakarta commons, Log4j 외

+ Recent posts