2 votes

Pourquoi le mécanisme d'extension Java ne vérifie-t-il pas le chemin d'accès à la classe pour un paquetage optionnel implémentant LocaleServiceProvider ?

J'ai créé un projet maven L et rédigé un Extension Java (c'est-à-dire un paquetage optionnel) la mise en œuvre (c'est-à-dire l'extension) des fournisseurs de services (abstraits) qui mettent en œuvre (c'est-à-dire étendent) LocaleServiceProvider pour soutenir un dialecte (appelons-le xy ) qui n'est normalement pas pris en charge par le JRE. (Je fais no je veux utiliser l'extension CLDR fournie avec Java 8, même si j'utilise la version 8.141).

Le projet se compile et produit un jar avec un META-INF/services qui contient les fichiers de configuration du fournisseur en UTF-8 avec les noms qualifiés des classes de fournisseurs sur une ligne qui se termine par un saut de ligne ( \n ).

J'ai ensuite déclaré une dépendance maven dans mon projet P sur le projet locale L et j'ai pensé que cela fonctionnerait, parce que le tutoriel États

T de chargement de classe. Lorsque l'environnement d'exécution doit charger une nouvelle classe pour une application, il recherche la classe dans les emplacements suivants, dans l'ordre dans l'ordre :

[...]

  1. Le chemin de la classe : les classes, y compris les classes dans les fichiers JAR, sur les chemins spécifiés par la propriété système java.class.path. Si un fichier JAR sur le chemin des classes possède un manifeste avec l'attribut Class-Path, les fichiers JAR spécifiés par l'attribut Class-Path seront pris en compte, les fichiers JAR spécifiés par l'attribut Class-Path seront également recherchés. Par défaut, la valeur de la propriété java.class.path est ., le répertoire courant. actuel. Vous pouvez modifier cette valeur en utilisant les options de ligne de commande -classpath ou -cp ou en définissant la variable d'environnement CLASSPATH. Les options de ligne de commande ont la priorité sur la variable d'environnement CLASSPATH de la variable d'environnement CLASSPATH

Maven place toutes les dépendances sur le classpath, je crois.

Pourtant, lorsque j'exécute mon test unitaire dans P (dans IntelliJ ; L se trouve sur le chemin d'accès), il échoue :

@Test
public void xyLocalePresent() {
    Locale xy = new Locale("xy");
    assertEquals("P not on classpath", xy, com.example.l.Locales.XY); // access constant in my Locale project L; should be equals to locale defined here
    SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, xy);
    assertEquals("dd/MM/yy", df.toPattern()); // fails; L specifies the short date pattern as dd/MM/yy
}

Je dois commencer par -Djava.locale.providers=SPI,JRE -Djava.ext.dirs=/path/to/project/L/target . Si je fais cela, cela fonctionne, ce qui indique que L ont été chargés avec succès (ce qui indique que l'application jar est correcte).

NB : la version Java 8 technotes dire que l'ordre SPI,JRE est la valeur par défaut.

Pourquoi, oh pourquoi cela ne fonctionne-t-il pas lorsque je mets simplement L sur le chemin d'accès (classpath) ? Pourquoi dois-je le pointer explicitement ?

Mise à jour : Après avoir relu la JavaDoc, je viens de voir ceci (c'est moi qui souligne) :

I le mécanisme d'extension Java en tant que installé des extensions.

Voilà qui explique les choses :(

Existe-t-il un moyen de faire fonctionner ce système ? en mettant simplement L sur le chemin d'accès (classpath) lorsque P Les courses, c'est à dire sans avoir à installer L (ou de devoir utiliser -D propriétés du système) ? ( P utilise maven, Struts2 et Spring, si cela peut aider...)

1voto

Andreas Points 3334

Dans les applications plus complexes, telles que les serveurs web (par exemple Tomcat), il existe plusieurs ClassLoaders, de sorte que chaque WebApp servie par le serveur web peut être maintenue indépendante.

Le mécanisme d'extension permet d'étendre la fonctionnalité Java de base, c'est-à-dire les fonctionnalités disponibles globalement dans la JVM en cours d'exécution (le serveur web). En tant que telles, elles doivent être chargées par le ClassLoader du système.

La manière standard d'ajouter une extension au code d'exécution Java est la suivante

  • ajouter le fichier Jar au fichier JRE_HOME/lib/ext dossier
  • ajouter des dossiers supplémentaires à rechercher en spécifiant l'option java.ext.dirs propriété du système

Vous pourriez également l'ajouter vous-même au chemin de classe de l'amorçage, mais cela pourrait poser des problèmes si le gestionnaire de sécurité est activé. Je ne suis pas sûr de cela. Il est donc préférable de procéder de la manière officielle.

Notez que le chemin d'accès défini par l'option CLASSPATH ou la variable d'environnement -cp ne définit pas le chemin d'accès à la classe Bootstrap.

Pour en savoir plus, consultez la documentation Java " Comment les classes sont-elles trouvées ? ".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X