How can I build a compile graph for Java files? - java

I have a large number of classes in a project, and I would like to compile all of them from a script. The thing is, the classes should be compiled in a certain order, for example: I have a class named A which depends on a class named B. Let's say class B depends on a class named C. In order for me to compile class A, I would have to compile first B and C.
Is there some tool I could use to establish the compile order of the classes, so that I don't have to parse each class and determine this myself? I would preffer that the tool can save a file with the order of the files to be compiled, so that I could parse that from my script.
Thanks !

If you compile all of them at the same time (in the same javac invocation), you do not need to do anything of the sort you are describing. javac is smart enough to compile all files you give to it at the same time, so it doesn't have any problem with out-of-order compilation.

The Java compiler (Javac) already builds up a dependency list of all the class files you need to compile. The real dependency here is between packages - not individual java files in the same package (this is automatically taken care of by the compiler).
Use a tool like Ant or Maven to specify and compile all the files in various packages and produce your final distribution.
If you are using an IDE like NetBeans, it automatically does this for you. Alternatively, if use a tool like JDepend

These kinds of DAG ordering problems are usually solved with topological sorting. See Wikipedia for a description. I don't know if there is a tool such as the one you are looking for, but implementing it yourself is should not be that difficult.

Related

How Java compilation works?

I have a question about java compilation or sequence of java file compilation.
Question - I have a small object oriented program where I have three classes. I wrote java code for the biggest one where I am creating the objects for other two classes and invoking the methods from other two classes. other two classes are very small. When I compiled the first class file (without writing other two class files), I got few compilation error messages. Then I wrote both new class files (but I didn't compile them, only .java files), my first class file compiled fine.
--So I want to understand, do I need to compile all the Java files to get all object references in those classes working or just writing java files is fine to compile any of these?
If you compile the one that refers to all the others, they will be compiled automatically as soon as Compiler encounters them in your code.
I would use a build system like maven, ant or your IDEs build system. This means you don't need to worry about these issues.
In answer to your question; it depends. You often don't need to compile everything, javac can compile more than one source file at once, sometimes you have to rebuild dependencies.

JavaCompiler classPath

I try to use JavaCompiler to compile source code.
class A{int i;};
class B extends A{i = 5;};
The problem is even if they are in the same folder, When compiling class B, JavaCompiler still can't find Class A.
So, I am wondering the problem is I didn't add the path of the folder to classPath.
I don't know how to do it in java code, So didn't give it a shot.
Thanks for any help.
You need to set the class path for the compile task.
Have a look at the answer over here:
How to set classpath when I use javax.tools.JavaCompiler compile the source?
another point of view would be to generate directly the bytecode using one of the famous tools for such task like ASM, JavaAssist, SERP or any other one.....
It could be a very good way to avoid :
- path problems
- to have a finer control on the process (if you have javac errors you will be obliged to parse the stream to raise thme into your application)
- improve the whole process performance
But it adds some complexity...
Like often it's a trade off
extend the classpath to the current directoy.
You can do that via the -classpath option or the CLASSPATH variable.
-claspath=.
or
CLASSPATH=.

Dynamically generating java class from a java program

At the build(compile) time of my project I need to do code-generation for a java class. The generated java class is a java bean class with a set of getters and setters. At the build time I am getting the name of the class and names of variables. So what I need to do is dynamically generate the java bean from the information which I have.
eg. At the compile time I am getting following data.
class-name=Test
variable-name=aaa
So the generate class should look like following.
public class Test {
public String aaa;
public void setVar(String str) {
this.aaa = str;
}
public String getVar(){
return this.aaa;
}
}
When I searched for a tool that I can use, I found Arch4j [1] interesting but the problem with that is it is not compatible with Apache 2.0 license. I am looking for a project/tool that is compatible with Apache 2.0 license.
I would appreciate if someone can give me some insight on how I can do this.
[1] - http://arch4j.sourceforge.net/components/generator/index.html
Why not just generate the .java file during your build, using a custom ant task or Maven plugin? This seems like a rather easy task which doesn't need any complex library. You could even use a template file with placeholders for the class name and the field name, and generate the real .java file using a replace task.
JET from Eclipse can be used:
http://eclipse.org/articles/Article-JET/jet_tutorial1.html
It can be called by ant: http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jet.doc/references/ant/antTasks.xhtml
And I think from maven: http://mvnrepository.com/artifact/org.eclipse/jet/0.8.0-v20070605
Take a look at javax.tools package. You can create and load a dynamically generated class only with that package.
Just bear in mind you need the JDK available and that's not re-distributable so your customer would need to downloaded it separately ( just like you do in any IDE today )
http://download.oracle.com/javase/6/docs/api/javax/tools/package-summary.html
For instance, you can invoke the java compiler programatically with:
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html
And you can load it with URLClassLoader
Odd suggestion, but it seems like you want to generate beans. Why not use something like apache common's DynaBean? They allow you to create beans at run time. Here is an example of using DynaBean.
Of course this is at run time and not compile time. For compile time, I would recommend using an ant task to compile your source and add a dependency for compile on generation of your classes. You can handle the classes generation by writing a small java application that uses velocity as the java class template's engine.
So your ant task on compile first calls a small java program that generates the java class files using velocity template (delete the old files in ant if needed). Then compile as normal.

How can I generate list of classes in order of dependency?

I'm doing a build script for a Java application to run inside the Oracle JVM. In order to import the 50-odd classes, it appears I need to bring them in in order, so any dependencies are present before compilation.
For each class, I'm running 'create or replace and compile java source {className} as {classPath}' for each file. Doing this gives me a compilation error, as the required class(es) are not imported.
How can I generate a list of the classes, in dependency order - that is, as you go down the list, the class's dependencies are listed above. I would prefer to do this as an Ant task.
Also if you have a better idea of how to get these classes imported, I'd love to hear your ideas.
I can't imagine why you'd need to do this, but if you really need to do this, I wonder if hacking a little classloader that prints out each class as it loads and load your app from there would give you a dependency graph?
Compile the classes in the filesystem using the Ant task javac. Use the task depend if more rigorous dependency checking is needed. Use the loadjava tool to load the .class and .java files into the database in arbitrary order.
In order to import the 50-odd classes, it appears I need to bring them in in order so any dependencies are present before compilation.
I have never had to do such a thing simply to compile Java.
This is what Ant was born for. I'd recommend just doing this with Ant. Set the <classpath> and you'll have no trouble.
Brute force method: put the 50 CREATEs in a batch file and execute it until no errors are found. Create the loop in a shell script. Of course it will never end if there are errors in the sources, but I'm assuming they are ok.
Can you not load in a jar file? Why does it have to be individual classes?

Modern equivalent of javadeps?

I am looking for a replacement for javadeps, which I used to use to generate sections of a Makefile to specify which classes depended on which source files.
Unfortunately javadeps itself has not been updated in a while, and cannot parse generic types or static imports.
The closest thing I've found so far is Dependency Finder. It almost does what I need but does not match non-public classes to their source files (as the source filename does not match the class name.) My current project has an interface whose only client is an inner class of a package-private class, so this is a significant problem.
Alternatively if you are not aware of a tool that does this, how do you do incremental compilation in large Java projects using command-line tools? Do you compile a whole package at a time instead?
Notes:
javadeps is not to be confused with jdepend, which is for a very different purpose.
This question is a rewrite of "Tool to infer dependencies for a java project" which seemed to be misunderstood by 2 out of 3 responders.
I use the <depend> task in ant, which is ok, but not 100% trustworthy. Supposedly JavaMake can do this dependency analysis, but it seems to be rarely updated and the download page is only sometimes available.

Categories