티스토리 뷰

728x90
반응형

 포스팅은 WildFly의 공통 라이브러리 반영 방법 및 라이브러리 우선순위 테스트 가이드입니다.


 

 

1. 공통라이브러리 반영 방법

먼저 신규로 개발한 공통라이브러리가 있을 경우 반영하는 방법에 대해 알아 보겠습니다.

 

Wildfly는 module이라는 디렉토리를 기반으로 라이브러리를 로딩합니다.

module 디렉토리에 들어가보면  

[wildfly@NRSON base]$ pwd
/home/wildfly/wildfly11/modules/system/layers/base
[wildfly@NRSON base]$ ls -la
합계 8
drwxr-xr-x 15 wildfly wildfly  151  3월 26 11:07 .
drwxr-xr-x  3 wildfly wildfly   18 10월 23 22:30 ..
drwxr-xr-x  3 wildfly wildfly   17 10월 23 22:30 asm
drwxr-xr-x  3 wildfly wildfly   17 10월 23 22:30 ch
drwxr-xr-x  8 wildfly wildfly   97 10월 23 22:30 com
drwxr-xr-x  3 wildfly wildfly   20 10월 23 22:30 gnu
drwxr-xr-x  3 wildfly wildfly   17 10월 23 22:30 ibm
drwxr-xr-x  4 wildfly wildfly   35 10월 23 22:30 io
drwxr-xr-x  3 wildfly wildfly   17 10월 23 22:30 javaee
drwxr-xr-x 30 wildfly wildfly 4096 10월 23 22:30 javax
drwxrwxr-x  3 wildfly wildfly   18  3월 26 11:07 kkm
drwxr-xr-x  3 wildfly wildfly   18 10월 23 22:30 net
drwxr-xr-x  3 wildfly wildfly   17 10월 23 22:30 nu
drwxr-xr-x 29 wildfly wildfly 4096 10월 23 22:30 org
drwxr-xr-x  4 wildfly wildfly   34 10월 23 22:30 sun
[wildfly@NRSON base]$ 

 

위와 같이 Wildfly 내부 엔진 관련 여러 Library 디렉토리들을 볼 수 있습니다.

한번 디렉토리 내부까지 들어가 보도록 하겠습니다. 

[wildfly@NRSON main]$ pwd
/home/wildfly/wildfly11/modules/system/layers/base/org/wildfly/extension/undertow/main
[wildfly@NRSON main]$ ls -la
합계 792
drwxr-xr-x 2 wildfly wildfly     65  3월 26 10:23 .
drwxr-xr-x 3 wildfly wildfly     18 10월 23 22:30 ..
-rw-r--r-- 1 wildfly wildfly   4041  3월 26 10:23 module.xml
-rw-r--r-- 1 wildfly wildfly 806865 10월 23 22:30 wildfly-undertow-11.0.0.Final.jar
[wildfly@NRSON main]$

 

standalone.xml 파일에서 주로 다루어야하는 undertow 관련 jar 파일이 해당 위치에 올라가 있네요.

module.xml 파일을 열어 보도록 하겠습니다. 

<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ JBoss, Home of Professional Open Source.
  ~ Copyright 2010, Red Hat, Inc., and individual contributors
  ~ as indicated by the @author tags. See the copyright.txt file in the
  ~ distribution for a full listing of individual contributors.
  ~
  ~ This is free software; you can redistribute it and/or modify it
  ~ under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ This software is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  ~ Lesser General Public License for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public
  ~ License along with this software; if not, write to the Free
  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  -->

<module xmlns="urn:jboss:module:1.5" name="org.wildfly.extension.undertow">
    <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <exports>
        <exclude path="org/wildfly/extension/undertow/logging"/>
    </exports>

    <resources>
        <resource-root path="wildfly-undertow-11.0.0.Final.jar"/>
    </resources>

    <dependencies>
        <module name="io.undertow.core" services="import"/>
        <module name="io.undertow.servlet" services="import"/>
        <module name="io.undertow.jsp"/>
        <module name="io.undertow.websocket"/>
        <module name="sun.jdk"/>
        <module name="javax.annotation.api"/>
        <module name="javax.api"/>
        <module name="javax.security.auth.message.api"/>
        <module name="javax.servlet.api"/>
        <module name="javax.servlet.jsp.api"/>
        <module name="javax.websocket.api"/>
        <module name="org.jboss.jandex"/>
        <module name="org.jboss.staxmapper"/>
        <module name="org.jboss.as.clustering.common"/>
        <module name="org.wildfly.clustering.service"/>
        <module name="org.wildfly.clustering.web.api" optional="true"/>
        <module name="org.wildfly.clustering.web.undertow" services="import" optional="true"/>
        <module name="org.wildfly.extension.request-controller" />
        <module name="org.jboss.as.controller"/>
        <module name="org.jboss.as.domain-management"/>
        <module name="org.jboss.as.ee"/>
        <module name="org.jboss.as.core-security"/>
        <module name="org.wildfly.extension.io"/>
        <module name="org.jboss.as.naming"/>
        <module name="org.jboss.as.network"/>
        <module name="org.jboss.as.security"/>
        <module name="org.wildfly.security.elytron-private"/>
        <module name="org.wildfly.security.elytron-web.undertow-server"/>
        <module name="org.jboss.as.server"/>
        <module name="org.jboss.as.threads"/>
        <module name="org.jboss.common-beans" services="import"/>
        <module name="org.jboss.marshalling"/>
        <module name="org.jboss.marshalling.river" services="import"/>
        <module name="org.jboss.as.web-common"/>
        <module name="org.jboss.invocation"/>
        <module name="org.jboss.metadata.common"/>
        <module name="org.jboss.metadata.web"/>
        <module name="org.jboss.metadata.ear"/>
        <module name="org.jboss.modules"/>
        <module name="org.jboss.msc"/>
        <module name="org.jboss.security.negotiation"/>
        <module name="org.jboss.threads"/>
        <module name="org.jboss.vfs"/>
        <module name="org.jboss.as.version"/>
        <module name="org.jboss.logging"/>
        <module name="org.picketbox"/>
        <module name="javax.security.jacc.api"/>
        <module name="org.jboss.xnio"/>
        <module name="org.jboss.xnio.nio" services="import"/>
        <module name="org.wildfly.http-client.common"/>
    </dependencies>
</module>

 

몬가 잔뜩 내용이 들어 있죠. 간략하게 해당 내용을 살펴보면 다음과 같습니다.

1) <module xmlns="urn:jboss:module:1.5" name="org.wildfly.extension.undertow">

- 위 첫 태그에서는 name 부분이 중요합니다. 해당 name이 실제 standalone.xml 파일의 Module-Name과 매칭되게 됩니다.

2) <properties>

- 해당 Modules API에 대한 접근성 설정입니다. private의 경우 내부 사용만 가능하겠죠.

3) <resources> <resource-root path="wildfly-undertow-11.0.0.Final.jar"/>

- 실제 Wildfly에 추가할 모듈 이름을 넣습니다.

4) <dependencies>

- 3번에 추가한 library를 반영할때 참조해야 할 depencency library를 등록해 줍니다.

 

위와 같은 일련의 과정을 통해 API jar file은 Wildfly에 등록되게 됩니다.

자 그럼 실제 개발한 소스를 등록하기 위해서는 어떻게 해야 하는지 알아 보겠습니다.

Step은 위와 동일하게 진행됩니다.

 

a. 먼저 개발한 소스를 확인해 보겠습니다.

 

package kkm;

public class Hello {

private String name="HelloTest : Hello!!!";

public void setName(String name) {
    this.name=name;
}

public String getName() {
    return name;
}

- Hello Class를 호출하면 HelloTest : Hello!!! 라는 결과 값을 Return 해주는 API입니다.

 

b. 해당 class를 컴파일하여 jar 타입으로 패키징 합니다.

 

 

c. 패키징한 jar 파일을 module 디렉토리의 특정 위치에 위치 시킵니다.

- 여기서 특정위치는 다음과 같이 산정됩니다.

$WILDFLY_HOME/modules/package_location/main

위에 기 개발한 API인 Hello Class를 실제 반영하기 위해서는 $WILDFLY_HOME/modules/kkm/main 디렉토리 밑에 b번에서 생성한 jar 파일을 업로드 하면되겠네요.

 

d. module.xml 파일을 생성합니다.

- 앞서 가이드 한데로 필요한 정보를 입력한 module.xml 파일을 작성합니다. 

[wildfly@NRSON main]$ pwd
/home/wildfly/wildfly11/modules/kkm/main

[wildfly@NRSON main]$ ls -la
합계 8
drwxrwxr-x 2 wildfly wildfly   38  3월 26 11:08 .
drwxrwxr-x 3 wildfly wildfly   18  3월 26 11:07 ..
-rw-rw-r-- 1 wildfly wildfly  827  3월 26 11:08 Hello.jar
-rw-r--r-- 1 wildfly wildfly 1218  3월 26 11:08 module.xml
[wildfly@NRSON main]$ cat module.xml
<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ JBoss, Home of Professional Open Source.
  ~ Copyright 2010, Red Hat, Inc., and individual contributors
  ~ as indicated by the @author tags. See the copyright.txt file in the
  ~ distribution for a full listing of individual contributors.
  ~
  ~ This is free software; you can redistribute it and/or modify it
  ~ under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ This software is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  ~ Lesser General Public License for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public
  ~ License along with this software; if not, write to the Free
  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  -->

<module xmlns="urn:jboss:module:1.5" name="kkm">
    <resources>
        <resource-root path="Hello.jar"/>
    </resources>
</module>

[wildfly@NRSON main]$ 

- 앞서 설명한 내용이지만 되짚어 보자면, module name = kkm은 실제 Hello class가 위치한 Package 경로라고 보면되고, resources에 실제 반영 되어야 할 jar 파일을 등록하면 됩니다.

 

e. standalone.xml 파일 작성 

<subsystem xmlns="urn:jboss:domain:ee:4.0">
            <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
            <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
            <global-modules>
                <module name="kkm" slot="main" />
            </global-modules>

            <concurrent>
                <context-services>
                    <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
                </context-services>
                <managed-thread-factories>
                    <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
                </managed-thread-factories>
                <managed-executor-services>
                    <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
                </managed-executor-services>
                <managed-scheduled-executor-services>
                    <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
                </managed-scheduled-executor-services>
            </concurrent>
            <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
</subsystem> 

 

- subsystem ee에 빨간색으로 표시한 부분을 추가해 줍니다.

 

f. 재기동을 수행합니다.

- 위 일련의 과정 중 module.xml 작성 또는 jar 파일 위치가 잘못 되었을 경우 아래와 같은 Exception이 발생할 수 있습니다. 

2018-03-26 10:24:05,050 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC000001: Failed to start service jboss.module.service."deployment.bmt.war".main: org.jboss.msc.service.StartException in service jboss.module.service."deployment.bmt.war".main: WFLYSRV0179: Failed to load module: deployment.bmt.war
        at org.jboss.as.server.moduleservice.ModuleLoadService.start(ModuleLoadService.java:91)
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:2032)
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1955)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.modules.ModuleNotFoundException: kkm
        at org.jboss.modules.Module.addPaths(Module.java:1217)
        at org.jboss.modules.Module.link(Module.java:1573)
        at org.jboss.modules.Module.relinkIfNecessary(Module.java:1601)
        at org.jboss.modules.ModuleLoader.loadModule(ModuleLoader.java:287)
        at org.jboss.modules.ModuleLoader.loadModule(ModuleLoader.java:271)
        at org.jboss.as.server.moduleservice.ModuleLoadService.start(ModuleLoadService.java:68)
        ... 5 more

 

g. 정상 재기동이 완료되면 해당 api 호출이 되는지 확인해 보겠습니다.

- 테스트는 WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final)에서 수행되었습니다.

- api 테스트를 위해 별도의 application은 deploy 하지 않았습니다.

 

확인방법 1) ClassInfo.jsp로 해당 Hello Class Loading 됐는지 여부 확인

- 위와 같이 Hello.jar 파일의 Hello Class가 정상 로딩된것을 확인할 수 있다.

 

확인방법 2) Hello.jsp로 getName 메소드를 호출해 본다.

- 위와 같이 HelloTest : Hello!!!가 정상 호출되는 것을 확인 할 수 있다.

  

2. 라이브러리 우선순위 테스트

자 그럼 기존에 기본으로 제공하는 라이브러리를 수정 반영해야 할 경우 어떻게 수행해야 하는지 고민해 보자.

예를 들어 undertow의 wildfly-undertow-11.0.0.Final.jar 파일 내부에 servlet-engine 관련 수정사항이 발생했다고 생각해 보자.

 

반영 할 수 있는 방법은 두가지 정도로 생각해 볼수있다.

반영방법 1) 기존 wildfly-undertow-11.0.0.Final.jar파일을 백업 한 후 신규 wildfly-undertow-11.0.0.Final.jar파일을 덮어쓴다.

- 위 방법을 사용할 경우 wildfly-undertow-11.0.0.Final.jar의 버전관리 측면에서 문제가 발생 할 수 있고 원본 소스를 유지하지 못한다는 단점이 존재한다.

반영방법 2) 클래스 로더 또는 라이브러리 패스의 우선순위에 따라 반영한다.

- 두번째 방법을 택하게 되면 기존 핵심 라이브러리는 그상태 그래도 두고 수정한 패치 소스만 업로드 하여 반영하는 방법을 사용한다면, 보다 관리 측면이나 패치 이력관리, 운영 측면 모두 이점을 갖을 수 있겠다.

 

이에 두번째 반영방법에 대해 알아보도록 하자.

a. 위 1번에서 살펴 보았던 Hello Class를 동일하게 하나더 만들되 Retun 값을 Hi로 갖는 Class를 생성한다.  

package kkm;

public class Hello {

private String name="HiTest : hi!!!";

public void setName(String name) {
    this.name=name;
}

public String getName() {
    return name;
}

}

 

b. 해당 파일을 특정 디렉토리에 업로드 한다.

- 앞서 설명했던 내용과 빗대어 위치 하데 기존 modules 디렉토리 이외에 jboss에서 사용하는 modules.ext 디렉토리를 만들어 업로드 한다.

$WILDFLY_HOME/modules.ext/package_location/main

기존과 다르게 위와 같이 변경되겠네요.

jar 파일명은 class 로딩에 전혀 영향을 주지 않으니 Hi.jar로 업로드를 하도록 하겠습니다.

 

c. module.xml 파일을 생성합니다.

- 앞서 가이드 한데로 필요한 정보를 입력한 module.xml 파일을 작성합니다. 

[wildfly@NRSON main]$ pwd
/home/wildfly/wildfly11/modules.ext/kkm/main

[wildfly@NRSON main]$ ls -la
합계 8
drwxrwxr-x 2 wildfly wildfly   38  3월 26 11:08 .
drwxrwxr-x 3 wildfly wildfly   18  3월 26 11:07 ..
-rw-rw-r-- 1 wildfly wildfly  827  3월 26 11:08 Hi.jar
-rw-r--r-- 1 wildfly wildfly 1218  3월 26 11:08 module.xml
[wildfly@NRSON main]$ cat module.xml
<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ JBoss, Home of Professional Open Source.
  ~ Copyright 2010, Red Hat, Inc., and individual contributors
  ~ as indicated by the @author tags. See the copyright.txt file in the
  ~ distribution for a full listing of individual contributors.
  ~
  ~ This is free software; you can redistribute it and/or modify it
  ~ under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ This software is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  ~ Lesser General Public License for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public
  ~ License along with this software; if not, write to the Free
  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  -->

<module xmlns="urn:jboss:module:1.5" name="kkm">
    <resources>
        <resource-root path="Hi.jar"/>
    </resources>
</module>

[wildfly@NRSON main]$ 

- 앞서 설명한 내용이지만 되짚어 보자면, module name = kkm은 실제 Hello class가 위치한 Package 경로라고 보면되고, resources에 실제 반영 되어야 할 jar 파일을 등록하면 됩니다.

 

d. 재기동을 수행합니다.

 

# 중간 확인사항

현재 상태를 되짚어 보면 다음과 같습니다.

- stanalone 서버에는 별도의 application이 deploy되어 있지 않다.

- modules 디렉토리에 Hello.jar 파일을 반영한다.

- modules.ext 디렉토리에 Hi.jar 파일을 반영한다.

- standalone.xml 파일에 global-modules에 해당 모듈 명을 등록한다. (Hello.jar와 Hi.jar는 동일한 module name을 갖고 있다)

 

위와 같은 상태로 호출을 하면 앞서 확인했던 결과와 동일하게 나옵니다.

확인방법 1) ClassInfo.jsp로 해당 Hello Class Loading 됐는지 여부 확인

- 위와 같이 Hello.jar 파일의 Hello Class가 로딩된것을 확인할 수 있다.

 

확인방법 2) Hello.jsp로 getName 메소드를 호출해 본다.

- 위와 같이 HelloTest : Hello!!!가 호출되는 것을 확인 할 수 있다.

 

e. 중요한 것은 어떠한 방법으로 Hello가 아닌 Hi를 호출할 수 있느냐입니다.

여러 테스트를 거치다 보니 다음과 같은 방법으로 변경방법을 찾게 되었습니다.

 

[$WILDFLY_HOME/bin/standalone.sh or standalone.bat 수정]

....

if [ "x$JBOSS_MODULEPATH" = "x" ]; then
    JBOSS_MODULEPATH="$JBOSS_HOME/modules"
fi 

....

 

=> 아래와 같이 변경

 

....

if [ "x$JBOSS_MODULEPATH" = "x" ]; then
    JBOSS_MODULEPATH="$JBOSS_HOME/modules.ext:$JBOSS_HOME/modules"
fi 

....

- 위의 변경 의미는 Wildfly에서 module을 읽어 올때 어느 위치의 jar파일을 먼저 읽어 올 것인지에 대한 의미로 해석하면 될 것입니다. 

 

f. 자 그럼 마지막으로 재기동 이후 테스트를 수행해 보겠습니다.

확인방법 1) ClassInfo.jsp로 해당 Hello Class Loading 됐는지 여부 확인

- 위와 같이 기존 Hello.jar가 아닌 Hi.jar 파일의 Hello Class가 로딩된것을 확인할 수 있다.

 

확인방법 2) Hello.jsp로 getName 메소드를 호출해 본다.

- 위와 같이 HiTest : hi!!!가 호출되는 것을 확인 할 수 있다.

 

3. 결론

공통라이브러리를 개발하거나 추가하는 방법

- modules 디렉토리를 활용하여 특정경로에 업로드 하고 module.xml을 작성하여 등록할 수 있다.

 

라이브러리 우선순위 테스트 결과

- standalone.sh 파일의 JBOSS_MODULEPATH의 우선순위에 따라 먼저 로딩한다.

 

다음시간에 뵈요~

고맙습니다.

#첨부

ClassInfo.jsp

ClassInfo.jsp

 

728x90
반응형