web-dev-qa-db-fra.com

L'implémentation de JAXB-API n'a pas été trouvée (lors de l'exécution de Java jar)

J'obtiens une erreur dans la ligne (JAXBContext.newInstance):

    @Override
    public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
    SoapHeader soapHeader = ((SoapMessage)message).getSoapHeader();

    try {
        JAXBContext context = JAXBContext.newInstance(AuthHeader.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.marshal(authentication, soapHeader.getResult());

    } catch (JAXBException e) {
        System.out.println(e.getMessage());
        throw new IOException("error while marshalling authentication.");
    }
}

Bien que cela fonctionne bien lorsque cela est exécuté comme cas de test en utilisant:

 mvn install

ou mvn: spring: boot run

Mais provoque un problème lorsque le fichier jar est exécuté en utilisant:

Java -jar target/fileName-0.0.1-SNAPSHOT.jar 

Erreur lors de l'exécution de Java -jar et frappe à l'aide de postman.

Implementation of JAXB-API has not been found on module path or classpath.

Java.io.IOException: error while marshalling authentication.

Informations sur la version

mvn -version
Apache Maven 3.6.0
Maven home: /usr/share/maven
Java version: 11.0.7, vendor: Ubuntu, runtime: /usr/lib/jvm/Java-11-openjdk-AMD64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-1051-aws", Arch: "AMD64", family: "unix"

Java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu218.04)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-2ubuntu218.04, mixed mode, sharing)

Le même fichier jar fonctionne correctement sur le serveur de développement mais ne fonctionne pas sur le serveur intermédiaire. Les serveurs de développement et de développement ont le même environnement (version Java, mvn, tout est identique). J'ai ces dépendances ajoutées à pom.xml:

    <dependency>
        <groupId>com.Sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.3</version>
    </dependency>

Si cela est lié à fat jar, alors pourquoi d'autres dépendances comme Amazon s3, stripe, etc. Quel est le problème avec jaxb uniquement?

J'ai même essayé de créer un gros pot en utilisant le package mvn avec la configuration suivante:

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
            <execution>
                <goals>
                    <goal>repackage</goal>
                </goals>
                <configuration>
                    <mainClass>com.patracorp.patrapay.PatrapayApplication</mainClass>
                    <layout>Zip</layout>
                </configuration>
            </execution>
        </executions>
    </plugin>

mais toujours la même erreur.

7
Vivek Sadh

Dans Java 9 et versions supérieures, Java a supprimé Java.xml.bind à partir de son chemin de classe par défaut. Vous devez donc ajouter explicitement des fichiers JAR au chemin de classe.

Et ajouter seulement jaxb-impl ne suffira pas, je suppose.
Pouvez-vous ajouter ci-dessous la dépendance dans votre POM, puis l'essayer.

    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>${jaxb-api.version}</version>
    </dependency>
    <dependency>
        <groupId>com.Sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>${jaxb-api.version}</version>
    </dependency>
    <dependency>
        <groupId>com.Sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>${jaxb-api.version}</version>
    </dependency>

Veuillez partager les résultats.

2
Tarun Verma

J'ai créé un petit projet de démarrage à ressort pour résoudre votre problème.

J'utilise spring-boot 2.2.7 RELEASE, Spring Tools Suite 4 IDE & AdoptedOpenJDK 11 sur macOS Catalina.

Juste une note rapide: Vous devez ajouter jaxb-impl & jaxb-core dernière version (pas les anciennes versions).

Sinon, vous risquez de recevoir ce message sur la console:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ......
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Autre chose à noter: Je soupçonne qu'il y a un problème avec le soap marshalling en utilisant jax-ws et jaxb.

Si tel est le cas, reportez-vous à cette SO question: Ajouter SOAP en-tête objet en utilisant pur JAX-WS


Maintenant,

Structure du projet:

enter image description here

J'ai créé un exemple de classe AuthHeader à montrer.

package com.example.demo;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "authreader")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class AuthHeader {

    private String token;

    public AuthHeader() {
        super();
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return "AuthHeader [token=" + token + "]";
    }

}

Pour les tests, j'ai pris la partie du code qui posait problème.

DemoApplication.Java:

package com.example.demo;

import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) throws JAXBException, FileNotFoundException {
        // for testing.
        JAXBContext context = JAXBContext.newInstance(AuthHeader.class);
        Marshaller marshaller = context.createMarshaller();
        AuthHeader header = new AuthHeader();
        header.setToken("set the token");
        OutputStream os = new FileOutputStream("header.xml");
        marshaller.marshal(header, os);
        // call the boot 
        SpringApplication.run(DemoApplication.class, args);
    }

}

La chose la plus importante pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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.0 https://maven.Apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <Java.version>11</Java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>com.Sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.Sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <classifier>executable</classifier>
                            <mainClass>
                                com.example.demo.DemoApplication
                            </mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Quand j'ai fait mvn:spring:boot run, fonctionne alors parfaitement

Production :

enter image description here

J'ai également créé un pot de graisse avec le nom demo-0.0.1-SNAPSHOT-executable.jar comme vous pouvez le voir dans la structure du projet en utilisant mvn install.

Quand je cours hors de ce bocal. Cela fonctionne parfaitement sans donner aucune erreur.

Production :

enter image description here

Le header.xml généré:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<authreader>
  <token>set the token</token>
</authreader>
0
Anish B.