잊지 않겠습니다.

maven에서 제공하는 maven-archetype-webapp 의 경우, 최신 eclipse인 JUNO와 tomcat7에서 동작하지 않는 문제가 있다. 

기본적으로, java 버젼을 1.4로, jst.web 버젼을 2.4로 잡아버리기 때문에 발생하는 문제인데, 이를 해결하기 위해서는 m2eclipse와 같은 eclipse plug-in을 이용하는 방법이 주로 추천되고 있다. 


maven을 오래 사용한 것은 아니지만, 일단 eclipse plugin을 사용하는 것보다는 console을 이용하는 것이 좀 더 나아보인다. test, deploy 등의 작업을 좀 더 편하게 할 수 있고, m2eclipse를 사용하더라도 손으로 하나하나 다시 설정을 잡아줘야지 되는 불편함이 존재하기 때문에, pom 자체를 이용해서 이를 수정해주는 것이 더 나아보이기 때문이다. 


단계는 다음과 같다. (자바세상의 빌드를 이끄는 메이븐 을 보면서 공부를 해서... 예시는 책에 나온 wikibook을 사용한다.)


1. web app의 skeleton code를 다음 maven command를 이용해서 작성한다.


mvn archetype:generate -DgroupId=com.xyzlast -DartifactId=wikibook -DarchetypeArtifactId=maven-archetype-webapp


작성된 project의 pom 파일은 다음과 같다.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.xyzlast</groupId>

  <artifactId>wikibook</artifactId>

  <packaging>war</packaging>

  <version>1.0-SNAPSHOT</version>

  <name>wikibook Maven Webapp</name>

  <url>http://maven.apache.org</url>

  <dependencies>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <version>3.8.1</version>

      <scope>test</scope>

    </dependency>

  </dependencies>

  <build>

    <finalName>wikibook</finalName>

  </build>

</project>


2. 먼저, 사용하는 java compiler의 버젼은 1.7을 사용하고 있기 때문에 compiler의 버젼을 넣어준다.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>

이 상태에서 mvn eclipse:eclipse를 이용해서 eclipse용 설정을 생성하게 되면, 다음과 같은 문제가 발생하게 된다.
* M2_REPO/junit/junit/4.11/junit-4.11.jar will not be exported or published. Runtime ClassNotFoundExceptions may result. 
* Project Facets가 정상적으로 맞지 않는 문제(최신 자바 1.7만 설정이 된 경우)

3. 사용되는 jar 파일들을 WEB-INF/libs 에 위치하게 하기 위해서 다음과 같은 설정을 추가한다. 또한, javadoc과 source를 보기 위한 설정 역시 추가한다.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<projectNameTemplate>[artifactId]</projectNameTemplate>
<wtpapplicationxml>true</wtpapplicationxml>
<wtpversion>2.0</wtpversion>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<useProjectReferences>true</useProjectReferences>
<workspace>..</workspace>
</configuration>
</plugin>


4. 이 상태에서 mvn eclipse:eclipse를 실행하면, .setting/org.eclipse.wst.common.project.facet.core.xml 파일의 내용은 다음과 같다.

<faceted-project>
  <fixed facet="jst.java"/>
  <fixed facet="jst.web"/>
  <installed facet="jst.web" version="2.4"/>
  <installed facet="jst.java" version="1.4"/>
</faceted-project>

여기서 eclipse로 import하기 전에 text 파일을 고쳐주면 문제가 해결되긴 하지만, 자동화를 위해서 다음과 같은 파일을 작성한다.

java_1.7_web_3.0.xml
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
     <fixed facet="jst.web"/>
     <fixed facet="java"/>
     <fixed facet="wst.jsdt.web"/>
     <installed facet="java" version="1.7"/>
     <installed facet="jst.web" version="3.0"/>
     <installed facet="jst.jsf" version="2.0"/>
     <installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>

또한, 생성된 skeleton project의 web.xml은 web app version 2.5의 것을 사용하고 있기 때문에 이것을 3.0으로 넣어줄 기본 web.xml 파일을 작성한다.

web_3.0_default.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
         id="WebApp_ID" version="3.0">

<display-name>wikibook</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

작성된 2개의 파일을 MAVEN_HOME의 app-conf Directory에 카피한다.

5. maven-eclipse-plugin 정보에 다음과 같은 추가 설정을 한다.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<projectNameTemplate>[artifactId]</projectNameTemplate>
<wtpapplicationxml>true</wtpapplicationxml>
<wtpversion>2.0</wtpversion>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<useProjectReferences>true</useProjectReferences>
<workspace>..</workspace>
<additionalConfig>
<file>
<name>.settings/org.eclipse.wst.common.project.facet.core.xml</name>
<location>file:///${MAVEN_HOME}/app-conf/java_1.7_web_3.0.xml</location>
</file>
<file>
<name>src/main/webapp/WEB-INF/web.xml</name>
<location>file:///${MAVEN_HOME}/app-conf/web_3.0_default.xml</location>
</file>
</additionalConfig>
</configuration>
</plugin>

추가 설정의 내용은 단순하다. MAVEN_HOME에 위치한 facet 파일과 web.xml을 이용해서 eclipse plugin에 의해 생성되는 파일을 대치해버리는 것이다. 

최종적인 pom.xml파일 내용은 다음과 같다. (JUnit 4를 사용하기 위해서, JUnit버젼 역시 3.8.1에서 4.11로 변경하였다.)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyzlast</groupId>
<artifactId>wikibook</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>wikibook Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>servlet-api</artifactId>
<version>6.0.35</version>
</dependency>
</dependencies>
<build>
<finalName>wikibook</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<projectNameTemplate>[artifactId]</projectNameTemplate>
<wtpapplicationxml>true</wtpapplicationxml>
<wtpversion>2.0</wtpversion>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<useProjectReferences>true</useProjectReferences>
<workspace>..</workspace>
<additionalConfig>
<file>
<name>.settings/org.eclipse.wst.common.project.facet.core.xml</name>
<location>file:///${MAVEN_HOME}/app-conf/java_1.7_web_3.0.xml</location>
</file>
<file>
<name>src/main/webapp/WEB-INF/web.xml</name>
<location>file:///${MAVEN_HOME}/app-conf/web_3.0_default.xml</location>
</file>
</additionalConfig>
</configuration>
</plugin>
</plugins>
</build>
</project>


6. 이제 console에서 mvn eclipse:eclipse를 실행한다. 
실행후, eclipse에서 Import를 이용해서 project를 load 한다. 결과는 다음과 같다.



test에 사용되는 junit부분 warning이고, 이 것은 무시 가능하다. delete로 지워버려도 된다.


이제 Tomcat을 구성하고, Tomcat에서 project를 추가하면 다음과 같은 페이지를 보는 것이 가능하다. 



Posted by Y2K
,

InvocationHandler

Java 2012. 9. 12. 00:00

JAVA와 .NET의 차이점을 볼때, 가장 특이한 점이라고 보이는 Interface.


Dynamic Proxy의 핵심 Interface이고, Proxy.newProxyInstance method를 통해서 기본적인 Dynamic Proxy 객체를 생성해주는 것이 가능하다.

코드는 다음과 같다.


Hello proxyHello = (Hello) Proxy.newProxyInstance(

                             getClass().getClassLoader(),

                             new Class[] { Hello.class },

                             new InvocationHandler(new HelloTarget()));


재미있어보이는 코드이고, 일단 Target의 Interface를 모두 상속받은 Proxy객체를 만들어준다는 것이 엄청나다는 느낌이 든다. 


물론. 이 코드를 바로 사용하는 일은 거의 존재하지를 않는다. 

Spring에서 제공하는 ProxyFactory를 이용해서, Dynamic Proxy를 구성하는 것이 일반적이기 때문이다. 

Posted by Y2K
,

1. S/W 개발에서 절대로 바꾸지 않는 것은 없기 때문에.

Class 대신이 Interface를 사용하고, New 대신에 DI를 이용하는 작업에 대한 비용보다 후에 바뀌게 되어서 지불하게 되는 비용이 더욱더 크다.


2. Class의 구현방식은 바뀌지 않는다고해도, Interface를 이용하면 다른 차원의 서비스가 구현 가능하다

method의 호출전, 후에 다른 일을 한다던지, 아니면 count를 늘려주는 사소한 일을 하더라도, 기존 class의 변경 없이 개발이 가능하게 할 수 있다.


3. TEST가 용이하다

단지 효율적인 테스트를 하기 위해서라도 DI를 적용해야지 된다.

Posted by Y2K
,