Dynamically generating java class from a java program - java

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.

Related

How can I have separate debug and release versions of gradle project that pull in different versions of the same class?

I have two versions of the same Java class (same name / methods). Since it's Java, both .java files have the same name. I want to configure gradle in such a way that I can build a "debug" version of my application that pulls in one of these files, and a "production" version of my application that pulls in the other one. How would I go about doing this?
This class has only static methods. I don't ever want to make an instance of this class. I additionally don't want to add the overhead of an if statement in each of the methods on this class to check which version I'm in.
Following #JFabianMeier's answer you could use 4 projects:
with the production version class
with the debug version class
with code that uses either of the two, parameterized according to Migrating Maven profiles ... → Example 6. Mimicking the behavior of Maven profiles in Gradle. (I'm also a Maven guy and therefore can't tell you exactly how to do it in Gradle.)
a multi-project with 1./2./3. as sub[-]projects for building all of them in one go, maybe parameterized to build just 1.+ 3. or 2.+ 3.
Have you tried creating production and debug source directories/sets? According to the docs you can use multiple directories when specifying source directories in your source set. Try dropping the different versions of your class in their respective production/debug source directories.
I haven't tested myself (not sure about the syntax), but this is based on the Gradle's Java compilation documentation.
sourceSets {
// Could also name this production
main {
java {
srcDirs ['src/main/java', 'src/prod/java']
}
}
debug {
java {
srcDirs ['src/main/java', 'src/debug/java']
}
}
}
You could do the following:
Put the class into a separate project (so generate a separate jar from it)
Then you can have two different jars, for production and debugging
Then you can pull either one or the other jar in gradle depending on a parameter.
Alternatively, you could look into template engines like Velocity which allow you to generate source code during the build depending on variables and then compile it.
Android has a neat feature called Product Flavors. It lets you swap classes at compile time effortlessly and keep your project clean.
This post is very good to get a taste of it: https://android-developers.googleblog.com/2015/12/leveraging-product-flavors-in-android.html
And here is the full documentation: https://developer.android.com/studio/build/build-variants#product-flavors

Eclipse New Java Class Wizard in VS Code

Is there a way to create Java class in VS Code similar to Eclipse New Java Class Wizard?
I would like VS Code to add package and class declarations automatically like Eclipse does.
Couldn't find relevant info in the docs and relevant functionality in plugins.
I faced a similar issue, coming from Eclipse/IDEA background, you can find it difficult to not have a feature in your java IDE to create a new classes, packages etc.
You can use the below VSCode extension : https://github.com/jiangdequan/vscode-java-saber
It is a very handy extension.It provides support/wizard for:
New: Java files(annotation/class/interface/enum/package/JSP/HTML)
Generate Getters and Setters
Copy Qualified Name
Sort Project By Name
Run Maven Goals
Generate Docs
You can try this extension.Search for vscode-java-saber in the extension search and install it.

Can I run a subset of pure Java code from an Android project via a regular Java main method?

I have some code in an Android project that parses HTML using Jsoup. It doesn't use anything Android specific, they're just static methods that take an InputStream, and return my model classes. The app uses Gradle to build itself in Android Studio.
Is there any way I can create a standard Java main method to do something like load HTML from a local file, run it through my parser, and output a JSON file (using Gson on my model class)? I'm thinking maybe I can add a new sourceSet to Gradle like a jvmCompatible set of classes? I would greatly prefer not to copy my code to a separate project.
EDIT:
I guess I didn't make this clear, but I would like the be able to run this locally on my dev machine from the command line, rather than on an Android device or emulator.
You don't necessarily need to do anything in the build file to set this up; the build file generates Java .class files, and you can feed them to Java directly from the command line. You can add a main method to any class:
package com.example.foo;
class MyClass {
...
public static void main(String [] args) {
...
}
}
The main method will be happily ignored util you invoke it via the Java command line. You can do this by setting your classpath to the intermediate build directory and telling the Java command line which class to start:
java -classpath app/build/intermediates/classes/debug/ com.example.foo.MyClass
where you pass in the path to the build/intermediates/classes/debug directory in your app module's build output, and the fully-qualified name of the class.
Note that if you're running a release build that uses ProGuard, this main method could get stripped out if it's not otherwise referenced in the code.
Make sure you don't access any Android classes or you'll get a runtime error.
As an aside, you might find it worthwhile to separate out your Java-only code into a Java-only module in the build. Among other things, it would let you use JUnit to write nice test cases for the classes within; if you're asking this question because you want to do some testing of your parser, you might find it convenient to do so within the auspices of a unit test.

How parse xml file in groovy and put it in a pojo?

Someone told me that groovy xml parser is better and easy, my question how to use groovy inside java to parse an xml file and put it in a pojo object ?
thanks.
Groovy compiler has a feature called "joint-compilation". That is used for compiling groovy project with another java project. It is defined in their site as
Joint compilation means that the Groovy compilation will parse the Groovy source files, create stubs for all of them, invoke the Java compiler to compile the stubs along with Java sources, and then continue compilation in the normal Groovy compiler way. This allows mixing of Java and Groovy files without constraint.
But the catch is as your project's codebase increases, it causes some problems with static references. If you are compiling your code using Maven or use Ant scripts then life becomes easier.
Ref Link : http://groovy.codehaus.org/The+groovyc+Ant+Task
You could also look into this link http://today.java.net/pub/a/today/2004/08/12/groovyxml.html where the user has tried a lot of options including Groovy.

How can I build a compile graph for Java files?

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.

Categories