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

Eclipse Java Discussion :

[jar][classpath][eclipse 3.0] memento de class path trop long


Sujet :

Eclipse Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 15
    Points : 14
    Points
    14
    Par défaut [jar][classpath][eclipse 3.0] memento de class path trop long
    Bonjour, une question très pointue !

    je suis dessus depuis une semaine, j'ai retrourné le truc dans tous les sens , pas de résultat probant pour l'instant.
    accrochez vous c'est assez long

    but : je veux lancer une JVM en mode debug sous eclipse à parir d'un plugin

    comment ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ILaunchConfigurationType configType = getLaunchManager()
    				.getLaunchConfigurationType(
    	IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
     
     
    ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchManager().generateUniqueLaunchConfigurationNameFrom(			"com.fortis.lu.wsad.tools.mains.MainGeneration"));
    ensuite il suffit de setter les bon attribut à l'objet wc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH,false);
     
    wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH,fullClassPath);
    par exemple
    ensuite il faut lancer le launch

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ILaunchConfiguration config = wc.doSave();
    /*ILaunch iLaunch =*/ config.launch(mode, progressMonitor);
    cela fonctionne.

    mais
    le problème vient du fait que mon class path est trop long pour java.
    or le class path n'est pas une simple string dans notre cas, il s'agit d'une (List) de "memento"

    un memento est une String xml définissant, disons, le descriptif d'un projet (ses bin, ses jars, ses lib etc...) à partir de ce xml-meento il déduit le class path sous forme de string , et là , c'esgt le drame "class path too long"

    pour info, voici comment optenir la classe qui genere le memento : (méthode maison)
    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
     
    	/**
             * Get classPath associated to the selected resource project
             * @param project The resource project
             * @return ArrayList[IRuntimeClasspathEntry]
             * @throws CoreException
             */
    	private static ArrayList getIRuntimeClasspathEntry(IProject project) throws CoreException {
    		IJavaProject javaPrj = JavaCore.create(project);
    		ArrayList classpathMemento = new ArrayList();
    		IRuntimeClasspathEntry[] iRuntimeClassPathEntry = JavaRuntime.computeUnresolvedRuntimeClasspath(javaPrj);
    		for (int i = 0; i < iRuntimeClassPathEntry.length; i++) {
    			//For WSAD5.1 need, only launch file wich contain good
    			// classpath are launched ! (all resources in the classpath must
    			// exist)
    			//Check if archives present in classpath exist or not.
    			if (iRuntimeClassPathEntry[i].getType() == IRuntimeClasspathEntry.ARCHIVE) {
    				if (iRuntimeClassPathEntry[i].getResource() != null) {
    					classpathMemento.add(iRuntimeClassPathEntry[i]);
    				} else {
    					System.out.println(project.getName() + " : "
    							+ iRuntimeClassPathEntry[i]
    							+ " == NOT EXIST");
    				}
    			} else if (iRuntimeClassPathEntry[i].getType() == IRuntimeClasspathEntry.PROJECT) {
    				//Check if java projects present in classpath exist or not.
    				IProject p = (IProject) iRuntimeClassPathEntry[i].getResource();
    				//If it is, do not add it to classpath
    				//Test if the project is accesible.
    				//test if project is a java project nature.
    				if ( p != null && p.isAccessible() && PluginsUtils.isJavaNatureOnly(p) ) {
    					classpathMemento.add(iRuntimeClassPathEntry[i]);
    				}
    			} else {
    				//No project classpath entry
    				classpathMemento.add(iRuntimeClassPathEntry[i]);
    			}
    		}
    		return classpathMemento;
    	}
    c'est à ce niveau que je coince : comme réduire le class path puisque ce n'est pas moi qui le génère mais eclipse...

    mon idée :
    sachant que les jars ont dans leur manifest un class-path, j'ai essayé de faire un jar factice qui contient ce class path trop long, en le splitant sur plusieurs lignes comme trouvé sur le net... (par tranche de 68 chars)

    j'arrive bien à dire à ma jvm d'utiliser le jar, et donc de trouver le main à l'intérrieur de ce jar. par contre un class.forName() d'une classe située dans un jar définie dans le class path du manifest ne fonctionne pas .... comme si le class-path dudit jar n'était pas chargé

    je ne sais pas d'ou cela peut venir ?
    hypothèses :
    - le split en plusieurs ligne est incorrect : je n'y crois pas trop
    - je ne sais pas si le chemin est en absolu ou en relatif dans un class path de manifest (selon les sites, j'ai pluseiurs réponses)
    - comme le séparateur est " ", comment faire losrque le chemin en contient un ?
    - dans le cas d'une chemin absolu si je note c:\toto, il n'en veut pas. donc j'ai mis "c:\toto" entre guillement... est ce la bonne notation ?


    par ailleurs, il ne s'agit que d'une piste de travail, peut etre est ce ma manière d'appeller un launch Eclipse qui est moisie

    si quelqu'un à une idée, ou ne serais-ce qu'une piste, je suis preneur.
    merci d'avance.
    JR

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 15
    Points : 14
    Points
    14
    Par défaut désolé pour le spam
    je débute sur le forum, et je viens de me rendre compte qu'il existe une sous rubrique eclipse, qui est peut etre plus pertinente...

    ceci dit, la question du class path trop long est tout de meme présente endehors de la problématique des plugins eclipse

  3. #3
    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
    Points : 3 083
    Points
    3 083
    Par défaut
    Si je ne m'abuse il n'y a pas de limite à la longueur du classpath...
    Ton problème se situe ailleurs.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 15
    Points : 14
    Points
    14
    Par défaut vrai et faux : raccourci verbal abusif :
    Le message exact est "The input line is too long."
    Ce qui est une limitation de windows, j'en conviens.

    Par ailleurs dans un jar, il faut mettre un retour à la ligne à chaque 70è caractère, sinon lors de la "jarisation", on obtient cette exception :
    "java.io.IOException: line too long"

    Pour tester c'est simple il suffit de faire un projet qui tourne et ensuite de rajouter dans le class path tout un tas de lib inutiles... résultat garanti sous windows (autres environnement, je ne sais pas)

    -----
    A ce problème, sur le net, j'ai vu une proposition de mettre dans un jar le class path (puisqu'on peu le splitter par tranche de 68 chars).
    d'où mes intérogations....

    Je suppose que cela fonctionne dans certains cas, notamment un jar exécutable, mais mon cas est vraiment (n'ayons pas peur des mots) pourri, puisque je ne lance pas une application java : je lance un objet ILaunchConfiguration d'eclipse... (ceci dit, nonobstant ce détail, le problème reste le meme)

    si je fais cette stratégie, c'est à dire mettre une classe Main dans un jar, et un classpath dans le manifest de ce dernier, le class path du jar n'est pas intégré à mon ClassLoader : "java.lang.ClassNotFoundException:" sur un simple Class.ForName() dans le Main.

    JRF

  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
    Points : 3 083
    Points
    3 083
    Par défaut
    Tu ne peux pas simplement ajouter les jars nécessaires à ton classpath dans le point d'entrée de ton application ?

    Un truc dans le genre :

    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
    	/**
             * 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);
    			}
    		}
    	}
    Tu dois juste mettre la liste de jars nécessaires dans ton applic ou dans un fichier de conf.

    Ce n'est qu'une proposition.

    Sinon java6 :


  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 15
    Points : 14
    Points
    14
    Par défaut bien vu !
    c'est un peu cracra d'acceder comme un sauvage à une méthode protected... mais il faut ce qu'il faut

    ***

    pour la seconde option, évidement je ne peux pas, puisque ce n'est pas moi qui génère le class path : c'est éclipse !

    ******

    ici donc,
    je créer un wc temporaire avec tout le class path, je l'utilise pour créer mon fichier de config avec le class path en entier.

    puis je m'en débarasse pour un autre ne contenante que le memento d'un seul projet dont je maitrise la taille de class path.

    dans ce projet : je rajoute un MainDispatcher dont le but est de charger la config puis de lancer le véritable Main.

    je rajoute deux arguments à un MainDispatcher : un pour le Main-réel, un pour le fichier de config.
    1- je force le class path à partir du fichier de conf.
    2- ja lance le main par ClassforName() sur mon main réel !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	public static void main(String[] args) {
    		try {
    			String classpathFile = args[args.length-1];
    			addURLfromConfig(classpathFile);
     
    			String clazz = args[args.length-2];
    			Class.forName(clazz).getMethod("main",new Class[]{args.getClass()}).invoke(null,new Object[]{args});
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    peut etre existe il une méthode plus efficiente, mais celle ci me semble correcte... à tester en profondeur ...

    MERCIIIIIIIIIIIIIIIIIi.

    jrf
    (je ne resolve pas tout de suite, si jamais quelqu'un a une idée supplémentaire !)

  7. #7
    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
    Points : 3 083
    Points
    3 083
    Par défaut
    J'ai pas mieux en stock de toute façon
    Content que ça marche.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 9
    Dernier message: 28/01/2013, 10h42
  2. problème de classpath après export d'un jar avec Eclipse
    Par dmichel dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 19/03/2009, 19h25
  3. [JAR][Manifest] classpath trop long
    Par zolive dans le forum Général Java
    Réponses: 5
    Dernier message: 22/03/2007, 16h46
  4. [JAR]Class-Path dans le fichier Manifest
    Par Kleb dans le forum Général Java
    Réponses: 5
    Dernier message: 08/01/2005, 08h51
  5. [Jar][Classpath]Pb chargement resource classpath dans un jar
    Par Pill_S dans le forum Général Java
    Réponses: 20
    Dernier message: 01/10/2004, 20h12

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