Je crée un client et un wrapper de serveur pour un réseau neuronal. Le client lit et envoie une image au serveur qui exécute les modèles et répond les résultats au client. J'ai créé un projet multimodule pour cette raison. Lorsque j'exécute le client et le serveur à partir de l'IDE (idée intellij), tout fonctionne correctement. Cependant, lorsque j'utilise maven pour construire puis exécuter à partir du terminal, j'obtiens des erreurs.

Mon pom.xml principal / parent est le suivant:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>gr.enomix</groupId>
<artifactId>imageClassificationWrapper</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<modules>
    <module>Server</module>
    <module>Client</module>
</modules>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

<dependencies>

    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>commons-cli</groupId>
        <artifactId>commons-cli</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.codehaus.plexus</groupId>
        <artifactId>plexus-utils</artifactId>
        <version>2.0.5</version>
        <scope>compile</scope>
    </dependency>

</dependencies>

</project>

Mon serveur pom.xml est:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
    <artifactId>imageClassificationWrapper</artifactId>
    <groupId>gr.enomix</groupId>
    <version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>gr.enomix</groupId>
<artifactId>Server</artifactId>
<packaging>jar</packaging>
<version>1.0</version>

</project>

Et mon client pom.xml est:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
    <artifactId>imageClassificationWrapper</artifactId>
    <groupId>gr.enomix</groupId>
    <version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<groupId>gr.enomix</groupId>
<artifactId>Client</artifactId>
<packaging>jar</packaging>
<version>1.0</version>

</project>

Je veux que toutes les bibliothèques du parent pom.xml soient héritées à la fois du client et du serveur enfants. Ensuite, je cours à partir du terminal mvn clean install et le projet se construit avec succès sans aucune erreur.

Puis enfin j'exécute

   java -cp target/Server-1.0.jar RunServer

Pour exécuter le serveur et

   java -cp target/Client-1.0.jar RunClient

Pour exécuter le client mais j'obtiens des erreurs

Exception in thread "main" java.lang.NoClassDefFoundError:     org/json/simple/JSONObject
    at ImageHttpClient.sendImage(ImageHttpClient.java:78)
    at RunClient.main(RunClient.java:11)

Du client et du serveur.

Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/apache/commons/io/IOUtils
    at     Handlers.ConnectionHandler.readAndSaveImage(ConnectionHandler.java:39)
    at Handlers.ConnectionHandler.run(ConnectionHandler.java:25)
    at java.lang.Thread.run(Thread.java:745)

Les dépendances Maven ne sont pas construites dans le chemin de classe ??? Est-ce que je fais quelque chose de mal?? S'il vous plaît, aidez-moi, je me brise la tête depuis deux jours maintenant ...

0
mixtou 24 nov. 2017 à 16:02

3 réponses

Meilleure réponse

Vos dépendances ne sont pas incluses dans le fichier .jar et sont donc introuvables. D'où le NoClassDefFoundError

Ce que vous devez faire est d'inclure les dépendances dans votre jar, c'est-à-dire de construire un soi-disant "fat jar".

Je ne publierai pas comment faire cela, car il y a déjà beaucoup de messages sur stackoverflow. Comme je le vois, vous en avez déjà dans les commentaires.

EDIT: Pour tester si vos dépendances ont été incluses, vous pouvez ouvrir le fichier .jar généré en utilisant 7zip.

1
DeiAndrei 24 nov. 2017 à 13:16

Lorsque vous développez une application Java autonome, vos dépendances sont toutes utilisées uniquement pour la phase de compilation. Lorsque vous souhaitez exécuter votre code réel, la machine virtuelle Java doit disposer de l'adresse des dépendances données pour exécuter votre code. Pour ce faire, vous devez indiquer explicitement à la machine virtuelle Java où trouver les bibliothèques. Vous pouvez ajouter toutes les bibliothèques à votre option -cp comme ceci:

java -cp {your-maven-repository-folder}/org/apache/common/commons-io/commons-io-1.3.2.jar:target/Client-1.0.jar RunClient

Dans lequel {your-maven-repository-folder} se trouve normalement dans le dossier personnel de votre utilisateur. Par exemple sous Linux, c'est /home/mixtou/.m2/repository.

Vous devez spécifier toutes vos dépendances en les séparant par : sous Linux et ; sous Windows.

Comme vous utilisez déjà IntelliJ, une solution plus simple pourrait être de faire un clic droit sur votre classe RunClient ou RunServer et de sélectionner Run. Ce faisant, IntelliJ essaiera d'exécuter votre projet dans le Run panel et si vous vérifiez la toute première ligne de la sortie d'exécution, vous devriez voir la commande exacte qu'IntelliJ utilise pour exécuter votre code qui inclut toutes les bibliothèques nécessaires.

N'oubliez pas que dans une application Java autonome, aucune dépendance ne serait incluse dans votre fichier jar. Une telle option n'est disponible que dans les applications qui vont être exécutées sur un serveur d'applications en tant que fichier war ou ear. Bien sûr, vous pouvez utiliser des plugins maven qui fusionnent toutes vos bibliothèques dans votre fichier jar (qui est normalement connu sous le nom de fat jar) et vous n'aurez pas besoin de spécifier quoi que ce soit dans classpath, mais votre fichier jar peut devenir trop gros (dépend de le nombre de bibliothèques que vous utilisez) et donc la mise à jour serait plus fastidieuse.

0
zaerymoghaddam 24 nov. 2017 à 13:21

Je pense que vous devriez utiliser la balise dependencyManagement à l'intérieur du pom parent afin de laisser les poms enfants hériter des dépendances.

Vérifiez ce lien

différences entre la gestion de la dépendance et les dépendances dans maven

0
Dogukan Zengin 24 nov. 2017 à 13:13
47473913