I was just curious to know this, when i give mvn install without doing 'clean', maven compiles only the modified java files. How does maven identify a java file is modified or not? I believe it is not using the last modified property of the file.
Reason for my belief: I had a module, after merging a change from svn, i gave mvn install and it didn't compile the modified file and when i looked at the change i saw that 'long' were modified to 'Long' in getters and setters.
So i just want to know how maven identifies if a java file has changed or not?
(P.S I'm using Apache Maven 3.0.3, if that matters)
I believe the Maven compiler plugin uses last modified dates on the source and class files to determine whether recompilation is necessary.
The compiler website is rather short on information, but the compiler:compile goal page has information on the following attribute, which finely tunes the staleness calculations: http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#staleMillis. That's about the only official statement regarding staleness.
Without knowing much about maven, I can tell you that generally speaking, "make"-like tools use the "last changed" timestamp, which would explain the issue you had with svn ( see Wikipedia on Subversion's weaknesses.
Robert Scholte's comment at https://issues.apache.org/jira/browse/MCOMPILER-205 explains the process. It depends on the "useIncrementalCompilation" option of the "maven-compiler-plugin" (and on the version of it btw, I've only managed to have "useIncrementalCompilation" work with 3.1, not 3.0):
I see there's some confusion, so something needs to be changed, maybe
improving documentation is good enough. Looking at the code, you'll
see that non-incremental will only look at changed sourcefiles.
Incremental will also verifies if dependencies have changed and if
files have been added or removed. If it has changed, it'll remove the
complete classes-directory. The reason is that the default java
compiler is quite fast, likely much faster than analyzing per file
what to do with it. IIUC the eclipse compiler is a real incremental
compiler, so we could decide that based that based on the used
compiler not to drop the classes directory.
Related
One of contractors at my current project has a weird habit to deploy fixes to the production as jars and not to push fixed code to the project's git repo. There are tens of maven projects which packs to a jars
Is there any practical way to detect and plot all discrepancies between compiled jars from production and code from a repo? Currently I can decompile a jar with IDEA and compare result with code. Decompiled code is not identical to original by design so it takes ages and possibly leads to errors.
To detect changed classes, I would compile the code in the codebase and make a class by class binary comparison between the class files you just created and the ones in production. This can be easily automated.
But the real solution is of course: Your company should have a rule that only builds from the build server (Jenkins, Bamboo, whatever) that draw from the official git repo can go to production. No exceptions.
The technical solution to your problem is called Reproducible_builds.
But i donot think that you need a technical solution for the "blaming-game" but an organisational solution like overwrite the production build with your own jar compilation and refuse to pay the contractor if the problem re-appears
In the coming version of Apache Netbeans, there's a new feature that looks impressive but I don't understand what it's all about.
https://github.com/apache/incubator-netbeans/pull/918
What is an expanded JDK? How can it be useful?
Expanded must be a synonym for exploded. This is hinted by the fact that this pull request is about using freshly compiled JDKs.
So, what is an exploded JDK then? This is explained at https://github.com/openjdk/jdk/blob/master/doc/building.md#running-make:
[An exploded JDK] is a minimal (or roughly minimal) set of compiled
output needed for a developer to
actually execute the newly built JDK. The idea is that in an
incremental development fashion, when doing a normal make, you should
only spend time recompiling what's changed (making it purely
incremental) and only do the work that's needed to actually run and
test your code.
The easy guess is that the terms expanded and exploded are used because, in this case, the modules are still available as a raw set of folders and class files instead of neatly compressed unique files. This last stage of neat packaging is a waste of time when you continually modify the JDK itself. So, it's skipped over while testing the JDK.
I have found this nowhere on SO or in the documentation, but I would like to create a single jar containing both the binaries and the source code. My project is a mix of Scala and Java, if it adds anything to the question.
I've found this Github project which seems interesting and might enable me to do this, but I could not manage to set it up despite of the instructions. I think it is anyway a bit overkill for my use case. Any idea ?
I want to rebuild JDK1.6 after some changes in currency.java in the java.util package. so how can I do it? is there any compiler or builder to make a custom version of JDK?
I try $ javac src/java/util/currency.java but it did not work.
You should not build the whole JDK. Only thing you need is compile your class, put it into a .jar and place it in endorsed folder of a JRE.
I found these build instructions for OpenJDK 6 in the source code repository:
OpenJDK 6 Build README
UPDATE - revisiting this after a couple of years, I came across the following useful blog entry that has links to "Build README" files for a number of Java versions:
https://blogs.oracle.com/kto/entry/jdk_build_readme_collection
Lets hope it stays there, and stays current!
But yea ... if you have just changed one class, then the "endorsed directory" approach is a better idea; see #kan's answer.
Finally, it is generally a bad idea / undesirable to modify the standard class libraries to make your application work:
Your code is immediately non-portable. It will only work on your private flavor of Java.
Each time you upgrade your Java version you have to resync the sources and rebuild. (The "endorsed" approach is simpler, but you still have work to do on each Java update.)
There might be legal issues with redistribution of your modified Java. Talk to an IP lawyer ...
I'm looking into a solution that displays the subversion revision number and last modification date in my application (written in GWT, therefore reflection is not available). Encode the revision in subversion keyword doesn't work as it applies only to the current file. Is there a better solution using annotation? (e.g., a separate class that's executed during the compile time, grab the latest revision # on the whole project and inject the revision and last modification date to the source code)
I kn
#SvnRevision("$Id$")
public class Foo {
}
Then your classes are all annotated with their version. You need to make sure the annotation is defined as having runtime retention so it can be queried at runtime.
EDIT
OK, since SVN doesn't have that feature, I'd write a Maven plugin to emulate it. Maven has access to the SCM information for every file so during the build phase you could have it do the same keyword expansion.
Annotations are not really designed for this. It's easiest to do it as part of the build.
Using Ant you can generate a file that contains the version information, include it in your application's JAR, load it as a resource on the server, and serve it out to the browser-side code by RPC. Ant can also do string replacement in files as it copies them, which you can use to include the version number in your application's HTML files (no need for RPC then).
No idea about Maven, but I would be very surprised if it could not do the same kind of thing.
Subversion still has the $Id$ feature, but it needs to be enabled explicitly using the svn:keywords property on the files (set it to 'Id').
See also: http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html
So the idea of Jherico above with #SvnRevision would work.