[java] java.lang.NoClassDefFoundError를 해결하는 방법 : Java 9의 javax / xml / bind / JAXBException

Java 6/7/8에서 JDK의 일부로 제공되는 JAXB API 클래스를 사용하는 코드가 있습니다. Java 9에서 동일한 코드를 실행하면 런타임에 JAXB 클래스를 찾을 수 없다는 오류가 발생합니다.

JAXB 클래스는 Java 6부터 JDK의 일부로 제공되었으므로 Java 9가 더 이상 이러한 클래스를 찾을 수없는 이유는 무엇입니까?



답변

JAXB API는 Java EE API로 간주되므로 Java SE 9의 기본 클래스 경로에 더 이상 포함되지 않습니다. Java 11에서는 JDK에서 완전히 제거됩니다.

Java 9에는 모듈 개념이 도입되었으며 기본적으로 java.se집계 모듈은 클래스 경로 (또는 모듈 경로)에서 사용할 수 있습니다. 이름에서 알 수 있듯이 java.se집계 모듈에는 전통적으로 Java 6/7/8과 번들로 제공되는 Java EE API가 포함되어 있지 않습니다 .

다행히 JDK 6/7/8에서 제공되는 이러한 Java EE API는 여전히 JDK에 있지만 기본적으로 클래스 경로에는 없습니다. 추가 Java EE API는 다음 모듈에서 제공됩니다.

java.activation
java.corba
java.transaction
java.xml.bind  << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation

빠르고 더러운 솔루션 : (JDK 9/10 만 해당)

런타임시 JAXB API를 사용 가능하게하려면 다음 명령 행 옵션을 지정하십시오.

--add-modules java.xml.bind

그러나 Java 8에서 작동하려면 여전히 이것이 필요합니다 !!!

--add-modules이전 JDK로 지정하려고 하면 인식 할 수없는 옵션이기 때문에 폭파됩니다. 두 가지 옵션 중 하나를 제안합니다.

  1. JDK_JAVA_OPTIONS환경 변수를 사용하여 Java 9+ 전용 옵션을 설정할 수 있습니다 . 이 환경 변수가되고 자동으로 읽기 에 의해 java자바 9+에 대한 발사기.
  2. 를 추가 -XX:+IgnoreUnrecognizedVMOptions하지 않고 JVM이 자동으로 인식되지 않는 옵션을 무시하도록 만들 수 있습니다. 그러나 조심하십시오! 사용하는 다른 명령 줄 인수는 더 이상 JVM에서 확인하지 않습니다. 이 옵션은 Oracle / OpenJDK 및 IBM JDK (JDK 8sr4 기준)와 함께 작동합니다.

대체 빠른 솔루션 : (JDK 9/10 만 해당)

--add-modules java.se.ee옵션 을 지정하여 위의 모든 Java EE 모듈을 런타임에 사용 가능하게 할 수 있습니다 . java.se.ee모듈을 포함하는 집계 모듈 java.se.ee뿐만 아니라 위의 자바 EE API 모듈. 참고,이 자바 (11)에서 작동하지 않습니다 때문에 java.se.ee자바 (11)에서 제거되었다.


적절한 장기 솔루션 : (JDK 9 이상)

위에 나열된 Java EE API 모듈은 모두 Java 11 에서 제거 예정@Deprecated(forRemoval=true) 이므로 표시되어 있습니다. 따라서이 접근 방식은 더 이상 Java 11 기본 제공에서 작동하지 않습니다.--add-module

Java 11 이상에서 수행해야 할 작업은 클래스 경로 또는 모듈 경로에 자신의 Java EE API 사본을 포함시키는 것입니다. 예를 들어 JAX-B API를 다음과 같이 Maven 종속성으로 추가 할 수 있습니다.

<!-- API, java.xml.bind module -->
<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>2.3.2</version>
</dependency>

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.2</version>
</dependency>

JAXB에 대한 자세한 내용 은 JAXB 참조 구현 페이지 를 참조하십시오.

Java 모듈성에 대한 자세한 내용은 JEP 261 : 모듈 시스템을 참조하십시오 .

Gradle 또는 Android Studio 개발자 : (JDK 9 이상)

build.gradle파일에 다음 종속성을 추가 하십시오.

dependencies {
    // JAX-B dependencies for JDK 9+
    implementation "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
    implementation "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}


답변

필자의 경우 (스프링 부트 팻 항아리) pom.xml에 다음을 추가합니다.

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>


답변

최근 JDK 9.0.1에서는 이러한 솔루션 중 어느 것도 제대로 작동하지 않았습니다.

이 종속성 목록이 제대로 작동하기에 충분하다는 것을 알았으므로 명시 적으로 지정할 필요가 없습니다--add-module (이러한 종속성의 pom 내에 지정되어 있음). 이 종속성 목록을 지정하기 만하면됩니다.

<dependencies>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
</dependencies>


답변

이것은 나를 위해 일했다 :

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.7.0</version>
</dependency>

최신 정보

@Jasper가 제안했듯이 전체 EclipseLink 라이브러리에 의존하지 않기 위해 EclipseLink MOXy에 의존 할 수도 있습니다.

메이븐

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.moxy</artifactId>
    <version>2.7.3</version>
</dependency>

그래들

compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3'

Java 8 앱의 종속성으로 추가 인수없이 JRE 8 또는 JRE 9 둘 다에서 실행할 수있는 * .jar을 생성합니다.

또한 JAXB API를 사용하기 전에 어딘가에서 실행해야합니다.

System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");

해결 방법으로 지금까지 잘 작동합니다. 그래도 완벽한 솔루션처럼 보이지는 않습니다 …


답변

모든 JDK에 대한 깨끗한 솔루션> = 9

빌드에 두 가지 종속성을 추가해야합니다

  • jaxb-api
  • jaxb 구현

구현으로 나는 glass com의 참조 구현을 사용하여 오래된 com.sun 클래스 / 라이브러리를 제거하기로 결정했습니다. 결과적으로 maven 빌드에 추가했습니다.

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.1</version>
</dependency>

<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>2.3.1</version>
</dependency>

버전 2.3.1부터는 javax.activation을 더 이상 추가 할 필요가 없습니다. ( https://github.com/eclipse-ee4j/jaxb-ri/issues/1222 참조 )


답변

jdk 9 이상 버전을 사용하는 경우 Java 버전이므로 pom에 추가하십시오.

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.0</version>
</dependency>


답변

이 문제를 해결하기 위해 프로젝트에서 일부 JAR 파일을 가져 왔습니다.

  • javax.activation-1.2.0.jar

http://search.maven.org/remotecontent?filepath=com/sun/activation/javax.activation/1.2.0/javax.activation-1.2.0.jar

  • jaxb-api-2.3.0.jar

http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar

  • jaxb-core-2.3.0.jar

http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-core/2.3.0/jaxb-core-2.3.0.jar

  • jaxb-impl-2.3.0.jar

http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar

  1. 위의 파일을 다운로드하여 프로젝트의 libs 폴더에 복사하십시오.
  2. Java 빌드 경로에 가져온 JAR 파일 추가