Compile Module that Depends on an External Jar











up vote
4
down vote

favorite
1












I worked through a simple example using Project Jigsaw in Java 11.0.1, built using the oracle JDK 11 on Ubuntu 18.04.



Following that example, I have created a simple project which compiles to a module, packages the module into a jar, and then uses jlink to create a standalone distribution. Everything works -- the end result is a smallish folder with a stripped down JRE and my module.



The project is made of only three files and some folders:



.:
build.sh src

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


src/com/greetings/Main.java



package com.greetings;

public class Main {
public static void main(String args) {
System.out.println("Greetings!");
}
}


src/module-info.java



module com.greetings { }


build.sh



#/bin/bash

#clean up from last build
rm -rf greetingsapp mlib mods

#compile
javac -d mods/com.greetings src/module-info.java src/com/greetings/Main.java

#Make module jar
mkdir mlib
jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .

#build distribution
jlink --module-path /usr/lib/jvm/java-11-oracle/jmods/:mlib --add-modules com.greetings --output greetingsapp --strip-debug --no-header-files --no-man-pages --launcher greetings=com.greetings

#run
greetingsapp/bin/greetings




All of that works. Now here's the problem:



The next thing I want to do is use an external library, so I added a few lines to Main.java:



Main.java - Updated



package com.greetings;

import org.apache.commons.cli.CommandLine; //new line

public class Main {

CommandLine line; //new line

public static void main(String args) {
System.out.println("Greetings!");
}
}


I then placed commons-cli-1.4.jar in a new directory named lib.



Which created this file structure:



.:
build.sh lib src

./lib:
commons-cli-1.4.jar

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


I modified the compile line to include the commons jar in the classpath:



javac -cp lib/commons-cli-1.4.jar:. 
-d mods/com.greetings
src/module-info.java src/com/greetings/Main.java


However, when I try to compile it, I get this error:



src/com/greetings/Main.java:10: error: package org.apache.commons.cli is not visible
import org.apache.commons.cli.CommandLine;
^
(package org.apache.commons.cli is declared in the unnamed module, but module org.apache.commons.cli does not read it)
1 error


How do I modify my project so I can compile against commons-cli-1.4.jar?





Edit, at the suggestion of the user nullpointer, I tried changing the -cp flag to just a -p flag, so the external jar is added to the module path instead. Unfortunately, that also doesn't work. Here are the various javac command I tried that also do not work:



javac -p lib -d mods/com.greetings 
src/module-info.java src/com/greetings/Main.java

javac --module-path=lib -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java

javac -p lib/commons-cli-1.4.jar -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java









share|improve this question




















  • 1




    It should ideally not remain in the unnamed module if you've specified the jar to be on the modulepath and removed it from the classpath. Could you update the question with your new javac command line.
    – nullpointer
    Nov 11 at 5:32






  • 1




    make sure your module declaration now requires the module ... Giving it a try, noticed that the module name for the commons-cli:commons-cli:1.4 would need requires commons.cli;, can you check with this?
    – nullpointer
    Nov 11 at 5:46








  • 1




    Are you doing this for learning purposes or to get something done? For work to actually use, adopt Maven or Gradle?
    – chrylis
    Nov 11 at 5:56






  • 2




    Chrylis: learning for now. Next step is to convert a large existing project and I'm getting myself familiar with the building blocks right now. Every time I run into an issue there, I distill it down into this test environment, understand it, and then go apply it to the large project. That project currently uses Ant, but I'm probably transitioning to Gradle.
    – JoshuaD
    Nov 11 at 6:12






  • 2




    @JoshuaD The final step of using jlink with automatic modules is what I am afraid is something I haven't seen people working a way until now. Apart from that, the rest of it should just be working fine. I gave your setup a try and could work with it and hence made an answer.
    – nullpointer
    Nov 11 at 6:37

















up vote
4
down vote

favorite
1












I worked through a simple example using Project Jigsaw in Java 11.0.1, built using the oracle JDK 11 on Ubuntu 18.04.



Following that example, I have created a simple project which compiles to a module, packages the module into a jar, and then uses jlink to create a standalone distribution. Everything works -- the end result is a smallish folder with a stripped down JRE and my module.



The project is made of only three files and some folders:



.:
build.sh src

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


src/com/greetings/Main.java



package com.greetings;

public class Main {
public static void main(String args) {
System.out.println("Greetings!");
}
}


src/module-info.java



module com.greetings { }


build.sh



#/bin/bash

#clean up from last build
rm -rf greetingsapp mlib mods

#compile
javac -d mods/com.greetings src/module-info.java src/com/greetings/Main.java

#Make module jar
mkdir mlib
jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .

#build distribution
jlink --module-path /usr/lib/jvm/java-11-oracle/jmods/:mlib --add-modules com.greetings --output greetingsapp --strip-debug --no-header-files --no-man-pages --launcher greetings=com.greetings

#run
greetingsapp/bin/greetings




All of that works. Now here's the problem:



The next thing I want to do is use an external library, so I added a few lines to Main.java:



Main.java - Updated



package com.greetings;

import org.apache.commons.cli.CommandLine; //new line

public class Main {

CommandLine line; //new line

public static void main(String args) {
System.out.println("Greetings!");
}
}


I then placed commons-cli-1.4.jar in a new directory named lib.



Which created this file structure:



.:
build.sh lib src

./lib:
commons-cli-1.4.jar

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


I modified the compile line to include the commons jar in the classpath:



javac -cp lib/commons-cli-1.4.jar:. 
-d mods/com.greetings
src/module-info.java src/com/greetings/Main.java


However, when I try to compile it, I get this error:



src/com/greetings/Main.java:10: error: package org.apache.commons.cli is not visible
import org.apache.commons.cli.CommandLine;
^
(package org.apache.commons.cli is declared in the unnamed module, but module org.apache.commons.cli does not read it)
1 error


How do I modify my project so I can compile against commons-cli-1.4.jar?





Edit, at the suggestion of the user nullpointer, I tried changing the -cp flag to just a -p flag, so the external jar is added to the module path instead. Unfortunately, that also doesn't work. Here are the various javac command I tried that also do not work:



javac -p lib -d mods/com.greetings 
src/module-info.java src/com/greetings/Main.java

javac --module-path=lib -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java

javac -p lib/commons-cli-1.4.jar -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java









share|improve this question




















  • 1




    It should ideally not remain in the unnamed module if you've specified the jar to be on the modulepath and removed it from the classpath. Could you update the question with your new javac command line.
    – nullpointer
    Nov 11 at 5:32






  • 1




    make sure your module declaration now requires the module ... Giving it a try, noticed that the module name for the commons-cli:commons-cli:1.4 would need requires commons.cli;, can you check with this?
    – nullpointer
    Nov 11 at 5:46








  • 1




    Are you doing this for learning purposes or to get something done? For work to actually use, adopt Maven or Gradle?
    – chrylis
    Nov 11 at 5:56






  • 2




    Chrylis: learning for now. Next step is to convert a large existing project and I'm getting myself familiar with the building blocks right now. Every time I run into an issue there, I distill it down into this test environment, understand it, and then go apply it to the large project. That project currently uses Ant, but I'm probably transitioning to Gradle.
    – JoshuaD
    Nov 11 at 6:12






  • 2




    @JoshuaD The final step of using jlink with automatic modules is what I am afraid is something I haven't seen people working a way until now. Apart from that, the rest of it should just be working fine. I gave your setup a try and could work with it and hence made an answer.
    – nullpointer
    Nov 11 at 6:37















up vote
4
down vote

favorite
1









up vote
4
down vote

favorite
1






1





I worked through a simple example using Project Jigsaw in Java 11.0.1, built using the oracle JDK 11 on Ubuntu 18.04.



Following that example, I have created a simple project which compiles to a module, packages the module into a jar, and then uses jlink to create a standalone distribution. Everything works -- the end result is a smallish folder with a stripped down JRE and my module.



The project is made of only three files and some folders:



.:
build.sh src

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


src/com/greetings/Main.java



package com.greetings;

public class Main {
public static void main(String args) {
System.out.println("Greetings!");
}
}


src/module-info.java



module com.greetings { }


build.sh



#/bin/bash

#clean up from last build
rm -rf greetingsapp mlib mods

#compile
javac -d mods/com.greetings src/module-info.java src/com/greetings/Main.java

#Make module jar
mkdir mlib
jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .

#build distribution
jlink --module-path /usr/lib/jvm/java-11-oracle/jmods/:mlib --add-modules com.greetings --output greetingsapp --strip-debug --no-header-files --no-man-pages --launcher greetings=com.greetings

#run
greetingsapp/bin/greetings




All of that works. Now here's the problem:



The next thing I want to do is use an external library, so I added a few lines to Main.java:



Main.java - Updated



package com.greetings;

import org.apache.commons.cli.CommandLine; //new line

public class Main {

CommandLine line; //new line

public static void main(String args) {
System.out.println("Greetings!");
}
}


I then placed commons-cli-1.4.jar in a new directory named lib.



Which created this file structure:



.:
build.sh lib src

./lib:
commons-cli-1.4.jar

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


I modified the compile line to include the commons jar in the classpath:



javac -cp lib/commons-cli-1.4.jar:. 
-d mods/com.greetings
src/module-info.java src/com/greetings/Main.java


However, when I try to compile it, I get this error:



src/com/greetings/Main.java:10: error: package org.apache.commons.cli is not visible
import org.apache.commons.cli.CommandLine;
^
(package org.apache.commons.cli is declared in the unnamed module, but module org.apache.commons.cli does not read it)
1 error


How do I modify my project so I can compile against commons-cli-1.4.jar?





Edit, at the suggestion of the user nullpointer, I tried changing the -cp flag to just a -p flag, so the external jar is added to the module path instead. Unfortunately, that also doesn't work. Here are the various javac command I tried that also do not work:



javac -p lib -d mods/com.greetings 
src/module-info.java src/com/greetings/Main.java

javac --module-path=lib -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java

javac -p lib/commons-cli-1.4.jar -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java









share|improve this question















I worked through a simple example using Project Jigsaw in Java 11.0.1, built using the oracle JDK 11 on Ubuntu 18.04.



Following that example, I have created a simple project which compiles to a module, packages the module into a jar, and then uses jlink to create a standalone distribution. Everything works -- the end result is a smallish folder with a stripped down JRE and my module.



The project is made of only three files and some folders:



.:
build.sh src

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


src/com/greetings/Main.java



package com.greetings;

public class Main {
public static void main(String args) {
System.out.println("Greetings!");
}
}


src/module-info.java



module com.greetings { }


build.sh



#/bin/bash

#clean up from last build
rm -rf greetingsapp mlib mods

#compile
javac -d mods/com.greetings src/module-info.java src/com/greetings/Main.java

#Make module jar
mkdir mlib
jar --create --file=mlib/com.greetings.jar --main-class=com.greetings.Main -C mods/com.greetings .

#build distribution
jlink --module-path /usr/lib/jvm/java-11-oracle/jmods/:mlib --add-modules com.greetings --output greetingsapp --strip-debug --no-header-files --no-man-pages --launcher greetings=com.greetings

#run
greetingsapp/bin/greetings




All of that works. Now here's the problem:



The next thing I want to do is use an external library, so I added a few lines to Main.java:



Main.java - Updated



package com.greetings;

import org.apache.commons.cli.CommandLine; //new line

public class Main {

CommandLine line; //new line

public static void main(String args) {
System.out.println("Greetings!");
}
}


I then placed commons-cli-1.4.jar in a new directory named lib.



Which created this file structure:



.:
build.sh lib src

./lib:
commons-cli-1.4.jar

./src:
com module-info.java

./src/com:
greetings

./src/com/greetings:
Main.java


I modified the compile line to include the commons jar in the classpath:



javac -cp lib/commons-cli-1.4.jar:. 
-d mods/com.greetings
src/module-info.java src/com/greetings/Main.java


However, when I try to compile it, I get this error:



src/com/greetings/Main.java:10: error: package org.apache.commons.cli is not visible
import org.apache.commons.cli.CommandLine;
^
(package org.apache.commons.cli is declared in the unnamed module, but module org.apache.commons.cli does not read it)
1 error


How do I modify my project so I can compile against commons-cli-1.4.jar?





Edit, at the suggestion of the user nullpointer, I tried changing the -cp flag to just a -p flag, so the external jar is added to the module path instead. Unfortunately, that also doesn't work. Here are the various javac command I tried that also do not work:



javac -p lib -d mods/com.greetings 
src/module-info.java src/com/greetings/Main.java

javac --module-path=lib -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java

javac -p lib/commons-cli-1.4.jar -d mods/com.greetings
src/module-info.java src/com/greetings/Main.java






java javac java-module java-11 jlink






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 11:14









nullpointer

35.7k1071141




35.7k1071141










asked Nov 11 at 5:22









JoshuaD

1,08731735




1,08731735








  • 1




    It should ideally not remain in the unnamed module if you've specified the jar to be on the modulepath and removed it from the classpath. Could you update the question with your new javac command line.
    – nullpointer
    Nov 11 at 5:32






  • 1




    make sure your module declaration now requires the module ... Giving it a try, noticed that the module name for the commons-cli:commons-cli:1.4 would need requires commons.cli;, can you check with this?
    – nullpointer
    Nov 11 at 5:46








  • 1




    Are you doing this for learning purposes or to get something done? For work to actually use, adopt Maven or Gradle?
    – chrylis
    Nov 11 at 5:56






  • 2




    Chrylis: learning for now. Next step is to convert a large existing project and I'm getting myself familiar with the building blocks right now. Every time I run into an issue there, I distill it down into this test environment, understand it, and then go apply it to the large project. That project currently uses Ant, but I'm probably transitioning to Gradle.
    – JoshuaD
    Nov 11 at 6:12






  • 2




    @JoshuaD The final step of using jlink with automatic modules is what I am afraid is something I haven't seen people working a way until now. Apart from that, the rest of it should just be working fine. I gave your setup a try and could work with it and hence made an answer.
    – nullpointer
    Nov 11 at 6:37
















  • 1




    It should ideally not remain in the unnamed module if you've specified the jar to be on the modulepath and removed it from the classpath. Could you update the question with your new javac command line.
    – nullpointer
    Nov 11 at 5:32






  • 1




    make sure your module declaration now requires the module ... Giving it a try, noticed that the module name for the commons-cli:commons-cli:1.4 would need requires commons.cli;, can you check with this?
    – nullpointer
    Nov 11 at 5:46








  • 1




    Are you doing this for learning purposes or to get something done? For work to actually use, adopt Maven or Gradle?
    – chrylis
    Nov 11 at 5:56






  • 2




    Chrylis: learning for now. Next step is to convert a large existing project and I'm getting myself familiar with the building blocks right now. Every time I run into an issue there, I distill it down into this test environment, understand it, and then go apply it to the large project. That project currently uses Ant, but I'm probably transitioning to Gradle.
    – JoshuaD
    Nov 11 at 6:12






  • 2




    @JoshuaD The final step of using jlink with automatic modules is what I am afraid is something I haven't seen people working a way until now. Apart from that, the rest of it should just be working fine. I gave your setup a try and could work with it and hence made an answer.
    – nullpointer
    Nov 11 at 6:37










1




1




It should ideally not remain in the unnamed module if you've specified the jar to be on the modulepath and removed it from the classpath. Could you update the question with your new javac command line.
– nullpointer
Nov 11 at 5:32




It should ideally not remain in the unnamed module if you've specified the jar to be on the modulepath and removed it from the classpath. Could you update the question with your new javac command line.
– nullpointer
Nov 11 at 5:32




1




1




make sure your module declaration now requires the module ... Giving it a try, noticed that the module name for the commons-cli:commons-cli:1.4 would need requires commons.cli;, can you check with this?
– nullpointer
Nov 11 at 5:46






make sure your module declaration now requires the module ... Giving it a try, noticed that the module name for the commons-cli:commons-cli:1.4 would need requires commons.cli;, can you check with this?
– nullpointer
Nov 11 at 5:46






1




1




Are you doing this for learning purposes or to get something done? For work to actually use, adopt Maven or Gradle?
– chrylis
Nov 11 at 5:56




Are you doing this for learning purposes or to get something done? For work to actually use, adopt Maven or Gradle?
– chrylis
Nov 11 at 5:56




2




2




Chrylis: learning for now. Next step is to convert a large existing project and I'm getting myself familiar with the building blocks right now. Every time I run into an issue there, I distill it down into this test environment, understand it, and then go apply it to the large project. That project currently uses Ant, but I'm probably transitioning to Gradle.
– JoshuaD
Nov 11 at 6:12




Chrylis: learning for now. Next step is to convert a large existing project and I'm getting myself familiar with the building blocks right now. Every time I run into an issue there, I distill it down into this test environment, understand it, and then go apply it to the large project. That project currently uses Ant, but I'm probably transitioning to Gradle.
– JoshuaD
Nov 11 at 6:12




2




2




@JoshuaD The final step of using jlink with automatic modules is what I am afraid is something I haven't seen people working a way until now. Apart from that, the rest of it should just be working fine. I gave your setup a try and could work with it and hence made an answer.
– nullpointer
Nov 11 at 6:37






@JoshuaD The final step of using jlink with automatic modules is what I am afraid is something I haven't seen people working a way until now. Apart from that, the rest of it should just be working fine. I gave your setup a try and could work with it and hence made an answer.
– nullpointer
Nov 11 at 6:37














1 Answer
1






active

oldest

votes

















up vote
3
down vote



accepted










You've placed the jar on the classpath because of which it results into an unnamed module..




The unnamed module exports all of its packages. ...



It does not, however, mean that code in a named module can access types in the unnamed module. ...



This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make
reliable configuration impossible.




Instead try placing the same jar on the modulepath from where it can be inferred as an automatic module.





You would also need to ensure that the module declaration of your module is updated accordingly to define a dependence on the newly added module to access its exported packages.



module com.greetings { 
requires commons.cli;
}




Edit: Trying out the complete build.sh in your case would still fail, but at the linking step, because of the presence of an automatic module.






share|improve this answer























  • 1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
    – JoshuaD
    Nov 11 at 6:52










  • 1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
    – nullpointer
    Nov 11 at 6:58












  • So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
    – JoshuaD
    Nov 11 at 7:20






  • 1




    I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
    – JoshuaD
    Nov 11 at 8:39











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246066%2fcompile-module-that-depends-on-an-external-jar%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote



accepted










You've placed the jar on the classpath because of which it results into an unnamed module..




The unnamed module exports all of its packages. ...



It does not, however, mean that code in a named module can access types in the unnamed module. ...



This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make
reliable configuration impossible.




Instead try placing the same jar on the modulepath from where it can be inferred as an automatic module.





You would also need to ensure that the module declaration of your module is updated accordingly to define a dependence on the newly added module to access its exported packages.



module com.greetings { 
requires commons.cli;
}




Edit: Trying out the complete build.sh in your case would still fail, but at the linking step, because of the presence of an automatic module.






share|improve this answer























  • 1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
    – JoshuaD
    Nov 11 at 6:52










  • 1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
    – nullpointer
    Nov 11 at 6:58












  • So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
    – JoshuaD
    Nov 11 at 7:20






  • 1




    I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
    – JoshuaD
    Nov 11 at 8:39















up vote
3
down vote



accepted










You've placed the jar on the classpath because of which it results into an unnamed module..




The unnamed module exports all of its packages. ...



It does not, however, mean that code in a named module can access types in the unnamed module. ...



This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make
reliable configuration impossible.




Instead try placing the same jar on the modulepath from where it can be inferred as an automatic module.





You would also need to ensure that the module declaration of your module is updated accordingly to define a dependence on the newly added module to access its exported packages.



module com.greetings { 
requires commons.cli;
}




Edit: Trying out the complete build.sh in your case would still fail, but at the linking step, because of the presence of an automatic module.






share|improve this answer























  • 1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
    – JoshuaD
    Nov 11 at 6:52










  • 1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
    – nullpointer
    Nov 11 at 6:58












  • So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
    – JoshuaD
    Nov 11 at 7:20






  • 1




    I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
    – JoshuaD
    Nov 11 at 8:39













up vote
3
down vote



accepted







up vote
3
down vote



accepted






You've placed the jar on the classpath because of which it results into an unnamed module..




The unnamed module exports all of its packages. ...



It does not, however, mean that code in a named module can access types in the unnamed module. ...



This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make
reliable configuration impossible.




Instead try placing the same jar on the modulepath from where it can be inferred as an automatic module.





You would also need to ensure that the module declaration of your module is updated accordingly to define a dependence on the newly added module to access its exported packages.



module com.greetings { 
requires commons.cli;
}




Edit: Trying out the complete build.sh in your case would still fail, but at the linking step, because of the presence of an automatic module.






share|improve this answer














You've placed the jar on the classpath because of which it results into an unnamed module..




The unnamed module exports all of its packages. ...



It does not, however, mean that code in a named module can access types in the unnamed module. ...



This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make
reliable configuration impossible.




Instead try placing the same jar on the modulepath from where it can be inferred as an automatic module.





You would also need to ensure that the module declaration of your module is updated accordingly to define a dependence on the newly added module to access its exported packages.



module com.greetings { 
requires commons.cli;
}




Edit: Trying out the complete build.sh in your case would still fail, but at the linking step, because of the presence of an automatic module.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 at 6:28

























answered Nov 11 at 5:49









nullpointer

35.7k1071141




35.7k1071141












  • 1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
    – JoshuaD
    Nov 11 at 6:52










  • 1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
    – nullpointer
    Nov 11 at 6:58












  • So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
    – JoshuaD
    Nov 11 at 7:20






  • 1




    I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
    – JoshuaD
    Nov 11 at 8:39


















  • 1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
    – JoshuaD
    Nov 11 at 6:52










  • 1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
    – nullpointer
    Nov 11 at 6:58












  • So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
    – JoshuaD
    Nov 11 at 7:20






  • 1




    I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
    – JoshuaD
    Nov 11 at 8:39
















1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
– JoshuaD
Nov 11 at 6:52




1. How did you determine the name commons.cli? I have 14 external jars in my actual project. 2. Is there a solution to the jlink / external jar problem you highlighted, or is that unsolvable?
– JoshuaD
Nov 11 at 6:52












1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
– nullpointer
Nov 11 at 6:58






1. Using the jar --file=<> --describe-module command. 2. I believe that's intentionally restricted to ensure only explicit modules(named modules) or simple terms modular projects are used while creating standalone runtime environments using jlink. | Also, note 14 jars using command line is not a good choice then, you shall use a framework like Maven/Gradle as suggested by chrylis in comments as well.
– nullpointer
Nov 11 at 6:58














So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
– JoshuaD
Nov 11 at 7:20




So jlink is not a good option for a project which depends on 14 external jars that haven't been updated to be modules? Is there another method for creating a stripped down JRE?
– JoshuaD
Nov 11 at 7:20




1




1




I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
– JoshuaD
Nov 11 at 8:39




I was able to find examples on how to convert my jar dependencies here: github.com/codetojoy/easter_eggs_for_java_9/blob/master/… It's a bit cumbersome, but it's good enough for me.
– JoshuaD
Nov 11 at 8:39


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246066%2fcompile-module-that-depends-on-an-external-jar%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Full-time equivalent

Bicuculline

さくらももこ