IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Encore une question à propos des jar & du classpath


Sujet :

Java

  1. #1
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut Encore une question à propos des jar & du classpath
    Salut,

    Décidément en ce moment j'ai des problèmes avec les jars et le classpath.

    Quand on définit dans le manifest d'un .jar un attribut Main-Class et un attribut Class-Path, et qu'on appelle notre jar avec , tout est ok.

    Maintenant (suite à ce post), si on a besoin d'un nombre indéterminé (et dont on ne connait pas le nom) des librairies .jar, il faut les écrire en ligne de commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java -cp malibrairie1.jar:malibrairie2.jar ...
    Le problème, c'est que si on fait ça, on ne peut plus utiliser l'attribut Main-Class du manifest, sinon le classpath indiqué n'est pas pris en compte. Je m'explique:
    Imaginons un jar monjar.jar qui contient un attribut Main-Class qui vaut monpackage.MainClass.

    Soit on fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java -cp unclasspath -jar monjar.jar
    la classe main est bien utilisée, mais le classpath utilisé est celui inscrit dans le manifest du jar, dans l'attribut "Class-Path" (même si celui-ci n'est pas défini, auquel cas le class-path est vide).

    Soit on fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java -cp monjar.jar:unclasspath monpackage.MainClass
    auquel cas on est obligé d'ajouter notre jar (sensé être exécutable) au classpath et indiquer la classe main manuellement pour lancer le programme, ce qui est un peu lourd (je trouve)... et du coup le .jar n'est pas "exécutable"...

    Avez-vous une solution?

    Merci d'avance...

  2. #2
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Si j'ai bien compris le problème je vois 2 solutions.
    La première ce serait de te faire un lanceur qui génèrerait la ligne de commande.
    La deuxième serait de charger ton classpath dans le point d'entrée de ton application en lisant tous les fichiers jar de ton répertoire lib.

    Voici une classe que je m'étais faite pour ce besoin.

    Il faut lancer l'application avec le paramètre -Dloap.cp=tonRepertoireLib; puis faire une classe launcher comme point d'entrée qui aura un main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	public static void main(String[] args) {
    		ClassPathAppender.load();
    		MaVraiClasseDEntree.main(args);
    	}
    Et voici le code de ClassPathAppender :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    /**
     * Independant class that offer methods to load files in the classpath dynamicaly.
     * 
     * @author nathanael
     */
    public final class ClassPathAppender {
     
    	/** Parameters for {@link URLClassLoader#addUrl(URL)} method. */
    	private static final Class<?>[] PARAMETERS = new Class<?>[] { URL.class };
     
    	/**
             * Hidden Constructor
             */
    	private ClassPathAppender() { }
     
    	/**
             * Add the File corresponding to given <code>path</code> to the classpath.
             * 
             * @param path
             * @throws IOException
             */
    	public static void addFile(String path) throws IOException {
    		File file = new File(path);
    		addFile(file);
    	}
     
    	/**
             * Add the given <code>file</code> to the classpath.
             * 
             * @param file
             * @throws IOException
             */
    	public static void addFile(File file) throws IOException {
    		addURL(file.toURI().toURL());
    	}
     
    	/**
             * Add the given <code>url</code> to the classpath.
             * 
             * @param url
             * @throws IOException
             */
    	public static void addURL(URL url) throws IOException {
    		URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    		Class<URLClassLoader> sysclass = URLClassLoader.class;
    		Method method = null;
    		try {
    			method = sysclass.getDeclaredMethod("addURL", PARAMETERS);
    			method.setAccessible(true);
    			method.invoke(sysloader, new Object[] { url });
    		} catch (Throwable t) {
    			t . printStackTrace(); // Authorized
    			throw new IOException("Error, could not add URL to system classloader");
    		} finally {
    			if (method != null) {
    				method.setAccessible(false);
    			}
    		}
    	}
     
    	/**
             * Load the libraries from the -Dload.cp defined paths.
             */
    	public static void load() {
    		String loadCp = System.getProperty("load.cp");
    		if (loadCp == null || loadCp.length() == 0) {
    			return;
    		}
    		String[] paths = loadCp.split(System.getProperty("path.separator"));
    		for (String path : paths) {
    			String[] tmpLibs = ClassPathGenerator.getLibs(path);
    			for (String lib : tmpLibs) {
    				try {
    					addFile(path + System.getProperty("file.separator") + lib);
    				} catch (IOException e) {
    					e . printStackTrace(); // Authorized
    				}
    			}
    		}
    	}
     
    }

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2006
    Messages
    238
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 238
    Par défaut
    Salut,

    Je fais de la meme facon que natha, lorsque j'ai un nombre indeterminé de librairie, ben je les charge dynamiquement dans le classpath.

    a+

  4. #4
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Merci pour l'astuce, mais cette solution (bien qu'elle puisse être pratique) n'est pas très correcte (appel d'une méthode inaccessible par introspection)...

    En fait je vais utiliser ceci:
    - chaque plugin devra indiquer de quelles librairies il a besoin
    - mettre l'URLClassLoader de ces librairies dans le classloader du plugin...

    @+

  5. #5
    Membre Expert
    Avatar de natha
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 346
    Par défaut
    Citation Envoyé par ®om
    (appel d'une méthode inaccessible par introspection)...
    Ouaip je sais bien mais j'ai pas trouvé mieux dans le temps qui m'était imparti

    La solution de le y@m's dans l'autre post a l'air pas mal par contre.

Discussions similaires

  1. Réponses: 21
    Dernier message: 09/02/2008, 23h09
  2. Encore une question licence
    Par Neilos dans le forum C++Builder
    Réponses: 4
    Dernier message: 27/01/2005, 09h48
  3. Question à propos des niveaux de transaction
    Par davy.g dans le forum Oracle
    Réponses: 3
    Dernier message: 18/01/2005, 15h31
  4. Encore une question sur malloc
    Par IG88 dans le forum C
    Réponses: 5
    Dernier message: 23/06/2004, 15h35
  5. Une question à propos des thread
    Par tscoops dans le forum C++Builder
    Réponses: 4
    Dernier message: 07/11/2003, 14h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo