Missing class files after Maven build - java

I'm using Maven 3.3.9 on Windows 10. I have a multi-POM project, and I want to share some test resources across the Maven projects. As we all know the files in src/test/* won't be included in distribution JARs, so I created a separate project just for the test resources (and accompanying Java class with the resource names), so that I could share this project across other projects.
For the sake of illustration let's say that there are two files in the foo-test project:
src/main/java/com/example/foo/test/FooTestResources.java
src/main/resources/com/example/foo/test/resource.txt
Straightforward, right? Except that when I build the project in Maven, the resulting JAR file only contains com/example/foo/test/resource.txt! The class file, which I would expect to be in com/example/foo/test/FooTestResources.class, is missing.
In fact they this file isn't even in the target directory, so it's as if Maven isn't even compiling the source file. I searched my project directory for FooTestResources.class, and it doesn't exist. Only the source code file FooTestResources.java is there.
When I build the project on Eclipse 4.6.3, Eclipse generates the file target/com/example/foo/test/FooTestResources.class as expected. When I do a mvn clean install it disappears.
What is going on?

I found it! Here's the story.
Once upon a time I had a project that needed two JARs. One JAR would contain the source code along with most of the resources, and the other would contain just a single resource. Rather than creating two projects (and two Git repositories), I tried to be lazy and I created two POMs. One POM built everything normally except for the one resource, the other… (you guessed it) ignored all the source files and generated the POM files.
You can read the full technical details here: https://globalmentor.atlassian.net/browse/CLOGR-3
For various reasons that didn't turn out to be the most manageable approach, so I split out the two POMs into separate projects repositories, as they should have been to begin with.
Unfortunately, somewhere along the way I copied the crucial lines from one of those POMs into this POM.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<skipMain>true</skipMain>
<skip>true</skip>
</configuration>
</plugin>
The skipMain is what does it. Bye-bye source files. (Apparently Eclipse ignores the details of this section.)
I was also skipping tests as well; I basically had just copied from the wrong POM, a POM I don't even have around anymore.

Related

Difference between maven plugins ( assembly-plugins , jar-plugins , shaded-plugins)

I am a beginner in maven and now I'm confused with the difference between these maven plugins. Is these all create jar files? now my questions are
what's the difference between the jar created in each plugins.( assembly plugin, jar-plugin, shaded plugin)
The purpose of each plugin. ( assembly, jar plugin, shaded plugin )
I know even without specifying any of these plugins once type mvn package there will be a jar output. What is the difference of the output jar without these plugins and the output jar with these plugins?. TIA
maven-jar-plugin: This plugin provides the capability to build and sign JARs. But it just compiles the java files under src/main/java and src/main/resources/. It doesn't include the dependencies JAR files.
maven-assembly-plugin: This plugin extracts all dependency JARs into raw classes and groups them together. It can also be used to build an executable JAR by specifying the main class. It works in project with less dependencies only; for large project with many dependencies, it will cause Java class names to conflict.
maven-shade-plugin: It packages all dependencies into one uber-JAR. It can also be used to build an executable JAR by specifying the main class. This plugin is particularly useful as it merges content of specific files instead of overwriting them by relocating classes. This is needed when there are resource files that have the same name across the JARs and the plugin tries to package all the resource files together.
Refer: comparison:maven plugin jar,assembly,shade
Jar plugin
Let's see what the following command can tell.
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-jar-plugin
It has 3 goals, help, jar and test-jar. I believe you are mostly interested in the jar goal, which according to the description does the following:
Build a JAR from the current project.
As a side note, executing mvn help:effective-pom on a project with packaging set to jar, shows that this plugin is automatically configured and gets executed during the package phase.
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Assembly plugin
This one serves a different purpose. It has 8 goals, but 6 of them are deprecated. So apart from the help goal, this leaves us with the single goal.
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-assembly-plugin
Assemble an application bundle or distribution from an assembly descriptor. This goal is suitable either for binding to the lifecycle or calling directly from the command line (provided all required files are available before the build starts, or are produced by another goal specified before this one on the command line).
You may use the assembly plugin when you want to deliver more than your project's artifact (JAR, WAR, etc.), but the configuration goes in another file.
Shade plugin
The description of the main goal is a bit disappointing.
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-shade-plugin
Mojo that performs shading delegating to the Shader component.
You mostly want to use this plugin if you want to produce an uber-jar, which is your artifact in a JAR with all its transitive dependencies in it.
Basicly, if you're building a library, you'll stick with the default JAR plugin. If you're building an application, you could consider using the shade plugin, though to me, it's kind of quick and dirty. If uber-jar is not your taste or the distribution cannot fit inside a single JAR (external configuration, native dependencies, etc.) then you should go for the assembly plugin.

Using third-party libraries in Eclipse RCP Tycho app

I've created a boiler-plate project following vogella's extensive Tycho tutorial.
Facts:
There's no feature, and there's no plugin. The only plugin is the RCP app, which is also the entry-point.
Problem:
I have no idea in which pom.xml do I include the 3rd party dependencies.
I cannot include them in the RCP project, because the packaging of that pom is eclipse-plugin, and not jar. From what I've noticed, if I change the packaging to jar, then the "Maven Dependencies" library is added automatically. If I change back to eclipse-plugin, they get removed.
Questions:
Where do I add the dependencies? There's no pom with jar packaging in my project.
Should I create a separate project with the necessary JARs? How do I include that dependency to my entire project?
Is it really that much of a good practice to create a separate plugin and a feature for this RCP app?
Related solutions:
"Update projects" doesn't work, and neither do the n other solutions in the other SO questions.
There's also this question and that question, but I don't fully get the answers
I think that you have a fundamental misunderstanding.
Maven: Maven determines all of the project dependencies via the pom.xml and resolves transitive dependencies automatically (assuming that all of the pom files and artifacts exist in repositories that you've configured and correctly declare their dependencies).
Tycho: The problem is that Eclipse already has its own project model based on product files, feature.xml files, and plug-in MANIFEST.MF files. Tycho leverages the Maven machinery for Eclipse, but the idea is that the pom.xml files just configure the Maven plug-ins and declare the packaging type. That provides an entry point for Maven, but then Tycho takes over. While Maven would normally build the dependency chain from information in the pom.xml files, Tycho is building the dependency change from information in the product, feature, and MANIFEST.MF files. You don't put any dependencies in the pom.xml files. Tycho also uses Eclipse p2 repositories (instead of normal Maven repositories) for finding dependent plug-ins that are not found in the local modules or target platform.
That's actually a benefit for many Eclipse developers since they've already set up everything properly in their Eclipse plug-ins, features, and products. They do not want to have to repeat all of the dependencies in the pom.xml.
Using Libraries in Eclipse plug-ins: In Eclipse, if you want to use a library that is not already packaged as an Eclipse plug-in, you have a few options. Your plug-in can include a set of JARs in a libs folder and then include that libs folder in the plug-in and runtime classpath (see the build.properties file). Another option is to create your own "library plug-in" that repackages a JAR library as an Eclipse plug-in. See also https://wiki.eclipse.org/FAQ_What_is_the_classpath_of_a_plug-in%3F. That's the answer that you're getting above.
The problem is that if you're trying to include a complex library with multiple JARs that is normally distributed and included in a standard Java project via Maven. We hit this problem with the Jersey JAX-RS implementation in my project. There's no p2 repository that includes all of the pieces of the libraries as plug-ins with correct dependency information.
Easy Solution: If you need a common library, check the Orbit project first to see whether the libraries have already been packaged as Eclipse plug-ins, http://www.eclipse.org/orbit/. In that case, you can download them and include them in your target platform, or you can pull them in dynamically at (Tycho) build time from their p2 repository. Your plug-ins would just include those plug-ins as dependencies (in the their MANIFEST.MF files).
Workaround / Solution: In our case, Jersey JAX-RS was not available as an Eclipse plug-in, and it had a bunch of transitive dependencies. The workaround was to create an Eclipse "library plug-in" like I mentioned above with two pom files. We initially created a skeleton plug-in with an empty libs folder. One pom file is just a standard Maven pom file with <packaging>jar</packaging> that declares the top-level dependencies required to pull in the Jersey JAX-RS implementation and all of its dependencies. The dependencies are declared with <scope>compile</scope>. We use the maven-dependency-plugin to copy all of those dependencies into the project's libs folder.
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
We actually ended up running Maven with that pom by hand from time to time to update the libs, and then we just checked the plug-in with all of its dependent JARs into source control. Checking the build later, I see that we actually populate the libs folder on-the-fly with Maven with a separate build task just before we start the Maven/Tycho part of the build. Of course, plug-in's MANIFEST-MF file's Bundle-ClassPath and Export-Package entries are coming straight from source control. We have to check those from time to time to ensure that they match the libraries and packages that we're getting from Maven. (That doesn't tend to change much unless we bump major library versions or add a new dependency at the Maven level.) The plug-in's build.properties has the libs/ folder as part of bin.includes.
In the development environment, after we first check out the code, we just run mvn (with an External Tools launch config that's also checked in with the project) on the project's "copy dependencies" pom file. That populates the libs folder with all of the JAX-RS libraries and dependencies. We only have to run it again when we update something about the dependencies or when we're jumping between branches that have different versions of the JAX-RS dependencies. We set .gitignore to ensure that we don't commit the libs to Git.
The other pom for this project is set up like a normal Tycho pom file with <packaging>eclipse-plugin</packaging>. During our automated build, we run one step early in the build process (just after check out) that calls mvn with the jar pom to populate the libs. Then we proceed with the main Maven/Tycho build using the eclipse-plugin pom. The eclipse-plugin pom has no dependency information (as I said above). It's just providing Tycho a way to recognize the Eclipse plug-in and build it based on its MANIFEST.MF and build.properties files. But the built plug-in includes and exposes all of those libs that were populated by the mvn call to the jar pom step.
So, it's a bit of a mess, but that's the best solution we found a couple of years ago when we hit this problem. I'm not sure whether Tycho is doing any work to permit some sort of hybrid Maven/Tycho build that could do this automatically as part of the build. I guess I should ask the developers. :)
Your questions:
Where do I add the dependencies? There's no pom with jar packaging in my project. Answer: The workaround above lets you do it with one project. You just have two pom files, like pom_deps.xml and pom.xml. You just have to invoke the pom_deps.xml separately to populate the libs folder (in the dev environment and with your automated builds).
Should I create a separate project with the necessary JARs? How do I include that dependency to my entire project? Answer: the workaround that I described above lets you do it with a single project. Another way to do it is to create a separate JAR project, but I don't think that your Eclipse RCP app can really include a <packaging>jar</packaging> module in a useful way. The only way I've found to do it is to use a similar workaround. You build the JAR module first, install it into the maven repository, and then have one of your plug-in projects bundle the JAR in its libs folder. (If you really want to do it that way, ask. We have a case where we have to do that, too, and I can provide the steps we do in development and the build to make it work. I think the single project workaround that I provided above makes more sense for your case.)
Is it really that much of a good practice to create a separate plugin and a feature for this RCP app? Answer: that's really a separate question. If you have a feature with multiple plug-ins, you have the same problem. Tycho can handle the product/feature/plug-ins, but it cannot jump across into Maven-based dependency resolution. You'll end up having to use the same workarounds
Summary: The fundamental issue is that Eclipse plug-ins can't "see" a bare JAR library. The plug-in needs to have the library included in its local libs folder (with a matching Bundle-ClassPath entry in MANIFEST.MF), or it needs to depend on some other plug-in that exports the appropriate packages. Tycho just resolves dependencies via Eclipse plug-ins, and it cannot leverage normal Maven dependency resolution directly to pull in a bunch of JARs. If all of your dependencies are already plug-ins, you're fine. If not, you may have to use the workaround above to package a set of libraries for your plug-ins to use.
Just adding the plugin to pom dependencies and including the entry <pomDependencies>consider</pomDependencies> in the configuration of target-platform-configuration makes it work.
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho.version}</version>
<configuration>
<!-- The configuration to make tycho consider the maven dependencies -->
<pomDependencies>consider</pomDependencies>
<!-- other configurations -->
</configuartion>
</plugin>
<!-- other plugins-->
</plugins>
<dependencies>
<!-- An example third-party bundle (plugin) present in maven repository-->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.gogo.shell</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
Reference link here.

Maven and Eclipse : loading default properties in maven library project and use it in runnable Jar

I believe this problem has been asked before on stackoverflow. And I'd like to mention that I tried the solutions that came with the questions related to mine. The one that came the closest to my problem was:
Load properties file in JAR?. Sadly the solution described there didn't work for me. And due the age of the question I thought asking it again is the way to go.
Heading on to describing my problem.
So currently I'm working on a library project which has been setup with maven and creates an extension for the current Spring AMQP project.
The goal here is to supply a JAR file which can be included into another project to support a specific way of communicating over a message broker.
At this point I'm implementing the configuration option to allow users to configure the messaging client to their liking. But while i was testing the functionality of this feature I hit a problem while using the library in an executable JAR.
While running it in the Eclipse workspace everything seems to work just fine. But when I try to run it from my desktop (as a runnable JAR) the properties file does not seem to be found anywhere.
Just to give a quick overview of the workspace/projects setup as described above:
The project structure of both project reflects the Maven default one:
- src/main/java
- java source files
- src/main/resources
- resource files
- src/test/java
- java test files
- src/test/resources
- test resource files
Where the library file contains a default.properties file in the src/main/resources folder and the chatclient project a custom.properties file.
Once the runnable JAR file has been build it has the following structure in it.
- com
- junit
- META-INF
- org
- resources
- default.resources
- custom.resources
I believe the resource files should not be located there. but in the META-INF/maven folder instead. After trying out stuff like:
Adding a META-INF folder into my src/main/resources folder and putting the property files there.
Adding a MANIFEST file with Class-Path: . in it.
Loading the file in multiple ways in code.
But nothing seems to work. I guess it is Maven related and a simple change in the pom.xml could fix it. Sadly my knowledge on the Maven project setup and pom related subjects is very basic (this is my first project using maven). And I can't seem to find any documentation on it, even though I know it should be there (probably a problem caused by me).
Before I forget to mention it. I load the property files using this way:
Properties props = new Properties();
prop.load(<custom static class>.class.getResourceAsStream(filename));
return props;
Also the pom.xml for my library looks like:
-- Artifact stuff --
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
-- Dependency stuff --
And the one for the project that uses the library look like:
-- Artifact stuff --
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.maxxton</groupId>
<artifactId>async-amqp-messaging</artifactId>
<version>0.2</version>
</dependency>
</dependencies>
-- Other stuff --
I hope there is someone who's a little more advanced on this subject and could help find a solution for this problem. And if you need any additional information on the project files/structure, please let me know. I'd gladly share it with you.
Update (28-04-2015 {1})
For testing I created a sample project which tries to load property files the same way as the scenario described above.
Even while following the Maven documentation (Using the META-INF folder) I was not able to load the properties.
For the sake of this question I uploaded the testing workspace here.
I hope someone could help me fix this, as the normal way as described on the Maven website does not seem to work for me.
Update (28-04-2015 {2})
Well I managed to fix a part of the problem.
Since I added the configuration for the maven-assembly-plugin (building runnable JAR with deps), I was able to get the correct structure within my JAR file.
The thing I added was:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>project</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.test.project.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then when running clean compile assembly:single I managed to get the right structure.
JAR root
- com
- META-INF
- MANIFEST.MF
- default.properties
- custom.properties
While this fixes a part of the problem. The file loading still results in a NullPointerException.
Final Update (04-05-2015)
After a long Maven struggle I managed to get everything the way I want it to be.
Following the advice given by both #Deepak and #Joop Eggen, I did some research on how to have all the dependencies in a lib folder as jar instead of unpacking them in a 'uber' jar. After trying loads of stuff I stumbled upon this answer. Following the instruction there seems to create this structure:
- runnable.jar
- lib
- spring-amqp.jar
- spring-core.jar
...
When following #Joop Eggen's advice I managed to get the property loaded the way I want to. So it seems this question has been answered. Currently I'm still figuring out how to award each answer as I'm not able to split the bounty into two pieces. I'll get back on that.
Side Note
Although I awarded both the bounty and the answer to #Joop Eggen does not mean that #Deepak's answer did not contribute. It did give some great information on best practice, but was not as complete as the accepted answer. So please when finding your answer here give him some of the credit too.
There are two ways to get resources,
with a ClassLoader against the entire class path using absolute paths (without /...),
with a class, using a relative (...) or absolute (/...) path inside the jar of that class.
The latter seems more direct, and can be used as:
getClass().getResource("/...");
ClassInJar.class.getResource("/...");
Now getClass() is only possible in a non-static object and is dangerous too: the actual class might be some child, not in the library jar.
On the actual structure of your application. I know a maven directory convention:
src/main/java/...
src/main/resources/...
where /... gets into the jar/war; the package directory.
Reassembling jars is not good. There always is the Class-Path: ... entry in META-INF/MANIFEST.MF. Following the basic maven conventions is best.
The solution to this is simpler, however there are couple of concepts that I would like you to be aware off.
It is not a good practice to create one big jar by using maven assembly plugin. In your examples, you are using small jars both developed by you, so it might seem okay. But as your real projects get bigger, this is not ideal, you would want separation of different modules and not one big jar. The ideal practice is opposite to what you are trying to achieve - you should aim to have smaller and smaller jars. You might in future want the convenience of replacing these smaller jars without having to deliver the entire package again.
You would surely not want to unpack 3PP jars and package them as your own jar!
Based on the above, you might wonder how do you create executable jars. Well, the answer is having the dependent jars in the class-path. When executing the "project" jar, you should have the "library" jar in the class-path and it will be able to find the properties file inside as expected.
You places the properties files in META-INF directory. The right place for them is the resources folder. And if you follow the point No.1, things will work as expected.

maven with eclipse error "Path must include project and resource name"

I've recently started using maven with eclipse.
I've set up several projects and I've noticed that if I try and specify a build directory (to over-ride target) which is outside the project directory, I get an error when doing "update project":
'Updating Maven Project' has encountered a problem.
An internal error occurred during: "Updating MAven Project".
Path must include project and resource name: /[my project name]
I need to build outside the project. How can I get around this? Can I perhaps have maven automatically create a softlink?
Although this is a fairly old thread, I recently encountered this problem and was able to solve it. The reason why maven threw this error is I had, somewhere in my pom.xml file, an absolute path that was not consistent with the directory from which the project was imported into eclipse. So I had two absolute paths (one incorrect, or points to a previous location) that point to resources, i.e. project.build.outputDirectory, in the pom.xml file.
The Solution: Locate the faulty absolute path, /home/userA/ProjectB/bin, and replace with a relative, ./bin, path. Update the project in eclipse and you should be fine.
This is a bit old thread, but since nobody gave a correct answer...
The following Eclipse error:
An internal error occurred during: "Updating Maven Project".
java.lang.IllegalArgumentException: Path must include project and resource name:
at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63)
at org.eclipse.core.internal.resources.Workspace.newResource(Workspace.java:2069)
at ...
can occur in many different scenarios - in the Eclipse Bugzilla you can find a lot of similar bug reports.
In situation you described, it is a known limitation. But it's not a m2e fault - simply Eclipse JDT does not allow setting output dir outside of the project.
IMHO it's a pity, because if maven supports a such layout, so I would expect that m2e should as well.
I've reported it as a bug 493229. But it has been closed with status WONTFIX.
To answer the last paragraph in your question, you can get around the problem with a softlink. I did it a little differently than what you guessed at. It's not Maven that creates the symlink because this is a problem with Eclipse JDT (as others have pointed out) which runs without invoking Maven at times (it seems). Here's what I did, with all paths relative to my Maven project directory:
1) I wanted my actual build directory to be "../../local/java/scratch/target"
2) I created a softlink: ln -s ../../local ./
3) I added this entry to my "pom.xml":
<build>
<directory>${project.basedir}/local/java/scratch/target</directory>
</build>
Now Eclipse JDT happily thinks it's building within the project directory but in reality the path "../../" takes it outside of the project directory. My guess is that an absolute path would have worked too.
For example, if you'd like to have build contents in some folder outside workspace, you can have something like :
<build>
<plugins>
<plugin>
<executions>
<execution>
<phase>move-build</phase>
////do your build
</plugin>
<plugin>
<executions>
<execution>
<id>copy-resources</id>
<phase>move-build</phase>
// do your copying to external
</plugin>
<plugin>
<executions>
<execution>
<phase>move-build</phase>
// do your deletions from target
</plugin>
</plugins>
</build>
then you can call mvn move-build to have your build, copy, delete done.
here is an example of copy to external folder and delete, you can combine both into your move-build phase as described above
why can't I build somewhere like ../build
Yes you can build in some folder called build provided it contains the pom.xml.
The pom.xml file is the core of a project's configuration in Maven. It is a single configuration file that contains the majority of information required to build a project.
In short the pom.xml will have all information to build your project.
pom.xml is a file which contains the project configuration details used by Maven. It provides all the configuration required for a project.
I was convinced that this problem was caused by either Maven or Eclipse, perhaps because I found this and other references to that combination on Stackoverflow.
After considerable investigation, and going slightly mad, it turns out that Git was involved - though I don't know if it was the cause.
My Maven project consists of several "nested" POMs, and I don't open the parent POM in Eclipse, but only the children. I had a couple of files (batch scripts) at the top level which I hadn't committed to Git, but once I committed these the
Path must include project and resource name
problem disappeared completely.
Eclipse version: 2020-12 (4.18.0)

Finding unused jars used in an eclipse project

Are there any plugins/tools available to go through the classpath of an eclipse project (or workspace) and highlight any unused jars?
ClassPathHelper is a good start.
It automatically identifies orphan jars and much more.
The only limitation is with dependencies that are not defined in classes, e.g. in dependency injection framework configuration files.
You also have other options/complements, such as:
workingfrog "Relief", which relies on the ability to deal with real objects by examining their shape, size or relative place in space it gives a "physical" view on java packages, types and fields and their relationships, making them easier to handle.
Unnecessary Code Detector: a eclipse PlugIn tool to find unnecessary (dead) public java code.
UCDetector does not help for this : It does not work on JARs.
And for classpathHelper, I wan't able to find out an easy way just to list the orphan JARs (BTW, if someone has a tutorial for this, i am interested).
So, if you are also using Maven as I do, I find out this great Maven plugin, and I would like to share this solution with you.
Just type :
mvn dependency:analyze
And you will instantly get a list of unused JARs in your dependencies.
Very handy !
I found a very fast and interesting tool to archive this goal:
http://tattletale.jboss.org/
Just unzip the program and run:
java -Xmx512m -jar tattletale.jar ~/myjavaproject/mydistribution output
This will generate a very impressive report with different points (text from their site):
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
You can use one of this plugins:
UCDetector or Classpath Helper
I know this is an old one, but if anyone else stumbles upon this, Eclipse does this by itself.
Navigate to Project properties->Java Code Style->Clean Up
Select the Eclipse [Built-in] and it does the following:
Change non static accesses to static members using declaring type
Change indirect accesses to static members to direct accesses
(accesses through subtypes)
Remove unused imports
Add missing '#Override' annotations
Add missing '#Override' annotations to implementations of interface
methods
Add missing '#Deprecated' annotations
Remove unnecessary casts
Remove unnecessary '$NON-NLS$' tags
In the Maven and Gradle projects you can use those plugins to identify unused dependencies.
For Maven : link
Use this in the pom.xml file plugin.
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
</plugin>
</plugins>
</build>
this will give as output. In this case we add commons-collections dependency to pom.xml, but do not use in the code.
For Gradle : link
Use this in the build.gradle file plugin.
plugins {
id "ca.cutterslade.analyze" version "1.7.1"
}
Using legacy plugin application:
this will give as output. In this case we add dependencies unusedDeclaredArtifacts to gradlefile, but do not use in the code.

Categories

Resources