Compiling Maven: Removing Deprecated Class Files from Target

We use Maven to compile our project on the build server. We update our sources from SVN, and then run "mvn install" from the project folder, creating a jar, which we then deploy to our production servers.

To save compilation time, we save the compiled classes before recompilation (in the target / classes folder maven creates). Thus, Maven only needs to recompile new or modify java files.

But there is a problem with the moved / deleted files: updating SVN removes the .java files from the source path, but Maven does not remove the compiled .class files from the target / classes. The same goes for files that are deleted from the main / resource folder. Thus, the remote / moved classes and remote resources still end up in the jar file that we deploy on our production servers, and this causes problems.

I know that we can "mvn clean" to get rid of any compiled files, but in this way we need to recompile the whole project for each assembly, which costs a lot of time.

Does anyone know a way to remove obsolete .class files and resources before or during Maven compilation?

+4
source share
3 answers

So, the remote / moved classes and remote resources still end up in the jar file that we deploy on our production servers, and this causes problems.

You really have to complete the build when creating artifacts that will be deployed to your production servers. This is not only best practice for reproducible collections (as mentioned in the Hudson Best Practices ), but more importantly, it is the only way to prevent run-time errors using multiple modules (unless you use the maven-incremental-build plugin). Imagine the following situation:

  module-parent
 | --- module-api
 `--- module-impl

The API module defines the interfaces implemented by the IMPL module (which, therefore, depends on the API module). If you change the API module by changing the method signature and not changing anything in the IMPL module, the assembly from the parent module will succeed , the IMPL will not be recompiled, and all this will work at runtime (see this discussion about this behavior). What you are doing now is really unsafe!

Does anyone know a way to remove obsolete .class files and resources before or during Maven compilation?

I don't know anything about this. And, as I said, your current practice is unsafe. You should change it, at least at the continuous integration server level, and especially for production builds.

+3
source

I do not think that's possible. Look at the javac documentation

javac determines if the class file is out of date. If the class file is outdated, javac recompiles the source file and uses the updated class file. Otherwise, javac just uses the class file. javac considers a class file to be obsolete only if it is older than the original file.

The Maven compiler plugin (or ant task) does not do more than javac does.

I highly recommend using a clean target. Not using it can cause a lot of problems, especially if you instantly deploy the artifact into production (for example, javac, relying on a file’s timestamp, is fragile, some resources can be filtered, etc.)

If you have problems with build performace, try to find other solutions - for example. divide your module into smaller submodules.

+1
source

Alexander Malfight,

If your problem is only in the integration environment, I join my mind with Pascal Tivent, cetnar,

However, your problem is still a problem in other contexts. Indeed, at the development stage, I found it very bad to do systematically in order to avoid such a problem. I think Maven should make a difference between the source and compile so as not to act like a blind when you want to compile juste. Ok Javac does not do this, but Maven is not javac. This is the javac layer. Thus, this may be his role.

0
source

All Articles