web-dev-qa-db-fra.com

Classpath incluant JAR dans un JAR

Est-il possible de spécifier un Java classpath qui comprend un fichier JAR contenu dans un autre fichier JAR?)

127
Paul Reiners

Si vous essayez de créer un seul fichier JAR contenant votre application et ses bibliothèques requises, il existe deux façons (à ma connaissance) de le faire. Le premier est One-Jar , qui utilise un chargeur de classe spécial pour permettre l’imbrication des fichiers jar. La seconde est berJar , (ou Shade ), qui explose les bibliothèques incluses et place toutes les classes dans le fichier jar de niveau supérieur.

Je devrais également mentionner que UberJar et Shade sont des plugins pour Maven1 et Maven2 respectivement. Comme mentionné ci-dessous, vous pouvez également utiliser le plug-in Assembly (qui est en réalité beaucoup plus puissant, mais beaucoup plus difficile à configurer correctement).

91
Steve Moyer

Vous ne voulez PAS utiliser ces solutions "exploser le contenu du fichier JAR". Ils rendent vraiment plus difficile de voir des choses (puisque tout explose au même niveau). De plus, il pourrait y avoir des conflits de noms (cela ne devrait pas arriver si les gens utilisent les bons packages, mais vous ne pouvez pas toujours contrôler cela).

La fonctionnalité que vous souhaitez utiliser est l’une des top 25 des RFE du soleil : RFE 4648386 , que Sun, dans sa sagesse infinie, a désignée comme étant de faible priorité. Nous ne pouvons qu'espérer que Sun se réveille ...

Entre-temps, la meilleure solution que j'ai trouvée (et que j'aimerais que Sun copie dans le JDK) consiste à utiliser le chargeur de classes personnalisé JarClassLoader .

50
Bruce Willis

Après quelques recherches, j'ai trouvé une méthode qui ne nécessite pas Maven ni aucune extension/programme tiers.

Vous pouvez utiliser "Class-Path" dans votre fichier manifeste.

Par exemple:

Créer le fichier manifeste MANIFEST.MF

Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass

Compilez tous vos cours et lancez jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

c signifie créer une archive f indique que vous voulez spécifier le fichier v est pour une entrée commentée m signifie que nous allons passer un fichier manifeste personnalisé

Assurez-vous que vous avez inclus lib dans le package jar. Vous devriez pouvoir exécuter jar de la manière habituelle.

basé sur: http://www.ibm.com/developerworks/library/j-5things6/

trouvez-vous toutes les autres informations dont vous avez besoin sur le chemin de classes ici

29
Tezar

Utilisez la balise zipgroupfileset (utilise les mêmes attributs que la balise fileset ); il décompressera tous les fichiers du répertoire et les ajoutera à votre nouveau fichier d’archive. Plus d'informations: http://ant.Apache.org/manual/Tasks/Zip.html

C’est un moyen très utile de résoudre le problème de pot dans un pot - je le sais parce que j’ai cherché dans Google cette question de StackOverflow tout en essayant de comprendre ce qu’il faut faire. Si vous voulez empaqueter un fichier jar ou un dossier de fichiers jar dans votre fichier jar construit avec Ant, oubliez tous ces trucs de classpath ou de plug-in tiers, tout ce que vous devez faire est ceci (dans Ant):

<jar destfile="your.jar" basedir="Java/dir">
  ...
  <zipgroupfileset dir="dir/of/jars" />
</jar>
22
ecbrodie

Si vous construisez avec ant (j'utilise ant chez Eclipse), vous pouvez simplement ajouter les fichiers jar supplémentaires en disant à ant de les ajouter ... Ce n'est pas nécessairement la meilleure méthode si vous avez un projet géré par plusieurs personnes, mais cela fonctionne. pour un projet de personne et est facile.

par exemple, ma cible qui construisait le fichier .jar était:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

Je viens d'ajouter une ligne pour le faire:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

<property name="external-lib-dir" 
          value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

était le dir avec les pots externes. Et c'est tout...

8
ntg

Non sans écrire votre propre chargeur de classe. Vous pouvez ajouter des fichiers jar au chemin de classe du fichier, mais ils doivent être co-localisés et ne pas être contenus dans le fichier jar principal.

6
Joe Skora

Pour ce faire, vous devez créer un chargeur de classe personnalisé ou une bibliothèque tierce qui le prend en charge. Votre meilleur pari est d'extraire le fichier jar du runtime et de l'ajouter au chemin de classe (ou de le faire déjà ajouter au chemin de classe).

2
James Schek

Si vous avez eclpise IDE, il vous suffit d’exporter votre fichier JAR et de choisir "Bibliothèques de packages requis dans le fichier JAR généré". Eclipse ajoutera automatiquement les fichiers JAR dépendants requis dans le fichier JAR généré, ainsi que du chargeur de classes personnalisé Eclipse qui chargera ces fichiers JAR automatiquement.

2
amralieg

J'utilise maven pour mon Java construit qui a un plugin appelé le plugin maven Assembly .

Il fait ce que vous demandez, mais comme certaines des autres suggestions le décrivent - exploser essentiellement tous les pots dépendants et les recombiner en un seul pot

2
Vinnie

Eh bien, il existe un moyen très simple d'utiliser Eclipse.

Exportez votre projet en tant que fichier Jar "exécutable" (cliquez avec le bouton droit de la souris sur le dossier du projet dans Eclipse, sélectionnez "Exporter ..."). Lorsque vous configurez les paramètres d'exportation, assurez-vous de sélectionner "Extraire les bibliothèques requises dans le fichier Jar généré". Gardez à l'esprit, sélectionnez "Extraire ..." et non "Paquetage de bibliothèques requises ...".

De plus: Vous devez sélectionner une configuration d'exécution dans vos paramètres d'exportation. Vous pouvez donc toujours créer une main () vide dans une classe et l'utiliser pour votre configuration d'exécution.

Quoi qu'il en soit, il n'est pas garanti de fonctionner à 100% du temps - vous remarquerez un message contextuel vous invitant à vérifier que vous vérifiez bien licences des fichiers Jar que vous incluez et quelque chose à propos de ne pas copier les fichiers de signature. Cependant, je le fais depuis années et je n’ai jamais rencontré de problème.

1
CM_2014

J'étais sur le point de conseiller d'extraire tous les fichiers du même niveau, puis de créer un fichier jar à partir du résultat, car le système de paquets devrait les garder soigneusement séparés. Ce serait la manière manuelle, je suppose que les outils indiqués par Steve le feront bien.

1
PhiLho

Winstone est plutôt bon http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ . Mais pas pour les sites complexes. Et c'est dommage car il suffit d'inclure le plugin.

1
Jan Goyvaerts