μ•ˆλ…•ν•˜μ„Έμš” μ΄μ •μš΄ μž…λ‹ˆλ‹€.

이번 κ°•μ’Œμ—μ„œλŠ” 쑰금 더 개발 μž…μž₯으둜 λ“€μ–΄κ°€ κ°œλ°œμ‹œμ— 많이 μ‚¬μš©ν•˜μ‹œλŠ” Maven 을 μ΄μš©ν•΄μ„œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°œλ°œμ„ μœ„ν•œ Open Liberty μ„œλ²„ 연동에 λŒ€ν•œ 뢀뢄을 ν•œλ²ˆ μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€. λ˜ν•œ, ν•΄λ‹Ή 뢀뢄은 ν–₯ν›„ μžλ™ν™”λ‚˜ 이런 λΆ€λΆ„μ—μ„œλ„ 많이 μ‚¬μš©ν•˜μ‹œλ‹ˆ μ°Έκ³ ν•΄λ‘μ‹œλ©΄ 쒋을듯 ν•©λ‹ˆλ‹€.

Building a web application with Maven
https://openliberty.io/guides/maven-intro.html

λ³Έ κ°•μ’ŒλŠ” μƒλ‹¨μ˜ λ§ν¬μ—μ„œ μ œκ³΅ν•˜λŠ” κ°€μ΄λ“œλ₯Ό 기반으둜 ν…ŒμŠ€νŠΈν•˜κ³  μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
(이번 κ°•μ’Œμ—μ„œλŠ” 기본적으둜 maven κ³Ό git 은 μ„€μΉ˜λ˜μ–΄ μžˆλ‹€λŠ” 가정을 ν•˜κ³  κ°•μ’Œλ₯Ό μ§„ν–‰ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.)

#1) Maven 을 μ΄μš©ν•œ Open Liberty μ„œλ²„ 연동

μš°μ„  λΉ λ₯΄κ³  κ°„νŽΈν•œ μ‹œμž‘μ„ μœ„ν•΄μ„œ μ–΄λŠμ •λ„ ν˜•νƒœκ°€ μž‘μ„±λ˜μ–΄ μžˆλŠ” κ°€μ΄λ“œ μƒ˜ν”Œμ„ github μ—μ„œ λ‹€μš΄λ‘œλ“œ λ°›μŠ΅λ‹ˆλ‹€.

git clone https://github.com/openliberty/guide-maven-intro.git
cd guide-maven-intro/start

λ‹€μš΄λ‘œλ“œλœ μ†ŒμŠ€λ₯Ό λ³΄μ‹œλ©΄ μ•„μ‹œκ² μ§€λ§Œ κ°„λ‹¨ν•œ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μœ„ν•œ κΈ°λ³Έ ꡬ쑰λ₯Ό 가지고 있으며 μƒ˜ν”Œ μ†ŒμŠ€κ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

특히, /src/main/liberty/config 폴더λ₯Ό ν™•μΈν•΄λ³΄μ‹œλ©΄ ν•˜λ‹¨κ³Ό 같이 Open Liberty λ₯Ό μœ„ν•œ μ„œλ²„ μ„€μ • 파일인 server.xml 이 ν¬ν•¨λ˜μ–΄ μžˆλŠ” 것을 ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.
(ν•΄λ‹Ή νŒŒμΌμ€ ν–₯후에 maven 컴파일과 λΉŒλ“œμ‹œμ— μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό Open Liberty κ°€ 같이 λΉŒλ“œλ˜λŠ”λ° μ΄λ•Œ, Open Liberty 의 μ„œλ²„ μ„€μ •μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.)

참고둜 μœˆλ„μš°μ¦ˆμ—μ„œ ν…ŒμŠ€νŠΈ ν•˜λŠ” 경우라면 λ°˜λ“œμ‹œ server.xml νŒŒμΌμ„ μ—΄μ–΄μ„œ 주석을 “<!—, —>” μ—μ„œ “<!–, –>” 둜 λ³€κ²½ν•΄μ£Όμ…”μ•Ό maven μ»΄νŒŒμΌμ‹œμ— 였λ₯˜κ°€ λ°œμƒλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ˜ν•œ, maven μ—μ„œ μ§€μ •λœ μ„€μ •μœΌλ‘œ λ™μ μœΌλ‘œ server.xml 섀정을 λ³€κ²½ν•˜μ‹œλ €λ©΄ ν•˜λ‹¨κ³Ό 같이 λ³€μˆ˜λ‘œ 섀정을 μž…λ ₯ν•΄ λ†“μœΌμ‹œλ©΄ λ©λ‹ˆλ‹€.

<server description=”Sample Servlet server”>
<featureManager>
<feature>servlet-3.1</feature>
</featureManager>

<httpEndpoint httpPort=”${default.http.port}” httpsPort=”${default.https.port}” id=”defaultHttpEndpoint” host=”*” />

<webApplication id=”${app.context.root}” location=”${app.context.root}.war” name=”${app.context.root}”/>
</server>

κΈ°λ³Έ ꡬ쑰λ₯Ό ν™•μΈν–ˆμœΌλ©΄ 이제 본격적으둜 maven 을 μœ„ν•œ κΈ°λ³Έ pom.xml νŒŒμΌμ„ μž‘μ„±ν•΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€. (pom.xml 에 λŒ€ν•œ μƒμ„Έν•œ μ„€λͺ…은 μƒλ‹¨μ˜ 링크λ₯Ό μ°Έκ³ ν•˜μ‹œκΈ° 바라며 μ—¬κΈ°μ„œλŠ” Maven κ°•μ’Œκ°€ μ•„λ‹ˆλ‹ˆ κ°„λ‹¨νžˆλ§Œ μ„€λͺ…λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.)

<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.0http://maven.apache.org/maven-v4_0_0.xsd”>;
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.wasdev.wlp.maven.parent</groupId>
<artifactId>liberty-maven-app-parent</artifactId>
<version>2.0</version>
</parent>

<!– Add the rest of the POM below here. –>

</project>

κΈ°λ³Έ pom.xml ν˜•μ‹ 에닀 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 이름과 μ„€λͺ…이 λ“€μ–΄κ°„ ν”„λ‘œμ νŠΈ μ½”λ””λ„€μ΄νŠΈ 정보λ₯Ό μΆ”κ°€ ν•©λ‹ˆλ‹€.

<groupId>io.openliberty.guides</groupId>
<artifactId>ServletSample</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>

그리고 ν”„λ‘œμ νŠΈμ—μ„œ μ‚¬μš©ν•  ν”„λ‘œνΌν‹° 정보λ₯Ό ν•˜λ‹¨κ³Ό 같이 μΆ”κ°€ ν•©λ‹ˆλ‹€. κ°„λž΅νžˆλ§Œ μ„€λͺ…λ“œλ¦¬λ©΄ Java 의 버전과(1.8) 인코딩 ν˜•μ‹(UTF-8) 등에 λŒ€ν•œ 정보λ₯Ό μ§€μ •ν•˜λ©° 이 섀정을 가지고 μ‹€μ œ Maven 이 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— λŒ€ν•œ μ»΄νŒŒμΌμ„ μˆ˜ν–‰ν•  κ²ƒμž…λ‹ˆλ‹€.

이외에 Maven μ—μ„œ μ‚¬μš©ν•  ν”„λ‘œνΌν‹° 정보가 더 μžˆλ‹€κ³  λ³΄μ‹œλ©΄ λ©λ‹ˆλ‹€. (예λ₯Ό λ“€μ–΄ Open Liberty μ—μ„œ μ‚¬μš©ν•  ν¬νŠΈμ •λ³΄)

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<app.name>${project.artifactId}</app.name>
<testServerHttpPort>9080</testServerHttpPort>
<testServerHttpsPort>9443</testServerHttpsPort>
<warContext>${app.name}</warContext>
<package.file>${project.build.directory}/${app.name}.zip</package.file>
<packaging.type>usr</packaging.type>
</properties>

λ‹€μŒμœΌλ‘œ μƒ˜ν”Œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ 기본적으둜 Servlet 을 μ‚¬μš©ν•  거라 ν•˜λ‹¨κ³Ό 같은 dependency λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

λ§ˆμ§€λ§‰μœΌλ‘œ 이 ν”„λ‘œμ νŠΈλ₯Ό λΉŒλ“œμ™€ κ΄€λ ¨λœ maven ν”ŒλŸ¬κ·ΈμΈ 섀정을 μΆ”κ°€ν•©λ‹ˆλ‹€.

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<packagingExcludes>pom.xml</packagingExcludes>
</configuration>
</plugin>
<plugin>
<groupId>net.wasdev.wlp.maven.plugins</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<assemblyArtifact>
<groupId>io.openliberty</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>17.0.0.3</version>
<type>zip</type>
</assemblyArtifact>
<serverName>${project.artifactId}Server</serverName>
<stripVersion>true</stripVersion>
<configFile>src/main/liberty/config/server.xml</configFile>
<packageFile>${package.file}</packageFile>
<include>${packaging.type}</include>
<bootstrapProperties>
<default.http.port>${testServerHttpPort}</default.http.port>
<default.https.port>${testServerHttpsPort}</default.https.port>
<app.context.root>${warContext}</app.context.root>
</bootstrapProperties>
</configuration>
<executions>
<execution>
<id>package-server</id>
<phase>package</phase>
<goals>
<goal>package-server</goal>
</goals>
<configuration>
<outputDirectory>target/wlp-package</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

μ—¬κΈ°κΉŒμ§€ 잘 λ”°λΌμ˜€μ…¨λ‹€λ©΄ 기본적인 pom.xml 파일 μž‘μ„±μ΄ μ™„λ£Œλœ 것이며 ν•˜λ‹¨κ³Ό 같이 ‘mvn install’ 을 μˆ˜ν–‰ν•©λ‹ˆλ‹€. 즉, maven 을 μ΄μš©ν•΄μ„œ pom.xml 에 μ§€μ •λœ ν˜•νƒœλ‘œ 컴파일과 λΉŒλ“œλ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.

mvn install

λ¬Έμ œκ°€ 없이 μ •μƒμ μœΌλ‘œ μˆ˜ν–‰μ΄ μ™„λ£Œλ˜λ©΄ target 폴더에 ν•˜λ‹¨κ³Ό 같은 디렉토리 ꡬ쑰λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. (참고둜 liberty 폴더에 Open Liberty μ„œλ²„κ°€ μ„€μΉ˜λœ ν˜•νƒœλ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.)

그러면 이제 maven λͺ…령을 μ΄μš©ν•΄μ„œ μ„€μΉ˜λœ Open Liberty μ„œλ²„λ₯Ό κ΅¬λ™ν•΄μ„œ μ‹€μ œ μ„œλΉ„μŠ€λ₯Ό μˆ˜ν–‰ν•˜κΈ° μœ„ν•˜μ—¬ “mvn liberty:start-server” λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€.

이제 μ›ΉλΈŒλΌμš°μ €λ₯Ό ν†΅ν•΄μ„œ ‘http://localhost:9080/ServletSample/’ 둜 접속해보면 ν•˜λ‹¨κ³Ό 같이 μƒ˜ν”Œ Servlet 에 λŒ€ν•œ κ²°κ³Όλ₯Ό 확인 κ°€λŠ₯ν•©λ‹ˆλ‹€.

참고적으둜 Open Liberty μ„œλ²„μ— λŒ€ν•œ 변경없이 ꡬ동쀑인 μƒνƒœμ—μ„œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ§Œ 재배포 및 κ²°κ³Όλ₯Ό ν™•μΈν•˜κ³  μ‹ΆμœΌμ‹œλ‹€λ©΄ “mvn package” λͺ…령을 μ‚¬μš©ν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€. λ˜ν•œ, “mvn liberty:stop-server” λͺ…령을 ν†΅ν•΄μ„œ Open Liberty μ„œλ²„μ— λŒ€ν•œ 쀑지가 κ°€λŠ₯ν•˜λ©° κ·Έμ™Έμ˜ λ‹€μ–‘ν•œ liberty-maven-plugin 의 λ‹€μ–‘ν•œ goal 은 ν•˜λ‹¨μ˜ 링크λ₯Ό ν†΅ν•΄μ„œ ν™•μΈν•΄λ³΄μ‹œκΈ° λ°”λΌκ² μŠ΅λ‹ˆλ‹€.

ci.maven
https://github.com/WASdev/ci.maven

μΆ”κ°€λ‘œ target/liberty/wlp/usr/servers/ServletSampleServer 폴더에 λ³΄μ‹œλ©΄ 기쑴에 μ„€λͺ…ν–ˆλ˜ server.xml 이외에 ν•˜λ‹¨κ³Ό 같은 ν˜•νƒœμ˜ bootstrap.properties 파일이 μΆ”κ°€λœ 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. λ³΄μ‹œλ©΄ μ•„μ‹œκ² μ§€λ§Œ maven μ—μ„œ μ‚¬μš©ν–ˆλ˜ λ³€μˆ˜λ“€μ΄λ©° 이 섀정을 μ΄μš©ν•΄μ„œ server.xml 의 λ³€μˆ˜λ₯Ό μΉ˜ν™˜ν•΄μ„œ κ΅¬λ™ν•˜λŠ” ν˜•νƒœμž…λ‹ˆλ‹€. (JVM κ΄€λ ¨ μ˜΅μ…˜μ„ μΆ”κ°€ν•˜μ‹œλ €λ©΄ jvm.options νŒŒμΌμ„ μΆ”κ°€ν•΄μ„œ λ„£μœΌλ©΄ λ©λ‹ˆλ‹€.)

# Generated by liberty-maven-plugin
app.context.root=ServletSample
default.http.port=9080
default.https.port=9443

#2) Maven 에 JUnit 을 ν†΅ν•œ Test 단계 μΆ”κ°€

κΈ°μ‘΄μ—λŠ” maven 을 ν†΅ν•΄μ„œ 컴파일과 λΉŒλ“œλ§Œ μˆ˜ν–‰ν–ˆλŠ”λ° μš”μ¦˜μ€ λŒ€λΆ€λΆ„ JUnit 을 ν†΅ν•œ Test 단계λ₯Ό 기본적으둜 μˆ˜ν–‰ν•˜λŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ ν•΄λ‹Ή 뢀뢄에 λŒ€ν•œ 뢀뢄도 κ°„λ‹¨νžˆ ν…ŒμŠ€νŠΈν•΄μ„œ κ³΅μœ λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.

μš°μ„  λ‹Ήμ—°ν•˜κ² μ§€λ§Œ Test λ₯Ό μœ„ν•œ μ†ŒμŠ€λ₯Ό ν•˜λ‹¨κ³Ό 같이 μž‘μ„±ν•©λ‹ˆλ‹€.

package io.openliberty.guides.hello.it;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
public class EndpointIT {
private static String URL;
@BeforeClass
public static void init() {
String port = System.getProperty(“liberty.test.port”);
String war = System.getProperty(“war.name”);
URL = “http://localhost:”; + port + “/” + war + “/” + “servlet”;
}
@Test
public void testServlet() throws Exception {
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(URL);
try {
int statusCode = client.executeMethod(method);
assertEquals(“HTTP GET failed”, HttpStatus.SC_OK, statusCode);
String response = method.getResponseBodyAsString(1000);
assertTrue(“Unexpected response body”, response.contains(“Hello! How are you today?”));
} finally {
method.releaseConnection();
}
}
}

기본적으둜 Test λ₯Ό μœ„ν•œ μ†ŒμŠ€μ˜ κ΅¬μ‘°λŠ” ν•˜λ‹¨μ²˜λŸΌ μž‘μ„±λ˜λ©΄ 되며 κΈ°μ‘΄ ν”„λ‘œμ νŠΈμ— test 폴더가 μΆ”κ°€λœ ν˜•νƒœμž…λ‹ˆλ‹€. μ§€κΈˆ μž‘μ„±λœ μ†ŒμŠ€λŠ” “src/test/java/io/openliberty/guides/hello/it/EndpointIT.java” 여기에 λ‘μ‹œλ©΄ λ©λ‹ˆλ‹€.

그리고 κΈ°μ‘΄ pom.xml 에 test μˆ˜ν–‰μ„ μœ„ν•œ maven ν”ŒλŸ¬κ·ΈμΈμ„ μΆ”κ°€ν•©λ‹ˆλ‹€.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/it/**</include>
</includes>
<systemPropertyVariables>
<liberty.test.port>${testServerHttpPort}</liberty.test.port>
<war.name>${warContext}</war.name>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>

λ§ˆμ§€λ§‰μœΌλ‘œ μ‹€μ œ test μ‹œμ— μ‚¬μš©λ˜λŠ” JUnit κ³Ό 같은 λΌμ΄λΈŒλŸ¬λ¦¬μ— λŒ€ν•œ dependency λ₯Ό μΆ”κ°€ ν•©λ‹ˆλ‹€.

<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

이제 이전 νŒŒνŠΈμ™€ λ™μΌν•˜κ²Œ mvn install ν•΄λ³΄μ‹œλ©΄ ν•˜λ‹¨κ³Ό 같이 쀑간에 ν…ŒμŠ€νŠΈ λ‹¨κ³„κΉŒμ§€ κ±°μΉ˜λŠ” 것을 확인 κ°€λŠ₯ν•˜μ‹­λ‹ˆλ‹€.

그럼 이번 κ°•μ’ŒλŠ” μ—¬κΈ°μ„œ 마무리 ν•˜λŠ” κ²ƒμœΌλ‘œ ν•˜κ² μŠ΅λ‹ˆλ‹€.Β  휘리릭~~~

ν† λ‘  μ°Έκ°€

이메일은 κ³΅κ°œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν•„μˆ˜ μž…λ ₯창은 * 둜 ν‘œμ‹œλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.