简体   繁体   中英

Can I detect which JDK (not version!) was used to compile a JAR / .class?

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 eg OpenJDK, or some other JDK. Do they leave some kind of "vendor tag" somewhere?

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!

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, eg 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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM