메이븐 레파지토리에 없는 jar 추가하고 manifest 에 기술하기
IBM DB2를 가지고 개발할 일이 생겼다.
늘 하던대로 executeable-jar 형식으로 빌딩을 수행하는 메이븐 프로젝트를 구성하는데.. 으잉? DB2의 jdbc 드라이버 db2jcc4.jar가 메이븐센트럴에 등록되어있지 않는것이다. 뭐지.. 이건?
회사 넥서스에 등록하고 땡겨쓰면 되긴 하지만 넥서스같은 로컬 메이븐 레파지토리가 없는 환경에서 이런경우는 어떻게 해야하는지 궁금했다.
귀찮겠지만 빌드하고 라이브러리 폴더에 jar를 복사해도 되긴하지만 문제는 POM파일에 기술되지 않으면 dependancy 관리가 안된다는것. 곧 IDE에서 클래스를 참조할 수 없다는 치명적인 문제가 발생한다.
이럴때를 대비해 메이븐은 dependencies.dependency.scope 속성 값으로 system을 제공하고 있고 <scope>system</scope> 를 사용한 경우 추가로 systemPath 속성을 정의할 수 있다.
이렇게 말이지..
[code xml] <dependencies>
<dependency>
<groupId>ibm.db2</groupId>
<artifactId>db2jcc4</artifactId>
<version>10.5</version>
<scope>system</scope>
<systemPath>${basedir}/lib/db2jcc4.jar</systemPath>
</dependency>
</dependencies>
[/code]
이제, 코드를 짤 수 있고 라이브러리 참조도 된다. 그런데.. 문제가 하나 있는데 <scope>system</scope> 속성은 메이븐 빌드 시 <scope>provided</scope> 와 마찬가지로 라이브러리를 빌드 결과물에 포함시키기 않는다.
이 현상은 maven-dependency-plugin의 configuration 조정을 통해 우회할 수 있다.
plugins.plugin.executions.execution.configuration.includeScope 속성을 추가하고 그 값으로 system 을 설정한다.
[code xml] <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>system</includeScope>
</configuration>
</execution>
</executions>
</plugin>[/code]
이제 빌드를 수행하면 system 스코프로 설정된 db2jcc4.jar 가 /lib/db2jcc4-10.5.jar 란 이름으로 이쁘게 들어와 있는걸 확인할 수 있다.
나는 이 프로그램을 executeable-jar 로 뽑을거라서 maven-jar-plugin 을 사용한다. 그런데 빌드 후 jar 내부의 MENIFEST 파일을 까 보니 Class-Path 정의에 db2jcc4-10.5.jar 가 기술되어 있지 않다... maven-dependency-plugin을 통해 복사까진 어떻게 처리했는데 메니페스트를 만드는건 maven-jar-plugin 역할이니 당연한건지도 모르겠다.
이제 마지막으로 /lib/db2jcc4-10.5.jar 에 들어온 jar를 메니페스트의 class path에 꾸겨넣어보자.
plugin.configuration.archive.manifestEntries.Class-Path 속성을 사용했다.
[code xml] <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addExtensions>true</addExtensions>
<mainClass>com.usbcopy.repository.DBProcess</mainClass>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<!--MANIFEST with systemPath-->
<manifestEntries>
<Class-Path>lib/db2jcc4-10.5.jar</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>[/code]
이제 빌드하고 java -jar app.jar 로 실행도 잘 된다.
늘 하던대로 executeable-jar 형식으로 빌딩을 수행하는 메이븐 프로젝트를 구성하는데.. 으잉? DB2의 jdbc 드라이버 db2jcc4.jar가 메이븐센트럴에 등록되어있지 않는것이다. 뭐지.. 이건?
회사 넥서스에 등록하고 땡겨쓰면 되긴 하지만 넥서스같은 로컬 메이븐 레파지토리가 없는 환경에서 이런경우는 어떻게 해야하는지 궁금했다.
귀찮겠지만 빌드하고 라이브러리 폴더에 jar를 복사해도 되긴하지만 문제는 POM파일에 기술되지 않으면 dependancy 관리가 안된다는것. 곧 IDE에서 클래스를 참조할 수 없다는 치명적인 문제가 발생한다.
이럴때를 대비해 메이븐은 dependencies.dependency.scope 속성 값으로 system을 제공하고 있고 <scope>system</scope> 를 사용한 경우 추가로 systemPath 속성을 정의할 수 있다.
이렇게 말이지..
[code xml] <dependencies>
<dependency>
<groupId>ibm.db2</groupId>
<artifactId>db2jcc4</artifactId>
<version>10.5</version>
<scope>system</scope>
<systemPath>${basedir}/lib/db2jcc4.jar</systemPath>
</dependency>
</dependencies>
[/code]
이제, 코드를 짤 수 있고 라이브러리 참조도 된다. 그런데.. 문제가 하나 있는데 <scope>system</scope> 속성은 메이븐 빌드 시 <scope>provided</scope> 와 마찬가지로 라이브러리를 빌드 결과물에 포함시키기 않는다.
이 현상은 maven-dependency-plugin의 configuration 조정을 통해 우회할 수 있다.
plugins.plugin.executions.execution.configuration.includeScope 속성을 추가하고 그 값으로 system 을 설정한다.
[code xml] <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>system</includeScope>
</configuration>
</execution>
</executions>
</plugin>[/code]
이제 빌드를 수행하면 system 스코프로 설정된 db2jcc4.jar 가 /lib/db2jcc4-10.5.jar 란 이름으로 이쁘게 들어와 있는걸 확인할 수 있다.
나는 이 프로그램을 executeable-jar 로 뽑을거라서 maven-jar-plugin 을 사용한다. 그런데 빌드 후 jar 내부의 MENIFEST 파일을 까 보니 Class-Path 정의에 db2jcc4-10.5.jar 가 기술되어 있지 않다... maven-dependency-plugin을 통해 복사까진 어떻게 처리했는데 메니페스트를 만드는건 maven-jar-plugin 역할이니 당연한건지도 모르겠다.
이제 마지막으로 /lib/db2jcc4-10.5.jar 에 들어온 jar를 메니페스트의 class path에 꾸겨넣어보자.
plugin.configuration.archive.manifestEntries.Class-Path 속성을 사용했다.
[code xml] <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addExtensions>true</addExtensions>
<mainClass>com.usbcopy.repository.DBProcess</mainClass>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<!--MANIFEST with systemPath-->
<manifestEntries>
<Class-Path>lib/db2jcc4-10.5.jar</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>[/code]
이제 빌드하고 java -jar app.jar 로 실행도 잘 된다.
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다