I have the following project structure.
ProjectName
|
|---src
|
|---main
|
|---java
| |
| |---ModuleName
| |
| |---module-info.java
| |
| |---PackageName
| |
| |---Main.java
|
|---resources
|
|---ResourceParentFolder
|
|---ResourceSubFolderA
| |
| |---Resource1A.png
| |---Resource2A.png
| |---Resource3A.png
|
|---ResourceSubFolderB
|
|---Resource1B.png
|---Resource2B.png
|---Resource3B.png
Here is my Main.java
.
package PackageName;
public class Main
{
public static void main(String[] args) throws Exception
{
new Main();
}
public Main() throws Exception
{
System.out.println("0 - " + ModuleLayer.boot().findModule("ModuleName") .map(o -> o.getClassLoader().getResource("PackageName/Main.class")));
System.out.println("1 - " + ModuleLayer.boot().findModule("ModuleName") .map(o -> o.getClassLoader().getResource("ResourceParentFolder")));
System.out.println("2 - " + ModuleLayer.boot().findModule("ModuleName") .map(o -> o.getClassLoader().getResource("ResourceParentFolder/ResourceSubFolderA")));
System.out.println("3 - " + ModuleLayer.boot().findModule("ModuleName") .map(o -> o.getClassLoader().getResource("/ResourceParentFolder")));
System.out.println("4 - " + ModuleLayer.boot().findModule("ModuleName") .map(o -> o.getClassLoader().getResource("/ResourceParentFolder/ResourceSubFolderA")));
System.out.println("4b - " + ModuleLayer.boot().findModule("ModuleName") .map(o -> o.getPackages()));
System.out.println("5 - " + ModuleLayer.boot().modules());
System.out.println("6 - " + ModuleLayer.boot().parents());
System.out.println("7 - " + ModuleLayer.boot().toString());
System.out.println("8 - " + Main.class.getClassLoader().getResource("ResourceParentFolder"));
System.out.println("9 - " + Main.class.getClassLoader().getResource("/ResourceParentFolder"));
System.out.println("10 - " + Main.class.getClassLoader().getResource("ResourceParentFolder/ResourceSubFolderA"));
System.out.println("11 - " + Main.class.getClassLoader().getResource("/ResourceParentFolder/ResourceSubFolderA"));
System.out.println("12 - " + Main.class.getClassLoader().getSystemClassLoader().getResource("ResourceParentFolder"));
System.out.println("13 - " + Main.class.getClassLoader().getSystemClassLoader().getResource("/ResourceParentFolder"));
System.out.println("14 - " + Main.class.getClassLoader().getSystemClassLoader().getResource("ResourceParentFolder/ResourceSubFolderA"));
System.out.println("15 - " + Main.class.getClassLoader().getSystemClassLoader().getResource("/ResourceParentFolder/ResourceSubFolderA"));
}
}
module ModuleName
{
requires java.base;
}
Here is my shell script which performs compilation, executes it, creates a modular jar, executes that, and then calls jpackage
.
echo "STARTING TO COMPILE MODULAR SOURCE CODE"
javac \
--module-source-path=src/main/java \
--module=ModuleName \
-d classes
echo "STARTING TO RUN MODULAR SOURCE CODE"
java \
--module-path="classes" \
--module=ModuleName/PackageName.Main
echo "STARTING TO BUILD A MODULAR JAR"
jar \
--verbose \
--create \
--file run/executable/jar/ProjectName.jar \
--main-class PackageName.Main \
-C classes/ModuleName .
echo "STARTING TO RUN A MODULAR JAR"
java \
--module-path="run/executable/jar" \
--module=ModuleName/PackageName.Main
echo "STARTING TO RUN JPACKAGE"
jpackage \
--verbose \
--type msi \
--name ProjectName \
--input src/main/resources \
--install-dir davidalayachew_applications/ProjectName \
--vendor "David Alayachew" \
--win-dir-chooser \
--module-path run/executable/jar \
--module ModuleName/PackageName.Main \
--win-console \
--java-options "--enable-preview" \
--dest run/executable/installer
As you can see, it creates a few directories.
Now, the output during executions is where my frustration is.
Here is the output when running immediately after compiling.
STARTING TO RUN MODULAR SOURCE CODE
0 - Optional[file:**ignore**/ProjectName/classes/ModuleName/PackageName/Main.class]
1 - Optional[file:**ignore**/ProjectName/src/main/resources/ResourceParentFolder]
2 - Optional[file:**ignore**/ProjectName/src/main/resources/ResourceParentFolder/ResourceSubFolderA]
3 - Optional.empty
4 - Optional.empty
4b - Optional[[PackageName]]
5 - [**ignore**]
6 - []
7 - **ignore**
8 - file:**ignore**/ProjectName/src/main/resources/ResourceParentFolder
9 - null
10 - file:**ignore**/ProjectName/src/main/resources/ResourceParentFolder/ResourceSubFolderA
11 - null
12 - file:**ignore**/ProjectName/src/main/resources/ResourceParentFolder
13 - null
14 - file:**ignore**/ProjectName/src/main/resources/ResourceParentFolder/ResourceSubFolderA
15 - null
Ok, it found the folders. And since it is java.net.URLConnection
, I can traverse the directory by modifying the URL
. So, things worked running the code immediately after compile.
Here is the output when running the created jar file.
STARTING TO RUN A MODULAR JAR
0 - Optional[jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/PackageName/Main.class]
1 - Optional[jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/ResourceParentFolder/]
2 - Optional[jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/ResourceParentFolder/ResourceSubFolderA/]
3 - Optional.empty
4 - Optional.empty
4b - Optional[[ResourceParentFolder.ResourceSubFolderB, ResourceParentFolder.ResourceSubFolderA, ResourceParentFolder, PackageName]]
5 - [**ignore**]
6 - []
7 - **ignore**
8 - jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/ResourceParentFolder/
9 - null
10 - jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/ResourceParentFolder/ResourceSubFolderA/
11 - null
12 - jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/ResourceParentFolder/
13 - null
14 - jar:file:///**ignore**/ProjectName/run/executable/jar/ProjectName.jar!/ResourceParentFolder/ResourceSubFolderA/
15 - null
Ok, a different type of connection, but we still found the same folders. I will likely have to do URL
construction a little differently, but the path forward is fairly clear.
Now, here is what happens after I run my newly installed jpackage
version of my application.
0 - Optional[jrt:/ModuleName/PackageName/Main.class]
1 - Optional.empty
2 - Optional.empty
3 - Optional.empty
4 - Optional.empty
4b - Optional[[ResourceParentFolder, PackageName, ResourceParentFolder.ResourceSubFolderA, ResourceParentFolder.ResourceSubFolderB]]
5 - [module ModuleName, module java.base]
6 - []
7 - ModuleName, java.base
8 - null
9 - null
10 - null
11 - null
12 - null
13 - null
14 - null
15 - null
Nothing can be found aside from the .class
file I put as a sanity check.
So, I opened up the installation directory, and I see that my resources are definitely there. The whole directory, subdirectories, and files. Everything inside of and including ResourceParentFolder
from my tree structure has been copied over to the C:/Program File/davidalayachew_applications/ProjectName/app folder.
I tried a laundry list of configurations, like prepending the getResource
parameters with app, but that was no good. I have cycled through >100 permutations, and truthfully, I have forgotten most of them.
Can someone give me a pointer on how to get my resources to be accessible to my application after calling jpackage? I specifically need to be able to see the contents of a folder. Not just fetching individual files.