web-dev-qa-db-fra.com

Est-il possible de mélanger --class-path et --module-path en javac (JDK 9)?

Lorsque je compile un module qui dépend des autres modules que j'ai compilés précédemment, je dois spécifier le --module-path <directory> option. Cela rend les modules dont je dépend visibles.

Mais en même temps, je voudrais également rendre visibles certains fichiers Jar non modulaires. Cependant, si ne faites pas d'eux des modules automatiques et spécifiez simplement le --class-path some.jar juste à côté de --module-path <directory>, alors javac semble ignorer le claspath et lance des erreurs "package yyy not found" et autres erreurs "not found".

Je peux comprendre qu'en utilisant --class-path et --module-path en même temps (compilation) est illégal, mais javac ne m'avertit pas du tout.

21
malloc4k

Vous pouvez utiliser le chemin de classe et le chemin de module en parallèle, mais il y a quelques détails à considérer.

Chemin du module de dépendance ~> Chemin de classe

Les modules explicites (JAR avec un descripteur de module sur le chemin du module) ne peuvent pas lire le module sans nom (JAR sur le chemin de classe) - cela a été fait exprès pour empêcher les JAR modulaires de dépendre du "chaos du chemin de classe".

Puisqu'un module doit exiger toutes ses dépendances et celles-ci ne peuvent être satisfaites que par d'autres modules nommés (c'est-à-dire pas des JAR sur le chemin de classe), toutes les dépendances d'un JAR modulaire doivent être placées sur le chemin du module. Oui, même les JAR non modulaires, qui seront ensuite transformés en modules automatiques .

La chose intéressante est que les modules automatiques peuvent lire le module sans nom, donc leur les dépendances peuvent aller sur le chemin de classe.

Chemin de classe de dépendance ~> Chemin du module

Si vous compilez du code non modulaire ou lancez une application à partir d'un fichier JAR non modulaire, le système de modules est toujours en jeu et parce que le code non modulaire n'exprime aucune dépendance, il ne résoudra pas les modules à partir du chemin du module.

Donc, si le code non modulaire dépend d'artefacts sur le chemin du module, vous devez les ajouter manuellement avec le --add-modules option . Pas nécessairement tous, juste ceux dont vous dépendez directement (le système de modules tirera des dépendances transitives) - ou vous pouvez utiliser ALL-MODULE-PATH (vérifiez la publication liée, cela explique cela plus en détail).

29
Nicolai

Je crois qu'en utilisant le --classpath et --module-path options en même temps est pas illégal. Il est possible d'utiliser les deux en même temps que même si vous ne spécifiez pas explicitement un chemin de classe, il par défaut dans le répertoire courant.

Détails du javac -help message et documentation des outils javac -

--module-path <path>, -p <path>

Spécifiez où trouver les modules d'application

--class-path <path>, -classpath <path>, -cp <path>

Spécifiez où trouver les fichiers de classe utilisateur et les processeurs d'annotation

Si --class-path, -classpath, ou -cp ne sont pas spécifiés , alors le chemin de la classe utilisateur est le répertoire courant .


Modifier: Merci à @MouseEvent, j'avais probablement raté la partie de la question

Cependant, si vous n'en faites pas des modules automatiques et spécifiez simplement le --class-path some.jar juste à côté de --module-path, alors javac semble ignorer le claspath et lance "package yyy not found" et other "not found " les erreurs.

Si vous ne les rendez pas automatiques, il est traité comme un module sans nom du système de modules et -

Un module nommé ne peut pas, en fait, même déclarer une dépendance sur le module sans nom. Cette restriction est intentionnelle, car permettre aux modules nommés de dépendre du contenu arbitraire du chemin de classe rendrait impossible une configuration fiable.

De plus, le module sans nom exporte tous ses packages d'où le code dans un automatique les modules pourront accéder à tout type public chargé depuis le chemin de classe.

Mais un module automatique qui utilise des types du classpath ne doit pas exposer ces types aux modules explicites qui en dépendent, puisque les modules explicites ne peuvent pas déclarer de dépendances sur le module sans nom.

Si le code dans le module explicite com.foo.app fait référence à un type public dans com.foo.bar, par exemple, et la signature de ce type fait référence à un type dans l'un des fichiers JAR toujours sur le chemin de la classe, puis le code dans com.foo.app ne pourra pas accéder à ce type car com.foo.app ne peut pas dépendre du module sans nom.

Cela peut être résolu en traitant com.foo.app comme module automatique temporairement afin que son code puisse accéder aux types à partir du chemin de classe, jusqu'à ce que le fichier JAR correspondant sur le chemin de classe puisse être traité comme un module automatique ou converti en module explicite.

9
Naman