How to distinguish whether the class files in the jar package belong to itself or its dependencies? - java

I'm working on some jars and building call graphs by analyzing bytecode files. I only want to analyze the class files belonging to the jar package itself, not its dependencies
The Maven central repository does not stipulate that the uploaded jar package must have its dependencies or not, and the class files in the jar package are not always organized according to groupId and artifactId.
For example, I download antisamy-1.5.3.jar from [Maven Central Repository] (https://search.maven.org/). And its id is org.owasp.antisamy:antisamy:1.5.3. The following figure is the directory organization structure of this jar package.
enter image description here
We can see that the path where the class file is located is not prefixed with groupId and artifactId.
There is an another expamle called org.apache.sling.xss-2.0.0.jar with the id org.apache.sling:org.apache.sling.xss:2.0.0.It looks like this jar package contains many class files from its dependencies.
enter image description here
Did anyone know how to distinguish them from its dependency class files?
Thanks a lot!

"Normal" libraries don't contain their dependencies.
But there are exceptions, like OSGi bundles or fat JARs. I don't think it is always possible to tell the internal and external classes apart, though in most cases, the Java packages will help you.

Related

Is there a way to bundle up multiple jars within the same jar file and make sure only one main jar inside it becomes part of classpath of the app

Is there a way to bundle up multiple jars within the same jar file and make sure only one main jar inside it becomes part of classpath of the application which adds this full jar into their classpath.
Code inside my main jar will use a custom class loader to load classes present in other Jars in the full jar.
I also want to create directory structure for other jars so that I can segregate jars based on use case and load only jars from a within directory inside the full jar.
Any help with any of the requirement above is appreciated. Thanks.
you can use Maven Shade plugin because it is a better option to create jar within jar based on custom business logic, if compare with the maven assembly plugin, it provides a class relocating feature, to avoid the issues in the complex structure of the classpath.
sample shade plugin configuration
you can also use many transformations in Shade plugin from the below list as per your requirement.

Maven : Copy only selected jars inside WEB-INF/lib

In my Maven project , I have certain dependencies which should be present inside the WEB-INF/lib . I cannot put all the jars inside WEB-INF/lib , only the selected ones . How to go about doing this?
I cannot use the maven-resources plugin since then I would have to mention the entire jar's name inside <include> tag and I need to keep it dynamic.
I tried using <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> but this not give me an option to insert only selected jars inside the lib folder.
I also tried using <scope>provided</scope> for some of the jars but due to this the name of the jar doesn't get added to the classpath field inside manifest.mf file.
Please suggest some solution. Thanks in advance!
You can use Assembly plugin and customized assembly descriptor. In descriptor you can set which jars you want to copy with their artifact id, group id, version and scope. it also supports regex. https://maven.apache.org/plugins/maven-assembly-plugin/advanced-descriptor-topics.html
This may not be the best way to package the content for the WEB-INF/lib/ nested directory in a WAR file, but the implementation presented in the question for How to put all required jars in a lib folder inside the final jar with maven (using the maven-dependency-plugin plugin) solved my JAR needs for bundling all dependent jars into the lib/ directory of my final jar. Oddly it's a commonly asked question, with many different solutions. This implementation actually bundled the jars inside the nested lib/ directory, while others, for example, extracted the contents of my dependent jars and laid their classes beside my classes. So this might get you a little closer but probably not the official way of handling a WAR files' library deps.

Finding dependecies amongst JARs

We are in process of migrating our project from Ant to Maven. While doing this migration we are facing difficulties in finding dependencies between jars that are used in Ant. I just want to know main jars which are needed to mention in pom.xml and the remaining jars will be automatically downloaded.
In short I want to know how to find dependecies amongst JAR files used in our project.
There is a tool from JBoss project called JBoss TattleTale, might be worth taking a look:
The tool will provide you lot more then just dependencies finding :
Identify dependencies between JAR files
Find missing classes from the classpath
Spot if a class/package is located in multiple JAR files
Spot if the same JAR file is located in multiple locations
With a list of what each JAR file requires and provides
Verify the SerialVersionUID of a class
Find similar JAR files that have different version numbers
Find JAR files without a version number
Find unused JAR archives
Identify sealed / signed JAR archives
Locate a class in a JAR file
Get the OSGi status of your project
Remove black listed API usage
And generate the same reports for your .WAR and .EAR archives
I would suggest you use jarAnalyzer which will traverse through each of the jar files in that directory specified, and identify the dependencies between the jar files. The output will be xml representing the dependencies between two jar files.

Creating jar issue

This question may be theoretical but I could not find any proper solution.
Suppose I am making a module which uses 3 jar file(hibernate,log4j,jackson).
Now I want to compile my module and create a jar such that my module can be used by any other module and that module should not require the three jars(hibernate,log4j,jackson) to again.
i.e my module jar file should not have any dependencies.
I am using eclipse.I am able to create a jar(project->export->jar) but it does not include the jars in it
Guide me how can I do that.
Is apache ant of any use here?
Eclipse's Runnable Jar Wizard
Eclipse's Runnable Jar Wizard (File → Export… → Java → Runnable Jar File) allows developers to create executable jars from an existing run configuration:
The wizard includes 3 options for handling dependencies:
Extract required libraries into generated jar: unarchives library
dependencies and repackages them into your executable jar. This
option has the advantage of simplicity and does not require a custom
class loader. However repackaging library jars can cause other
problems and does not preserve the signatures of signed jars. This
option may also violate the license terms of the libraries you are
using.
Package required libraries into generated jar: creates a "fat jar"
with a custom class loader. The resultant jar contains
the application's classes and resources
library jars required to launch the application
a small custom class loader that knows how to find jar libraries inside another jar archive
Copy required libraries…: creates the application archive and copies
any required library dependencies to the destination folder.
I think the second option suits your present purpose.
You will need to include all classes from your dependencies into your jar file.
Since a jar file is merely a zip file, you can use any archive manager such as Winzip to explore them, then copy the contents of the jars you depend on into your own jar, taking care to keep the directory structure intact.
That way you have everything in one jar.

Difference between extracting and packaging libraries into a jar file

I would like to know the difference between extracting and packaging libraries into a jar file from eclipse with the runnable jar file creation.
If my program (runnable jar) uses other classes which require these external libraries(jars), what should I pick?
If you want to put jars into your generated jar file, you can use packaging method.
For example if you are using an Apache library or some other 3rd party jars, you may want to keep these jars preserved in your generated jar. In this case, use packaging.
"Packaging required libraries into a jar file" option puts classes of org.eclipse.jdt.internal.jarinjarloader package into your generated file and this package is just under the root directory of the generated jar file. This option also creates a larger jar file in terms of size due to jar loader classes of Eclipse.
Extracting required libraries will result in putting classes of 3rd party libraries into your jar file by following the package naming convention, e.g. if you open your jar content you can see some classes under org.apache.. packages.
Main class entries are different between the MANIFEST.MF files of these jar files:
Main class entry when you package required libraries:
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Main class entry when you extract required libraries:
Main-Class: YourMainClass
For my use, the principal difference is that packaged JAR files are included intact as a distinct item, hence retaining their copyright information and signature data.
If you choose extract, the class files are pulled out of their original context and stored as if you had originated them, hence possibly violating some licence conditions, although the size of the final JAR will be smaller in this case. Eclipse does warn you about licensing in this case, too.
So, if using third-party JAR libraries, it's professional to always package.
Try it both ways, and open the resulting jar files with a Zip program. Very instructive.
These are mainly two ways to export as a Runnable jar in eclipse.
1). Package required libraries into jar
This will add actual jar files of the libraries into your jar.
This is the cleanest since it separates application class files with
library JARs.
The downside is this makes runnable jar perform very slow.
2). Extract required libraries into generated jar
This way will extract only the actual class files from the libraries
that your application uses and includes in the runnable jar file.
As a result your Jar file will include your application class files
as well as class files of all the libraries used by your application.
This method makes runnable jar perform just like it is run in your
eclipse IDE.

Categories

Resources