Some preliminary notes on jdeprscsan
from Oracle JDK 11 under Windows (I know the question related to JDK 9 on CentOS, but maybe the following applies as well...):
- use wildcard "path/to/lib/*.jar" (it will not work without the ".jar" extension)
- having a wildcard with more than one path is not supported (i.e.
--class-path dir1/;dir2/*.jar
throws a parse exception on the wildcard)
- JARs in the directory specified by
--class-path
are added to the classpath and analyzed in alphabetical order, which may cause some error : cannot find class X
messages because a JAR a.jar
may depend on a JAR b.jar
which is not yet loaded.
Based on the above, I found the 3 solutions below. Note that I did the same experiment with jdeprscan
from the Oracle JDK 12.0.2 without any improvement.
Solution 1: all classes on the classpath
- unzip all JARs in a specific directory (ignore overwritted files such as META-INF/maven/pom.xml), e.g.
mylib
(note that at this stage, the mylibs directory contains only classes organized by directory packages, and no JARs).
- run the following command:
jdeprscan --for-removal --class-path /path/to/mylib /path/to/my-application.jar
Advantage: fast (very manual operations)
Drawback: only analyses the JAR file that has been specified on the command line (my-application.jar
)
Solution 2: all JARs + a fat JAR on the classpath
- copy all JARs libs into a single
mylib
directory
- extract all files from JARs of
mylib
(ignore duplicate files) and repack them into a big JAR mylib/00lib.jar
(a simple ZIP file renamed to .jar
makes the trick)
- copy the
mylib/00lib.jar
to mylib/01lib.jar
to ensure that it will be analysed
run the following command:
jdeprscan --for-removal --verbose --class-path path/to/mylib/*.jar path/to/my-application.jar
Advantage: fast (only a few manual operations) + analyses the JARs from mylib
Drawback: some of the jdeprscan
messages will be related to the fat JAR 00lib.jar
so you will not be able to determine immediately which library uses classes that are deprecated or removed from Java 9 or 11, but you can do it indirectly by looking at the class name, e.g. (a class from the com.atomikos
library requires the missing class javax.jms.JMSException
):
Processing class com/atomikos/datasource/xa/jms/JmsTransactionalResource...
error: cannot find class javax/jms/JMSException
Solution 3: reorder the JAR files on the classpath
- copy all JARs libs into a single
mylib
directory
run the following command:
jdeprscan --for-removal --class-path path/to/mylib/*.jar path/to/my-application.jar
inspect the log to see error: cannot find class
messages that are not supposed to be raised because the JAR exists in the lib directory. For each such library, copy the library with a name that is before the library name which reference it alphabetically speaking. For example, I have a JAR in the lib dir alpha.jar
which depends on commons-lang-3.0.jar
(which is not yet loaded in the classpath), so I copy commons-lang-3.0.jar
to a0commons-lang-3.0.jar
so that it will be loaded before alpha.jar
. It is important to copy the JAR and not to rename it otherwise it may not be analyzed by jdeprscan
(does not occur on every JAR). Once done, go back to step 2 until no error messages produced by library dependencies occurs.
Advantage: gives a clear view of which JAR uses deprecated/removed classes.
Drawback: takes a lot time (manual copy of each individual JARs which cause a classloading issue).
Conclusion
I use jdeprscan
with Solution 2. This should be considered as a workaround (is it an incomplete tool documentation or a bug, I don't know...).