13장. 웹 서비스 서브시스템

Name

Date

Reason For Changes

Version

오픈나루

2013/11

Initial Version

1.0

전준식, jjeon@opennaru.com

2018/02

Second Version

2.0

물리적으로 떨어진 시스템에서 동작하는 애플리케이션 간 네트워크를 통해 정보를 교환해야 하는 필요성이 점점 높아져 가고 있다.

흔히 우리가 사용하는 가장 간단한 방법은 HTTP 프로토콜을 사용하여 웹 브라우저에서 웹 서버의 정보를 검색하는 것이다. ‘시스템’과 ’사람’을 연결하는 이러한 방법을 애플리케이션 간의 통신에도 사용할 수 있다. 즉 웹에서 사용되는 표준 기술들을 이용하여 시스템과 시스템을 연결하는 서비스에 적용하는 것으로 이것을 ‘웹 서비스(Web Services)’라고 한다.

웹 서비스는 네트워크에 있는 다른 애플리케이션들이 서로 '메시지’를 송수신하여 서로 연계하는 기술이다. ’웹 서비스’라고 한마디로 표현되지만, 내부적으로는 다양한 기술들을 사용하여 구성한다. 메시지 내용은 메시징 서브시스템에서 설명한 ‘비동기’ 처리와도 결합하여 사용할 수 있다.

JBoss EAP 6에서 웹 서비스는 JBoss WS(http://www.jboss.org/jbossws)를 사용하여 구현되어 있다. JBoss WS 내부적으로는 Apache CXF를 사용하고 있다. 물론 Java EE 표준 웹 서비스를 지원한다.

이번 장에서 웹 서비스의 기본적인 개념들과 JBoss EAP 6의 웹 서비스 서브시스템에 대해서 살펴보자.

13-1.웹 서비스 개요

웹 서비스의 핵심 기술들

웹 서비스를 구성하는 여러 가지 많은 기술이 있지만, 그 중에서도 핵심이 되는 것이 SOAP과 WSDL이다.

image46

그림 1. 웹 서비스의 개념도

SOAP

SOAP(Simple Object Access Protocol)은 웹 서비스에 사용되는 메시지 형식 및 규칙 등을 정의한 규약이다. HTTP, HTTPS, SMTP 등을 사용하여 XML 기반의 메시지를 서버들 간에 교환하는 형태의 프로토콜이다. SOAP 메시지는 다음 그림과 같이 Envelope, Header, Body로 구성된다.

http://blog.jdevelop.eu/uploads/2008/03/soapmessage.gif

그림 2. SOAP 메시지 포맷

WSDL

SOAP 인터페이스는 XML 기반의 WSDL(Web Services Description Language)로 정의된다. WSDL은 웹 서비스가 '어디에 있는지', '어떤 메시지 포맷을 이용하는지’, ‘어떤 통신 프로토콜을 이용하는지’ 등 웹 서비스를 사용하는 데 필요한 정보가 들어 있다.

File:WSDL 11vs20.png

그림 . WSDL의 구조

REST

최근에는 SOAP과 WSDL 대신 ‘REST(REpresentational State Transfer)'라는 기술을 사용하는 경우가 많다. REST는 HTTP를 사용하여 통신하는 방법이며, XML이나 JSON(JavaScript Object Notation)을 메시지 포맷으로 사용하고 있다.

UDDI

UDDI(Universal Description, Discovery and Integration)는 필요한 웹 서비스를 찾아보기 위한 검색 시스템이다.

웹 서비스 제공자는 웹 서비스를 UDDI 시스템에 등록하고, 사용자는 UDDI에서 검색하여 웹 서비스를 이용하는 구조이지만, 현재는 거의 이용되지 않는다. 그 이유는 접속할 대상을 알고 있으면 웹 서비스를 검색하여 사용하는 구조가 필요 없기 때문이다.

또 UDDI는 웹 검색 엔진과 같이 웹 서비스에 대한 정보를 반환하는 역할만 하며, 같은 웹 서비스도 공급자에 따라 인터페이스가 전혀 달라진다는 것이 더욱 사용하기 어렵게 만들었다.

13-2.JAX-WS 웹 서비스

JAX-WS(Java API for XML Web Services)는 Java EE 플랫폼에 포함된 API를 사용하여 웹 서비스를 만드는 기술이다. 웹 서비스는 주로 XML 및 구조화된 텍스트 형식으로 정보 교환 등 네트워크에서 통신할 수 있는 표준이다. 웹 서비스는 플랫폼 독립적이다. JAX-WS 애플리케이션은 클라이언트/서버 모델을 사용한다. 서버 컴포넌트를 웹 서비스 엔드 포인트라고 한다.

웹 서비스의 기능을 구현하기 위해 Java EE에서는 JSR-220 JAX-WS라는 표준API를 제공한다.

JAX-WS는 Java SE 5에서 도입된 어노테이션을 사용하여 웹 서비스 서버 모듈과 클라이언트 개발이 쉽다. JAX-WS는 JAX-RPC 표준을 발전시킨 것으로 XML의 바인딩을 위한 JAXB 표준과 표준 스트리밍 파싱 API인 StAX 표준, 기능이 향상된 새로운 SAAJ(SOAP with Attachments API for Java) 표준을 기반으로 통합한 API이다.

JAX-WS는 XML 기반 통신에 SOAP과 REST를 사용한 웹 서비스를 처리하기 위한 API이다.

이전에는 JAX-RPC(Java API for XML Based RPC)라고 불리며, Java 프로그램에서 RPC원격 프로그램 호출을 위한 API 표준이 있었다. JAX-WS 버전은 2.0이며, JAX-RPC 1.1의 후속 표준이기 때문에 JAX-WS 버전 1.0은 없다.

http://disciplinas.ist.utl.pt/~leic-sod.daemon/2012-2013/labs/lab3/jax-ws/jax-ws.png

그림 4. JAX-WS 개념도

JAX-WS에서 주고받는 메시지는 Java 객체에서 자동으로 생성된다. XML을 기반으로 하고 있기 때문에 다른 플랫폼과 연계하여 사용할 수 있다.

JAX-WS는 WS-Notification, WS-Addressing, WS-Policy, WS-Security, WS-Trust 등의 웹 서비스 프로토콜들을 지원하고 있다. 이런 프로토콜들은 메시지 구조 및 메시지 형식을 정의하는 XML기반 SOAP메시지를 사용하여 통신한다.

웹 서비스 엔드 포인트는 웹 서비스 인터페이스와 웹 메서드 인터페이스를 구현하는 클래스로 구성된다.

웹 서비스 클라이언트는 WSDL 정의를 사용하여 생성한 스텁이라는 클래스를 사용하여 작성한다.

JBoss EAP 6에는 JAX-WS 웹 서비스 앤드 포인트의 배포를 지원하는 기능이 포함되어 있다. 이런 기능은 JBossWS에 의해 제공된다. 엔드 포인트 등을 설정하려면 웹 서비스 서브시스템을 사용한다.

JAXB

Java 및 XML 데이터의 맵핑은 ‘JAXB(Java Architecture for XML Binding)’가 이용된다. JAXB는 Java 오브젝트를 XML로 변환하는 표준이며, 반대로 XML에서 Java 객체로 변환도 가능하다.

JAXB를 사용하면 특별히 신경 쓰지 않고도 Java 객체와 XML간의 상호 맵핑이 가능하다. 따라서 웹 서비스를 구축할 경우, 사용자는 프로토콜을 전혀 의식하지 않고 메시지를 주고받을 수 있어 개발 부담이 많이 줄어든다.

Stub와 Tie

JAX-WS를 사용할 때 사용자의 Java 프로그램과 공급자 Java 프로그램의 통신을 위한 프로그램을 직접 코딩할 필요가 없다. 사용자 Java 프로그램의 Stub과 공급자 프로그램의 Tie가 서로 통신을 수행한다. 이때 Tie가 Stub을 자동으로 생성하기 때문에 개발 시 통신에 대해서는 신경 쓸 필요 없다. 일반적인 원격 메서드 호출뿐만 아니라 SOAP을 사용하여 XML 문서도 송수신할 수 있다. 다음 그림은 웹 서비스 공급자와 클라이언트 간의 통신 방식을 보여준다.

http://www.ibm.com/developerworks/webservices/library/ws-devaxis2part2/Jaxwsarchitecture.jpg

그림 5. JAX-WS 웹 서비스와 클라이언트 간의 통신

13-3.확장 프로토콜 WS-* 표준

웹 서비스를 확장하는 WS-* 표준들은 다음과 같은 것이 있다.

  • WS-Security -디지털 서명, 사용자 인증, 메시지의 암호화 메커니즘을 제공

  • WS-Addressing - 메시지 정보 헤더를 XML 메시지에 유지하는 방법을 제공

  • WS-Policy - XML 보안 정책 등의 정책 설명하고 그것을 외부에 공개하는 방법을 제공

  • WS-Reliable Messaging - SOAP 메시지에서 안정적인 메시지 전달을 제공

  • WS-Coordination - 여러 웹 서비스를 연계하여 상호 연결하기 위한 구조를 제공

JBossWS가 제공하는 기능

JBossWS가 지원하는 웹 서비스 표준들의 전체 구조를 설명하려고 한다.

기본 표준인 XML이나 메시징 위에 확장 표준인 보안이나 트랜잭션 처리에 관한 표준들로 구성되어 있다. 또, 메타데이터는 웹 서비스들끼리 통신하기 위한 스키마을 제공하는 프로토콜들이다.

다음 그림은 JBoss EAP 6가 지원하는 웹 서비스 표준들을 도식화한 것이다.

image

그림 6. JBoss EAP 6 웹 서비스 표준

구분 표준 설명

XML 표준

XML

XML(eXtensible Markup Language)은 W3C에서 HTML과는 다른 특수 목적의 마크업 언어를 만드는 용도로 권장하는 다목적 마크업 언어이다. XML은 SGML의 단순화된 부분집합이지만, 수많은 종류의 데이터를 기술하는 데 사용할 수 있다. XML은 주로 다른 시스템, 특히 인터넷에 연결된 시스템 간에 데이터를 쉽게 주고받을 수 있도록 만들어졌다.

XML Schema

XML 문서의 구조와 엘리먼트, 속성 간의 관계를 정의하여 다양한 자료형을 만들어 사용할 수 있도록 정의된 문서 구조

메시징 표준

SOAP

SOAP(Simple Object Access Protocol)은 일반적으로 널리 알려진 HTTP, HTTPS, SMTP 등을 사용하여 XML 기반의 메시지를 컴퓨터 네트워크상에서 교환하는 형태의 프로토콜이다. SOAP은 웹 서비스에서 메시지를 전달하는 기반이 된다.

MTOM

MTOM(Message Transmission Optimization Mechanism, 메시지 전송 최적화 메커니즘)은 효율적인 전송을 위해 웹 서비스에서 이진 데이터를 전송하기 위한 표준으로 W3C에서 제정하였다.

MTOM에서는 이진 데이터 전송에 MIME이나 DIME가 아닌 XOP(XML-binary Optimized Packaging)를 사용한다.

WS-Addressing

WS-Addressing은 WS-Routing과 WS-Referral의 기술을 대체하는 표준으로 2003년도에 새롭게 발표된 표준이다.

WS-Addressing에서는 라우팅 경로뿐만 아니라 SOAP Envelope에 To 및 From 헤더를 추가하여 사용하는 편리한 방식을 제공하고 있다.

신뢰성 메시지 표준

WS-ReliableMessaging

신뢰성 있는 SOAP 메시지 전달을 가능하게 하는 프로토콜. SOAP 메시지를 교환할 때 전달 보증, 중복 방지, 메시지 순서 보장 등의 기능을 제공한다.

웹 서비스 보안 표준

WS-Trust

WS-Security 사양을 확장해, 보안 토큰의 요구와 발행, 신뢰 관계의 관리를 지원하는 프로토콜.

WS-Security

웹 서비스 환경에서 메시지를 암호화하여 안전한 SOAP 메시지의 송수신을 지원하기 위한 프로토콜. SSL은 전송 계층 수준에서 전체 메시지를 암호화하는 방식이라면, WS-Security는 부분 메시지만 암호화하는 방식이다.

트랜잭션 표준

WS-Coordination

웹 서비스에서 분산되어 실행되는 처리를 연동하기 위한 표준. 상호 접속 가능한 웹 서비스를 제어할 수 있다.

WS-Transaction

오랫동안 실행되는 트랜잭션에서 애플리케이션 간에 일관성을 유지할 수 있도록 하는 표준이다.

메타데이터

WSDL

웹 서비스의 위치, 메시지 포맷, 통신 프로토콜 등을 정의하는 표준

표 1. JBoss EAP 6의 주요 웹 서비스 표준

13-4.JAX-RS 웹서비스

JAX-RS(Java API for RESTful Web Services)는 자바 플랫폼에서 REST 방식의 웹 애플리케이션을 구현할 수 있도록 제공하는 자바 API이다.

SOAP기반의 연동은 자바 애플리케이션을 무겁게 한다는 비판이 많았다. 최근 웹 애플리케이션에서는 AJAX기반의 JSON이나 RSS와 같이 간결한 프로토콜을 사용하는 연동방법이 개발에 많이 사용하고 있다. Java EE에서도 이런 방식을 쉽게 구현할 수 있도록 JAX-RS 표준을 제공한다.

JBoss EAP 6에서는 JBoss RESTEasy(http://www.jboss.org/resteasy)를 사용하여 구현되어 있다. RESTEasy 프레임워크도 어노테이션을 사용하여 JAX-RS를 쉽게 구현할 수 있다.

13-5.JBossWS 구성

JBoss EAP 6에서는 기본으로Apache CXF 스택인 JBossWS-CXF를 사용하고 있지만 JBoss의 독자적인 구현 스택인 JBossWS-Native도 사용할 수 있다.

JBossWS-CXF는 JBossWS에서 Apache CXF를 사용하기 위한 모듈이며, Apache CXF의 WSDL 바인딩, WS-* 지원 기능을 사용한다. 또, JBoss EAP 6에서 JAX-RPC를 지원하기 위해 JBossWS-Native 모듈을 함께 사용하고 있다.

JBoss EAP 6에 배포된 웹 서비스 동작을 제어할 수 있다. 관리 콘솔에서는 ‘Profile’ ‘Web’ ‘Web Services’에서 설정할 수 있다.

image

그림 7. 웹 서비스 서브 시스템 설정

파라미터 설명

modify-wsdl-address

기본적으로 JBoss의 IP주소가 WSDL의 주소가 된다. 웹 서버나 도메인 이름을 통해 웹 서비스를 제공하면 이 주소로 WSDL 주소를 변경해야 한다. true이면 <soap:address>의 값을 wsdl-host, wsdl-port의 값을 지정한 값으로 덮어쓴다. false이면 <soap:address>의 URL이 유효하지 않은 경우에만 덮어쓴다.

/subsystem=webservices/:write-attribute(name=modify-wsdl-address, value=true)

wsdl-host

<soap:address>를 덮어쓸 때 사용할 호스트 이름이나 IP 주소를 설정한다. jbossws.undefined.host 로 설정하면 <soap:address> 요청자의 호스트가 사용된다.

/subsystem=webservices /:write-attribute(name=wsdl-host, value=192.168.0.100)

wsdl-port

<soap:address>를 덮어쓸 때 사용하는 HTTP 포트번호이다. 정의하지 않으면, 설치된 HTTP 커넥터를 찾아 그 HTTP 포트를 사용한다.

/subsystem=webservices/:write-attribute(name=wsdl-port, value=8080)

wsdl-secure-port

<soap:address>를 덮어쓸 때 사용하는 HTTPS 포트번호이다. 정의하지 않으면, 설치된 HTTPS 커넥터를 찾아 그 HTTPS 포트를 사용한다.

/subsystem=webservices/:write-attribute(name=wsdl-secure-port, value=8443)

표 2. 웹 서비스의 주요 설정 항목

CLI를 사용하여 아래와 같이 JBossWS의 웹 서비스 서브 시스템을 설정한다.

[standalone@localhost:9999 /] cd /subsystem=webservices

[standalone@localhost:9999 subsystem=webservices] :write-attribute(name=modify-wsdl-address, value=true)

{
  "outcome" => "success",
  "response-headers" => {
    "operation-requires-reload" => true,
    "process-state" => "reload-required"
  }
}

read-resource 명령으로 설정된 내용을 확인한다.

[standalone@localhost:9999 subsystem=webservices] :read-resource

{
  "outcome" => "success",
  "result" => {
    "endpoint" => {},
    "modify-wsdl-address" => true,
    "wsdl-host" => "jbossws.undefined.host",
    "wsdl-port" => 80,
    "wsdl-secure-port" => 443,
    "endpoint-config" => {
      "Standard-Endpoint-Config" => undefined,
      "Recording-Endpoint-Config" => undefined
    }
  },
  "response-headers" => {"process-state" => "reload-required"}
}

13-6.웹 서비스 개발

웹 서비스를 개발하는 방법은 두 가지가 있다. 첫 번째 방법은 새로운 웹 서비스를 제공하기 위해 Java 코드로 개발하여 배포하고 웹 서비스에 대한 WSDL을 제공하는 방법이 있다. 또 다른 방법은 웹 서비스가 제공해야 할 WSDL이 주어진 경우, 이에 맞는 웹 서비스를 개발해야 하는 경우이다.

Java 코드에서부터 개발하는 방식을 Bottom-up 개발 방식이라고 하며, WSDL에서 시작하는 방식을 Top-down 개발 방식이라고 한다.

Bottom-up을 사용하는 경우 :

  • 이미 존재하는 EJB 3 빈을 웹 서비스로 제공하고자 할 때

  • 새로운 서비스를 제공하는 WSDL을 생성해야 할 때

Top-down을 사용하는 경우 :

  • 다른 언어로 개발된 기존의 웹 서비스를 Java로 다시 개발하여야 할 때

  • 예전 클라이언트와 호환을 유지하며 재개발해야 할 때

  • 먼저 수동으로 개발된 WSDL과 XML 스키마를 준수하는 서비스를 만들 때

먼저 Java 코드에서 웹 서비스를 개발하는 방법을 살펴보자. 다음과 같이 문자열를 반환하는 간단한 Hello 웹 서비스를 개발하였다. Hello 웹 서비스는 @WebService 어노테이션을 사용하여 웹 서비스 클래스를 지정하였고, @WebMethod 어노테이션으로 웹 서비스의 메서드를 지정하였다.

package com.opennaru.wstest;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService()
public class Hello {
  private String message = new String("Hello, ");

  public void Hello() {
  }

  @WebMethod()
  public String sayHello(String name) {
    return message + name + ".";
  }

}

이 웹 서비스를 WAR에 패키징하기 위하여 web.xml에 서블릿으로 등록한다.

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <servlet-name>HelloService</servlet-name>
    <servlet-class>com.opennaru.wstest.Hello</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>HelloService</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

WAR로 패키징한 애플리케이션을 배포하면 ‘Runtime’ ‘Status’ ‘Subsystems’ ‘Webservices’ 에서 WSDL URL을 확인할 수 있다.

image

그림 8. 웹 서비스 엔드 포인트

제공하는 서비스에 대한 WSDL URL에 접근하면 웹 서비스에 대한 WSDL이 브라우저에 표시된다.

image

그림 9. Hello 웹 서비스의 WSDL

Hello 웹 서비스를 테스트하려면 웹 서비스에 접속하는 클라이언트가 필요하다.

먼저 pom.xml 파일에 JBossWS의 클라이언트에서 필요한 jar파일인 jbossws-cxf-client를 <dependency>에 추가한다.

<dependency>
  <groupId>org.jboss.ws.cxf</groupId>
  <artifactId>jbossws-cxf-client</artifactId>
  <version>4.2.3.Final</version>
</dependency>

또, Hello 웹서비스가 제공하는 WSDL에서 Java 코드를 생성하여 사용하기 위해서 Hello 웹 서비스의 WSDL 파일을 이클립스 프로젝트의 src/test/resources/hellows.wsdl 파일로 저장한다.

메이븐에서 WSDL에서 클라이언트 Java코드를 생성하려면 아래와 같이 maven-jaxws-tools-plugin의 wsconsume을 사용하도록 pom.xml에 설정한다.

<plugin>
  <groupId>org.jboss.ws.plugins</groupId>
  <artifactId>maven-jaxws-tools-plugin</artifactId>
  <version>1.1.1.Final</version>
  <executions>
    <execution>
      <id>My execution</id>
      <goals>
        <goal>wsconsume</goal>
      </goals>
      <configuration>
        <wsdls>
          <wsdl>$\{basedir}/src/test/resources/hellows.wsdl</wsdl>
        </wsdls>
        <targetPackage>com.opennaru.wstest</targetPackage>
        <sourceDirectory>$\{basedir}/src/test/java</sourceDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

메이븐으로 빌드하면 <sourceDirectory>에 지정한 src/test/java 디렉터리에 Java 파일이 생성된다. 이 파일을 사용하는 클라이언트를 다음과 같이 작성한다.

package com.opennaru.wsclient;

import javax.xml.ws.Service;
import com.opennaru.wstest.Hello;
import com.opennaru.wstest.HelloService;

public class HelloClient {
  public static void main(String[] args) {
    try {
      String name = "JBoss EAP 6";
      Service service = Service.create(
        HelloService.WSDL_LOCATION,
        HelloService.SERVICE
      );

      Hello hello = service.getPort(Hello.class);
      String message = hello.sayHello(name);

      System.out.println("message=" + message);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

위 클라이언트 코드를 실행하면, Hello 웹 서비스를 호출하여 콘솔에 다음과 같은 메시지가 출력된다.

message=Hello, JBoss EAP 6.

Hello 웹 서비스에서는 WSDL에서 Java 클라이언트 코드를 생성하기 위해 wsconsume을 메이븐 플러그인으로 실행하였다. 예제에서는 WAR 애플리케이션을 배포하면 자동으로 생성되는 WSDL을 사용하였다. 만약 배포하지 않고 WSDL을 생성하려면 메이븐 플러그인의 골(goal)을 wsprovide로 변경하면 Java 코드에서 WSDL이 생성할 수 있을 것이다.

또, 콘솔 명령으로 wsconsume, wsprovide를 제공하고 있다. 사용법은 다음과 같다.

명령 설명

wsprovide

웹 서비스로 제공될 Java 구현 클래스로에서 WSDL과 Schema 파일을 생성한다. Bottom-up 개발에 사용된다.

$ ./wsprovide.sh -w com.opennaru.wstest.Hello -c /home/jboss/workspaces/ hellows/target/hellows/WEB-INF/classes

Could not find log4j.xml configuration, logging to console.

java2ws -s /home/jboss/eap/jboss-eap-6.1/bin/output -classdir /home/ jboss/eap/jboss-eap-6.1/bin/output -d /home/jjeon/jboss/eap/jboss-eap-6.1/bin/output -verbose -wsdl -cp /home/jboss/workspaces/hellows/target/hellows/WEB-INF/classes/: -wrapperbean -createxsdimports com.opennaru.wstest.Hello

java2ws - Apache CXF 2.6.6-redhat-3

wsconsume

WSDL과 Schema 파일에서 서버 및 클라이언트에 사용할 수 있는 Java 파일을 생성한다. 주로, 웹 서비스의 클라이언트 프로그램을 생성할 때 사용하는 툴이다.

$ ./wsconsume.sh -k hellows.xml

Could not find log4j.xml configuration, logging to console.

Loading FrontEnd jaxws ...

Loading DataBinding jaxb ...

wsdl2java -compile -exsh false -d /home/jboss/eap/jboss-eap-6.1/bin/output -verbose -classdir /home/jboss/eap/jboss-eap-6.1/bin/output -allowElementReferences file:/home/jboss/eap/jboss-eap-6.1/bin/hellows.xml

wsdl2java - Apache CXF 2.6.6-redhat-3

13-7.웹 서비스의 모듈 설정

JBoss EAP 6에 웹 서비스를 배포할 때, 모듈 의존성에 주의하여야 한다. JBoss EAP 6의 웹 서비스가 구현된 애플리케이션도 모듈로 관리한다. 웹 서비스 구현체인 JBossWS구현 모듈에 대해서 암시적인 의존성이 설정되지 않기 때문에 필요하면 명시적으로 의존성을 설정해야 한다. 모듈의 명시적인 의존성의 설정은, jboss-deployment-structure.xml 또는 MANIFEST.MF를 사용해 설정한다. jboss-deployment-structure.xml 파일의 예제는 다음과 같다.

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
  <deployment>
    <dependencies>
      <module name="org.jboss.ws.cxf.jbossws-cxf-client services export" />
      <module name="org.apache.ws.xmlschema services export" />
      <module name="org.apache.ws.security services export" />
    </dependencies>
  </deployment>
</jboss-deployment-structure>

또, 애플리케이션에서 JAX-RS구현체로 JBoss RESTEasy가 아닌 Jersey를 사용하면 다음과 같이 jboss-deployment-structure.xml 파일에 모듈 의존성을 설정하여야 한다.

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
  <deployment>
    <dependencies>
      <system>
        <paths>
          <path name="com/sun/xml/bind/v2/runtime/JAXBContextImpl"/>
        </paths>
      </system>
    </dependencies>
  </deployment>
</jboss-deployment-structure>