Why does jdeps issue a warning about a split package? - java

I have a simple non-modular jar file main.jar that depends on libA.jar and libB.jar. These three jar files all reside in the current directory. I want jdeps (version 15.0.1) to generate a module-info.java file for main.jar. Here's my shell command (using cmd.exe on Windows):
jdeps --module-path . --add-modules=ALL-MODULE-PATH --generate-module-info . main.jar
This command indeed produces the desired module-info.java file but also issues this warning:
Warning: split package: org.example.main file:///D:/Temp/./main.jar main.jar
writing to .\main\module-info.java
The package org.example.main does only exist in main.jar - so I reckon there should be no warning.
Any hints as to why jdeps does see a problem here ?

Related

Javac classpath / cp option not able to find the source file

I have a source file Example.java in the following location:
C:\Users\sushr\Desktop\Experimental Java code\tutorial
Result of dir command from tutorial directory:
Directory of C:\Users\sushr\Desktop\Experimental Java code\tutorial
10/10/2020 01:51 PM <DIR> .
10/10/2020 01:51 PM <DIR> ..
10/10/2020 01:51 PM 133 Example.java <- This is the source file
I am trying to compile this file from location C:\ .
The command that I am running from the command prompt is the following:
C:\>javac -cp "C:\Users\sushr\Desktop\Experimental Java code\tutorial" Example.java
I am getting the following error:
error: file not found: Example.java
Usage: javac <options> <source files>
use --help for a list of possible options
The classpath setting for javac is for finding other libraries and classes while compiling your .java files. It is not used for finding the .java files you specified as argument for the javac program. When you call javac Example.java and you are currently in the directory C:\, then it will look for a file C:\Example.java. It is most likely that the Example.java file will not be directly in the file system root C:\.
Either specify the .java files with an absolute path or adjust your working directory with cd "C:\Users\sushr\Desktop\Experimental Java code\tutorial\" to go in that directory and compile the files from that location.
If you specify the absolute path to your .java file you should be able to just compile it without the -cp flag like so:
C:>javac "C:\Users\sushr\Desktop\Experimental Java code\tutorial\Example.java"
In macOS, I have noticed that using the "~/" to shortcut to home, it does not work. For example:
javac -cp .:~/algs4/algs4.jar MyFile.java
Instead, I had to use the full path to locate the .jar file in order to compile:
javac -cp .:/Users/username/algs4/algs4.jar MyFile.java

jdeps returns "not found"

I'm following this tutorial which tries to minimize the JVM memory footprint by building a minimal JVM.
When I'm running jdeps -s myjar.jar I'm getting:
myjar.jar -> java.base
myjar.jar -> java.logging
myjar.jar -> not found
In the tutorial he solves this by running another command.
jdeps -cp 'lib/*' -recursive -s myjar.jar
I tried this but I'm getting the same result.
How to run it correctly?
For a Maven project, you can do it like this:
Run mvn dependency:build-classpath
Copy the output of the maven-dependency-plugin (the line after "Dependencies classpath:")
Run jdeps -cp <paste output here> -s -recursive myjar.jar
It is due to Bug in Jdeps and has been the same since JDK 8 at least.
You can see the actual Path parser checks if the -cp/-classpath argument list contains "dir/.*" format and not "dir/*" format as advertised by the docs, examples and the API's javadoc.
JdepsConfiguration.java:599

Why Java fail to run class- error occurred during initialization of boot layer- Module mods not found

I have gone through the java 9 jigsaw tutorial. I have been struggling to run class, java throws below error-
java --module-path mods -m mods/com.test/com.test.HelloWorld
Error occurred during initialization of boot layer
java.lang.module.FindException: Module mods not found
Javac command-
javac -d mods --module-source-path src $(find src -name '*.java')
I am using mac, java version-
$ java -version
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
Am I missing anything?
Remove additional mods from module name-
java --module-path mods -m com.test/com.test.HelloWorld
The -m flag accepts the module name and the main class you want to run. The module name is com.test, hence the command to run the class should be:
java --module-path mods -m com.test/com.test.HelloWorld
The --module-path mods tells java where to search for to find com.test.
When you first compiled your code using javac command as-
javac -d mods --module-source-path src $(find src -name '*.java')
What you ensured using -d directory was that to
Set the destination directory for class files.
in your case the mods folder where
If a class is part of a package, then javac puts the class file in a
subdirectory that reflects the package name and creates directories as
needed.
Hence you can take a look at the mods directory after executing the command, the .class for all(*.java) would exist in the corresponding directory structure as of their package name.
Then java tool option --module-path module path or -p module path specified in your next command :
Searches for directories from a semicolon-separated (;) list of
directories. Each directory is a directory of modules.
Your listed directory according to which is mods, assuming which you must have created following the getting started link.
Followed by --module modulename[/mainclass] or -m module[/mainclass] in your command
Specifies the initial module to resolve and the name of the main class to execute if not specified by the module.
which in your case is the module name com.test and the main class com.test.HelloWorld.
Hence the complete correct syntax of the command shall be:-
java --module-path mods -m com.test/com.test.HelloWorld
^ ^ ^
module directory module name main class
Thanks for the info
2 things I was doing incorrectly
1) Using the package path again like below
module\package\package.class
We should not retype the package path while executing the class.
2) Using the dos styled backslash instead of forward slash. We should always use the forward slash (/) to separate module with the class even you are executing in windows environment.
module/package.class

compile files from different directories with javac, referring a depending jar file?

I have the following set up:
I have 4 packages:
root/src/terminal - has some java files
root/src/mail - has some java files
root/src/data - has some java files
root/src/main - has a single java file, Main.java
I also have the following files
root/bin - a folder to store .class files
root/mail.jar - a jar file which has important classes used in my code
Within the root, I would like to enter a terminal command which compiles root/src/main/Main.java and puts the class files in the root/bin location.
Can someone show me the command to do this? I'm on a Mac (running Leopard).
Here's the one liner:
cd /xyz/root
rm -rf bin/*
javac -d bin -classpath mail.jar -sourcepath src main/Main.java
Alternatively, you could use absolute directory names:
rm -rf /xyz/root/bin/*
javac -d /xyz/root/bin -classpath /xyz/root/mail.jar \
-sourcepath /xyz/root/src /xyz/root/ main/Main.java
In reference to Ant you said "I would rather keep it simple.".
In fact in the long term it is simpler to create a simple Ant build.xml file. The alternative is a bunch of non-portable scripts or batch file ... or lots of typing.
To run the application, assuming that you are still in the /xyz/root directory:
java -classpath bin:mail.jar main.Main
Or on Windows:
java -classpath bin;mail.jar main.Main
Or modify the above to use absolute pathnames in the classpath argument; e.g.
java -classpath /xyz/root/bin:/xyz/root/mail.jar main.Main
Without knowing your operating system?
What you should look into is using Apache Ant. It is a build tool that once installed and configured can utilize a build.xml file in your root to compile class files to a folder as well as package a jar file.
http://ant.apache.org/
try this:
javac -cp "/root/mail.jar;/root/src;" -d "/root/bin" Main.java
This is written hoping that you have package declarations in your classes from src folder like package terminal; and package main;.
See this: Options in javac command
Or use Apache Ant as suggested by maple_shaft.
From comment give by #maple_shaft:
In Unix, Linux operating systems the classpath separator is a colon instead of a semicolon.

Java execute jar which depends on other jar from command line

I have an application that uses an external jar. I used eclipse and it works fine. I export as jar from eclipse, having created a Manifest file that has as Class-Path: ./cab.v1.jar
I place both jars in the same directory.
I run in command line:
java -jar myApp.jar
and get java.lang.NoClassDefFoundError for the classes in the cab.v1.jar (the other jar)
Have also tried java -cp . -jar myApp.jar but no success.
What am I doing wrong?
Using the documentation for the Manifest it does not use a ./ for relative directories. Try it just with:
Class-Path: cab.v1.jar
Note that the -cp option is ignored when using -jar.
If you use the -jar option the classpath is ignored. You could start the application by
java -cp jar1.jar:jar2.jar mainclass
The class path separator ':' is ';' on windows.

Categories