Compiled Java compiler in JAR form? - java

I have an application which requires compiling a .java file into a .class file within the application. Ideally, I'd like to have a JAR that I could use its api to compile by giving two arguments: the name of the file to be compiled and the directory to store the .class file. My application will use the Java compiler, which will be packaged and shipped with the software.
I actually have a small java compiler like I describe in JAR form, but it only has a subset of what java 7.0 has.
Is the java compiler available in Jar form like this?

the compiler is in tools.jar.
refer to http://docs.oracle.com/javase/6/docs/api/javax/tools/package-summary.html

Java Compiler API (JSR 199) was created for this purpose, you create a compiler instance like this:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
Here is a good educational tutorial on Generating Java classes dynamically
and here is a related question with example code

Related

Is every `.class` file generated by `scalac` also obtainable via `javac`?

Is it true that for every .class file that was created by the Scala compiler scalac, it is theoretically possible to define a .java file that gets compiled, by javac, to exactly this same .class file?
If not, can you give one or more non-trivial examples of constructions in Scala that get compiled to JVM bytecode for which there is no corresponding Java construction?
Is it true that for every .class file that was created by the Scala compiler scalac, it is theoretically possible to define a .java file that gets compiled, by javac, to exactly this same .class file?
No.
If not, can you give one or more examples of constructions in Scala that get compiled to JVM bytecode for which there is no corresponding Java construction?
class `class`
class is a legal name for a class in Scala, but not in Java, so it is impossible to get the Java compiler to generate a bytecode file with a class named class.
Scala being compiled inserts ScalaSig (scala signatures) into bytecode, i.e. Scala-specific kind of comments. These "comments" will be absent in class files compiled from Java sources.
Java being compiled can generate annotations (#) visible with Java reflection at runtime while Scala can't. Scala can only generate annotations visible at sources and class files but not at runtime with Java reflection although they can be visible at runtime with Scala reflection (because some info is written to ScalaSigs).

JVM language interoperability

Recently I've been writing a compiler for a JVM programming language and I've realised a problem.
I would like to access a Java method from my programming language and also allow a Java method to access a method in my language. The problem is that I need to know the Java methods signature to call it in the bytecode I generate and vice versa.
I've been trying to think of any methods for how Scala does this. Here are my thoughts.
Scala accesses the .java files on the class path and parses them, extracting the method signatures from there.
.java files are compiled to .class files. The Java ASM library is then used to access the .class files and get the method signatures. The problem with this method is that the .java files must be compiled first.
.java files are loaded dynamically using reflection. The problem with this is I believe that the JVM doesn't allow for loading classes that are outside of the compilers class path.
Looking into Scala it works well with other JVM languages but I can't find information on exactly how it does it.
How does Scala get method signatures of other JVM language methods?
I think you are confusing class path and source path: there are no .java or .scala files on the class path, there are .class files (possibly inside .jars). So for dependencies (on the class path), you don't need to do anything special. They can have their own dependencies on your language, including previous versions of your project, but they are already compiled by definition.
Now, for mixed projects, where you have Java and your language on the source path, scalac does parse Java with its own parser (i.e. your option 1).
The problem with option 3 is not that "the JVM doesn't allow for loading classes that are outside of the compilers class path", but that reflection also only works on classes, not on source files.

Dynamic linking in C/C++ (dll) vs JAVA (JAR)

I am new to java programming.
Basically when we work in c/c++ programming we create dll files using .h and .c files,where .h file contains declarations and .c file contains definitions of those classes, functions.
when we want to use those functionalities of created .dll file in other project, we include .h in preprocessor declaration to tell compiler about declarations of variables,functions and we provide respective dll file path during compilation so that at linker stage it communicates with dll.
Here is my question how do they manage this in java programming because it doesn't contain any header files. it has only .java files where these files are combined and created JAR file.when i want to use this jar file in another project we use "package" or "import" keyword but when it says import total file will be imported with logic and how do linker manage at compilation step??
how do they manage this in java programming because it doesn't contain any header files.
It manages this by placing all the information it needs for compiling against the class and at runtime (and possibly debugging) in the .class file so there is no need for additional information.
Often the source and javadoc are placed in JARs as well (sometimes the same JAR)
when i want to use this jar file in another project we use "package" or "import" keyword
You don't have to. This is just a short hand. You can use full package.ClassName and there is no need for an import. Note: this doesn't import any code or data, just allow you to use a shorter name for the class.
e.g. there is no difference between
java.util.Date date = new java.util.Date();
and
import java.util.Date;
Date date = new Date(); // don't need to specify the full package name.
when it says import total file will be imported with logic
There is no way, nor no need to do this. There is nothing like #include for example, and inlining only occurs at runtime, not compile time (except for constants known at compile time)
how do linker manage at compilation step
The linking and compiling to native code is performed at runtime. All the javac compiler does is check the validity of your code and generate byte code for the JVM to read.
Modern languages, Java (& C#) do not make a distinction between declaration and definition, so the concept of .H file is gone in these languages.
In many aspects (new languages) the dualism compile-time vs runtime is lost (mainly because they have strong reflection). Java Classes or JARs (or C# assemblies) have information required to compile (alike declarations). Java environment don't require special 'files for compilation'. The same JAR is 'compile file' and 'runtime binary dll'
Typical C thinking with .H, .C, .LIB files goes to niche (IMHO - I'm old C programmer and I feel good with new languages)

Where in the java compiler source code does the compiler look for .java files to compile

I am currently working on a project which will require knowledge of the java compiler source code. I have never worked on a project this large before and I need some help.
I would like to find out in which part of the source code does the compiler actually look for and find a .java file to compile.
I have looked at the java compiler source code which is very large. I have found that the parsing and the code generation phases are independent of each other but I don't know where javac asks for a .java file and where that file is given to it.
Any help on this is greatly appreciated.
The javax.tools package provides a Java-based interface to the Java compiler from your JDK (JavaCompiler).
JavaCompiler uses a JavaFileManager's methods to find and access the source files to be compiled. The StandardFileManager (used by default) offers a getJavaFileObjectsFromFiles() method that provides iteration over all java files found in a given root.
The links above will take you to the JDK sources (in case you actually want to roll your own version after modifying those sources, read this); and to the JavaDoc for StandardFileManager.

How to create a runnable jar file from source code programmatically?

I need to create runnable .jar file programmatically from a string. My decision is to create a .class file from string and add it to the .jar using JarOutputStream.
What API must I use to create the .class file?
Are there any other solutions to create a .jar from the source code?
In order to do that, you can use the Java Compiler API.
There is this excellent tutorial that can walk you through.
To compile code, you need a compiler. You can either use the SunOracle compiler or the Eclipse compiler. Calling the compiler API (both have documented APIs) will produce a .class file in a temporary location. You can then make a jar.
For an example of this sort of thing, start with, for example, the Maven Compiler Plugin, which is a Java module which uses the compiler API. You'll have to find your way into the Plexus compiler module.

Categories