Reputation: 70213
Is there a way to detect specifically which JDK was used to compile a given JAR / class file?
I am not asking for the Java version (1.4, 1.6, 1.8...).
I am asking about whether something was compiled with e.g. OpenJDK, or some other JDK. Do they leave some kind of "vendor tag" somewhere?
Upvotes: 0
Views: 767
Reputation: 298103
In principle, a compiler could leave information about itself in a class file, as class files are extensible containers, build from named attributes.
However, the class file format is well documented and there are independent open source libraries and tools, like ASM, BCEL, or Javassist, which can be used to inspect compiled class files and their attributes, to find out, that no such additional attributes exist in class files created by the common compilers like javac
or ecj
.
Still, there are some differences in the code generated, e.g. by javac
or ecj
, which allows to find out which of these compilers has been used. For example, this answer discusses the code generated by javac
for “try-with-resource” statements, which differs significantly from the code generated by ecj
.
However, you can not tell javac
of OpenJDK and Oracle’s commercial JDK apart, simply because it’s the same compiler. I just verified this by comparing trees of compiled nontrivial class files, generated by OpenJDK and Oracle’s JDK. Not a single bit difference.
The differences between these two JDKs are the monitoring and profiling tools. Of course, you can not find out whether these tools have been used during an application development, but that’s nothing to worry anyway, as Oracle’s licence allows using their JDK for development. The use of these management tools in a production environment, is what is supposed to cost money.
Upvotes: 1
Reputation: 1176
Default manifest file contains build info. https://docs.oracle.com/javase/tutorial/deployment/jar/defman.html
META-INF/MANIFEST.MF
Manifest-Version: 1.0
JDK version and vendor
Created-By: 1.7.0_06 (Oracle Corporation)
Upvotes: 0
Reputation: 99
Answer to the question first: By default, to my knowledge, no it does not leave an indicator as to which JDK was used to compile a jar/class file.
That being said...
You can modify/add to your own compiled jar's MANIFEST file and include your own attributes (in this case the JDK you used) if you use a build tool such as Maven.
Here's a few links to get started that outline the process of adding attributes and values to the manifest file using the Maven Jar Plugin and I've copied/pasted the post as quoted text from the one that I think (just an opinion) would be the "easiest" to understand/use: Using the Apache Maven Jar Plugin
The answer was kinda obvious in hindsight. Spring-Boot's maven plugin rewrites the original manifest file so using the maven jar plugin the manifest can be written as normal. Like this:
org.springframework.boot spring-boot-maven-plugin
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestEntries> <splashscreen-image>${image.name}</splashscreen-image> </manifestEntries> </archive> </configuration> </plugin> </plugins> </build>
Also here's a few links to Apache's documentation and site which cover similar things, but might offer a bit more detail.
Link To Apache's Documentation example/explanation of Manifest Entries
Link To Apache's "cookbook" for adding build time to the manifest
Hope this helps!
Upvotes: 1