2017-09-18 4 views
9

Lorsque je compile un module qui dépend des autres modules que j'ai compilés précédemment, je dois spécifier l'option --module-path <directory>. Cela rend les modules dont je dépend visible.Est-il possible de mélanger --class-path et --module-path dans javac (JDK 9)?

Mais en même temps je voudrais aussi rendre certains fichiers Jar non modulaires visibles. Cependant, si vous ne faites pas les modules automatiques et juste spécifier le --class-path some.jar juste à côté de --module-path <directory>, puis javac semble ignorer le claspath et jette "paquet yyy non trouvé" et d'autres erreurs "non trouvées".

Je peux comprendre que l'utilisation en même --class-path et --module-path (compilation) le temps est illégal, mais javac ne me mettent en garde contre pas en aucune façon.

+0

Il est possible de mélanger les deux, pouvez-vous partager un exemple minimal que nous pouvons vérifier? –

+0

* Je peux comprendre que l'utilisation de --class-path et --module-path au même moment (compilation) est illégale, * pourquoi est-ce le cas? – nullpointer

+5

Le mélange est absolument légal.Cependant, les fichiers JAR modulaires ne peuvent pas référencer les fichiers JAR non modulaires sur le chemin de classe. Les modules automatiques (jar non modulaires sur le chemin du module) agissent comme un pont: les jars modulaires _can_ les référencent, et les modules automatiques peuvent lire le classpath. –

Répondre

14

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

dépendances Chemin du module ~> Chemin de classe

modules explicites (JARs avec un descripteur de module sur le chemin du module) ne peut pas lire le module sans nom (JARs sur le chemin de classe) - qui a été fait exprès pour empêcher modulaire Les JAR dépendent du "chaos du chemin de la classe". Comme un module doit exiger toutes ses dépendances et que celles-ci ne peuvent être remplies que par d'autres modules nommés (pas 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 automatic modules.

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

classe de dépendance chemin ~> Chemin du module

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

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

+5

Nicolai - votre réponse est correcte mais je pense pourrait être développée pour souligner que l'option '--add-modules' peut être nécessaire pour s'assurer que les modules nécessaires par le code de chemin de classe sont résolus. La question initiale demande pourquoi javac échoue et je suppose que c'est parce qu'il compile du code sur le chemin de la classe avec des références aux classes dans les modules sur le chemin du module et a juste besoin de '--add-modules' pour s'assurer que les modules sont résolus . –

+0

Je pense que OP essaie de compiler du code modulaire avec une dépendance non-modulaire - de toute façon, j'ai ajouté l'autre direction aussi, juste pour être sûr. – Nicolai

9

Je crois à l'aide des --classpath et --module-path options en même temps est pas illégal. Il est possible d'utiliser les deux en même temps, même si vous ne spécifiez pas explicitement un chemin de classe, affiche par défaut dans le répertoire en cours.

Détails dans le message javac -help et javac tools docs -

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

Indiquez où trouver des modules d'application

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

Indiquez où trouver les fichiers de classes d'utilisateurs et processeurs d'annotation

Si --class-path, -classpath ou -cpne sont pas spécifiés, puis l'utilisateur le chemin de classe est le répertoire actuel.


Modifier: Merci à @MouseEvent, je serais probablement manqué la partie dans la question

Cependant, si ne les font pas de modules automatiques et simplement spécifier le --class-path un.jar juste à côté de --module-path, alors javac semble ignorer le claspath et lance "package yyy not found" et d'autres erreurs "not found".

Si vous ne les faites pas automatique, il est traité comme un Module System's unnamed module et -

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

De plus, les exportations du module sans nom tous ses paquets d'où le code dans un modules automatiques seront en mesure d'accéder à tout type du public chargé de la classpath.

Mais un module automatique qui utilise des types du chemin de classe 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 publique dans com.foo.bar, par exemple, et la signature de ce type fait référence à un type dans l'un des fichiers JAR encore sur le chemin de la classe, puis le code dans com.foo.app ne pourra pas accéder à ce type puisque com.foo.app ne peut pas dépendre du module sans nom.

Cela peut être résolu en traitant com.foo.app comme un module automatique temporaire de sorte que son code peut accéder à des types de chemin de classe, jusqu'à ce que le fichier JAR concerné sur le chemin de la classe peut être considérée comme un module automatique ou converti en un module explicite.

+1

Laissé seul si c'est légal ... Le concept entier du module sans nom est pour les jars dans le classpath, et que les modules explicites ne peuvent pas y accéder. – Mordechai

+0

@MouseEvent Eh bien, c'est vrai. Je crois que j'ai raté cette partie de la question auparavant et juste répondu au titre. Edité pour inclure cela aussi. Merci :) – nullpointer