What is the difference between using javac and javax.tools.JavaCompiler? - java

Maven Compiler Plugin documentation states:
The Compiler Plugin is used to compile the sources of your project. Since 3.0, the default compiler is javax.tools.JavaCompiler (if you are using java 1.6) and is used to compile Java sources. If you want to force the plugin using javac, you must configure the plugin option forceJavacCompilerUse
And indeed when forceJavacCompilerUse is not specified in our build there are some build errors, for example when the code references the com.sun. packages (legacy, we know that its a bad idea...)
What are other differences between these two compile modes in general and with maven? Are there any output differences that one should know?

javac (as "java compiler") is an executable, which could be theoretically even a platform-dependent executable or a script. This is called to compile a .java to a .class.
On windows is its name javac.exe, and it is normally somewhere below C:\Program Files*\jdk*\bin.
This compiler was developed in java as well. That means, if we start this .exe, a new java virtual machine need to be started to run it. This is slow.
But, because it was written in Java, there is a much faster alternative to it: from our already running jvm, we simply import its main class (f.e. javax.tools.JavaCompiler or such) and call this. This doesn't need to start an unneeded jvm. That is what maven does. Simply 10 yrs was them enough to make this correctly. :-)
Of course it has some fallbacks as well. To most probable cause is that in the case of the internal compiler it needs to run from the same jvm and in the same namespace as the maven core. Also specifying an alternate jvm is impossible, and there could be some side effects as well resulting from the namespace collisions. But they are very improbable, because both of them is well-designed software.

Related

Why is Scala usually installed for each of your Scala projects rather than being installed system-wide?

I was wondering why https://www.scala-lang.org/download/ says
Scala is unusual because it is usually installed for each of your Scala projects rather than being installed system-wide.
Why is it not the case for Java? Can this way work for Java projects?
Thanks.
If you use SBT, on the basis of scalaVersion specified in project's build.sbt, it will treat Scala like other regular library dependencies and download them under
.ivy2/cache/org.scala-lang/scala-compiler
.ivy2/cache/org.scala-lang/scala-library
.ivy2/cache/org.scala-lang/scala-reflect
similarly to regular library, say, cats
libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0"
which would end up under
.ivy2/cache/org.typelevel/cats-core_2.13
We can also have system-wide installation of Scala under, say /usr/local/bin, however SBT will not use that and will read from ~/.ivy2/
One thing is that, when talking about Java we need to distinguish JRE and JDK.
The JRE has JVM, so it's only the runtime platform for Java bytecode, JDK has compiler and other development tools.
Scala instalation already comes with compiler, interpreter, etc.
Both can run their own compiled code, but Java needs additional jars on classpath to run Scala programs (nicely described here).
Another and probably the main reason behind having separate installation of Scala for each project is that Scala is not fully compatible between its versions, i.e. particular version of Scala needs specific version of libraries.
(where Java is backward compatible)

Why Eclipse doesn't have path to java compiler?

As I know, java source code is compiled into class files by the java compiler (javac.exe); then these class files are put into JVM to interpret using java.exe
But Eclipse is only using javaw.exe. So, I think javaw.exe is equivalent to javac + java
But some references say javaw.exe nearly equivalent java.exe. thus Eclipse only has the interpreter progress. Compiler process takes place where, how?
How should I understand this?
Eclipse does not compile files using javac. It has its own, independent implementation of a Java compiler, complete with its own set of error messages—and bugs.
Eclipse still needs access to all the standard library classes against which it compiles Java code.
The Java runtime which runs the Eclipse IDE process is not related to the JDK used to compile the code against. For all that matters, Eclipse could be a native application written in C++ and that wouldn't stop it from being able to compile Java.

run with difference jar?

I am from .net world. I remember .net will immediately complain if you build with one dll but supply a different dll at run time.
I am now adding some hadoop reference to my project and find the following article.
http://answers.mapr.com/questions/364/maven-repository-for-mapr-jar-files
I just don't understand how this happens.
Java can build with one jar but run with a different jar?
Thanks
yes. this is often the case with APIs (you compile the API, but at runtime you may run with a newer version of the API which may be included with the implementation). everything will work out fine as long as the classes/method prototypes referenced in your compiled code are unchanged from the jar you compiled against.
For a specific definition of compatibility, see binary compatibility (thanks to #MiserableVariable for the link).

Can a Java program be analyzed to strip it down to essential packages as well as the JRE?

Is there some tool that can analyze a Java program and strip down the Java runtime and the program itself to the essentials only? Can a tool analyze the programs dependencies and create a custom JRE just with the required libraries?
You are looking for ProGuard. They claim it also works on rt.jar from the JRE.
You could try http://proguard.sourceforge.net/. It allows you removed unused classes and methods. This can backfire if you're using things like Class.forName("myclass"), so be sure to test a lot. You could try to run the shrinker against the JVM libraries, but that seems risky.

Java compilation with two versions of Eclipse

I've got an old project in Eclipse 2.1 and compiled with a JDK 1.4.2_12. I want to upgrade the version of Eclipse to Eclipse Galileo.
I've imported my project and set the compilation level to 1.4 and I've also updated my build path to use the correct JDK.
The problem is that when I compare the compiled files in the classes folder in the two versions of Eclipse, the MD5 checksum are different.
Should I be worried about that fact or this is normal?
This is normal. The Eclipse compiler is free to change the class file structure as long as it conforms to the 1.4 JVM specification. If a 1.4 JVM will load and run the class, I see no issue.
For truly pedantic cases, you should do your final builds with a JDK which matches the JRE, and not the Eclipse compiler.
As long as the program is working i dont think that you need to worry!!!
As MD5 would be unique for each entity, and it represents the Hash value.
It's normal, but I would make sure about doing a complete rebuild anyway (possibly erasing any existing class files). My experience with Eclipse is that the incremental builder doesn't react well to unexpected situations.

Categories

Resources