web-dev-qa-db-fra.com

Maven ne définit pas correctement le chemin de classe pour les dépendances

Nom du système d'exploitation: "linux" version: "2.6.32-27-generic" Arch: "i386" Famille: "unix"

Apache Maven 2.2.1 (r801777; 2009-08-06 12: 16: 01-0700)

Version Java: 1.6.0_20

J'essaie d'utiliser la dépendance mysql avec maven dans ubuntu. Si je déplace le fichier "mysql-connector-Java-5.1.14.jar" que j'ai téléchargé dans mon dossier $ Java_HOME/jre/lib/ext /, tout va bien lorsque j'exécute le bocal.

Je pense que je devrais être en mesure de spécifier simplement la dépendance dans le fichier pom.xml et maven devrait prendre soin de définir automatiquement le chemin de classe pour les pots de dépendance. Est-ce incorrect?

Mon fichier pom.xml ressemble à ceci:

<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>com.ion.common</groupId>
  <artifactId>TestPreparation</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>TestPrep</name>
  <url>http://maven.Apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.Apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>

        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.ion.common.App</mainClass>
            </manifest>
          </archive>
        </configuration>

      </plugin>
    </plugins>
  </build>

  <dependencies>

    <!-- JUnit testing dependency -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- MySQL database driver -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-Java</artifactId>
      <version>5.1.14</version>
      <scope>compile</scope>
    </dependency>

  </dependencies>
</project>

La commande "mvn package" le construit sans aucun problème, et je peux l'exécuter, mais lorsque l'application tente d'accéder à la base de données, cette erreur se présente:

Java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
        at Java.net.URLClassLoader$1.run(URLClassLoader.Java:217)
        at Java.security.AccessController.doPrivileged(Native Method)
        at Java.net.URLClassLoader.findClass(URLClassLoader.Java:205)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:321)
        at Sun.misc.Launcher$AppClassLoader.loadClass(Launcher.Java:294)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:266)
        at Java.lang.Class.forName0(Native Method)
        at Java.lang.Class.forName(Class.Java:186)
        at com.ion.common.Functions.databases(Functions.Java:107)
        at com.ion.common.App.main(App.Java:31)

La ligne sur laquelle il échoue est:

Class.forName("com.mysql.jdbc.Driver");

Quelqu'un peut-il me dire ce que je fais mal ou comment y remédier?

19
Matthew

Raghuram m'a donné un coup de pouce dans la bonne direction. La façon d'obtenir que maven s'occupe de copier automatiquement les bocaux est d'ajouter ce code à l'intérieur de la balise dans le fichier pom.xml:

  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>copy-dependencies</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.build.directory}</outputDirectory>
          <overWriteReleases>false</overWriteReleases>
          <overWriteSnapshots>true</overWriteSnapshots>
        </configuration>
      </execution>
    </executions>
  </plugin>

Plus de détails à ce sujet peuvent être trouvés ici: https://maven.Apache.org/plugins/maven-dependency-plugin/usage.html

Obtenir maven pour emballer les pots ensemble serait bien, mais cela suffit pour répondre à cette question. Réponses associées sur stackoverflow:

Construire un pot exécutable avec maven?

Comment puis-je créer un JAR exécutable avec des dépendances en utilisant Maven?

19
Matthew

Je sais que cette question est ancienne, mais elle apparaît en haut des recherches pour que Maven définisse correctement les dépendances avec les versions -SNAPSHOT et j'ai dû affiner la solution acceptée pour que ma résolution de chemin de classe fonctionne correctement.

Le problème que j'ai rencontré était que le plugin maven-jar incluait la version résolue d'une dépendance (par exemple -. Jar) tandis que le plugin maven-dépendance (à partir de la version 2.5.1) copie les dépendances en préservant leur version de base --SNAPSHOT. pot). (Voir https://jira.codehaus.org/browse/MDEP-38 pour plus d'informations sur cette amélioration.)

Pour que les choses fonctionnent, j'ai dû désactiver ce comportement comme suit:

    ...
    <plugins>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>dependency/</classpathPrefix>
                        <mainClass>com.example.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <useBaseVersion>false</useBaseVersion>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
    ...

Cette configuration a entraîné la copie des dépendances dans ${project.build.directory}/dependency avec leur resolvedVersion correspondant au blasspath défini dans le META-INF/MANIFEST.MF par le plugin maven-jar. J'espère que cela aidera quelqu'un à l'avenir.

13
Maelstrom

Maven définit correctement le chemin de classe sur les dépendances, mais sans préfixe avec l'emplacement du référentiel. Il ressemblera à ceci dans votre fichier Manifest.

Class-Path: mysql-connector-Java-5.1.14.jar

Il vous appartient de placer les pots dépendants dans le même dossier que le pot que vous exécutez.

Voir les exemples

2
Raghuram

Ou si vous utilisez maven-shade-plugin une solution consiste à ajouter un filtre pour inclure les fichiers manquants:

        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    ...
                    <configuration>
                        ...
                        <filters>
                            ...                                
                            <filter>
                                <artifact>com.Sun.istack</artifact>
                                <includes>
                                    <include>**</include>
                                </includes>
                            </filter>
0
kellogs