Create Pojo at runtime and save it on Disk? - java

With reference to the following link, I have created the classes at run time, http://blog.javaforge.net/post/31913732423/howto-create-java-pojo-at-runtime-with-javassist. Now I need to view the created class that means Where will it create the class file? Is it possible to save it on disk/work space?

You can call cc.writeFile() right before or right after you call cc.toClass() to store a class file containing the bytecode of the generated class.
I don’t know of an equivalent operation to get a source file, however, you may consider the fact that you are actually generating the source code already (at least for the methods) and passing it to Javassist’s CtClass in order to be compiled.
So it’s not that hard to use the same code to generate the source code for an entire class as you only need to concatenate these methods, add field declarations and enframe it with a class body. After all, generating a source file means just writing a text file in a format that you already know very well…

The process of taking a java object and writing it to a text-like file is called serialization. The language has good built in support for this.
Oracle's documentation for these features can be found here and a tutorial here.
In general it's pretty easy to use and well understood and provides some clever features including the ability to detect if one version of a program saved the record but an incompatible version is trying to load it.
Also this stack overflow question will be useful to you.

Why would you want do do that? It's possible to create files from Pojos, then youll have to follow this tutorial:
http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/. But then you'll only write the contents of the fields to a file.

Related

Save values to file(e.g yml) in java

First of all this might be a dumb question and I searched for some days but didn't find an answer. So if there is an existing answer concerning my question, I would be grateful for a link.
I don't know if anyone of you ever coded Spigot, Paper or Bukkit, but there was a class called YamlConfiguration which had the following methods:
public FileConfiguration cfg = YamlConfiguration.loadConfiguration(file);
cfg.set(path.path2, "hello");
cfg.getInt/String/...(path.path2); (which obviously returns "hello")
cfg.save(file);
The produced file then looks like this:
path:
path2: "hello"
So you could basically save any value in those files and reuse them even if your program has been restarted.
I know have moved forward from Spigot/Paper to native Java and I'm missing something like that Yaml-thing. The only thing I found was a kind of a config file, where every time the whole file is overwritten, when I try to add values.
Can you show me a proper way of saving values to a file? (would be nice without libraries)
I'm missing sth like that Yaml-thing
SnakeYAML should have you covered. Without knowing anything about your use-case, it makes no sense to discuss its usage here since its documentation already does cover the general topics.
The only thing I found was a kind of a config file, where everytime the whole file is overwritten, when I try to add values.
Saving as YAML will always overwrite the complete file as well. Serialization does not really work with append-only. (Serialization is the term to search for when you want functionality like this, by the way.)
If you mean that previous values were deleted, that probably was because you didn't load the file's content before or some other coding error, but since you don't show your code, we can only speculate.
Can you show me a proper way of saving values to a file?
People will have quite different opinions on what would be a proper way and therefore it is not a good question to ask here. It also heavily depends on your use-case.
would be nice without libraries
So you're basically saying „previously I used a library which had a nice feature but I want to have that feature without using a library“. This stance won't get you far in today's increasingly modular software world.
For example, JAXB which offers (de)serialization from/to XML was previously part of Java SE, but has been removed as of Java SE 11 and is a separate library now.

How to find all Java method calls and given parameters in a project programmatically?

I have a multilingual web application that gets all of the translations from a single object, for example lang.getTranslation("Login") and the object is responsible for finding the translation in an xml file in the user's language.
What I'd like to do is a script / custom static analysis that outputs all the missing translations and translations that are no more used in the application. I believe I should start by programmatically finding every call to the getTranslation method and the string parameter, storing the data in a special structure and comparing it to all the translation files.
Is there a library that will allow me to do this easily? I already found Javassist but I can't use it to read the parameter values. I also tried grepping, but I'm not sure if that's a robust solution (in case there will be a call to another class that has a getTranslation method). I know Qt has a similar mechanism for finding translatable strings in the code, but that's a totally different technology..
I'm asking this because I'm quite sure there's a good existing solution for this and I don't want to reinvent the wheel.
Ok, here's how I did it. Not the optimal solution, but works for me. I created a utility program in Java to find all the method calls and compare the parameters to existing translations.
Find all classes in my project's root package using the Reflections library
Find all getTranslation method calls of the correct class in the classes using the Javassist library and create a list of them (contains: package, class, row number)
Read the appropriate .java files in the project directory from the given row until the ';' character
Extract the parameter value and add it to a list
Find the missing translations and output them
Find the redundant translations and output them
It took me a while to do this, but at least I now have a reusable utility to keep the translation files up to date.

#Generated Annotation, how do we use it?

I recently read an article talking about the Java annotations, and on this latter comes the #Generated one. They say that it is used for automatically generate code.
Could someone explain me that in further with a little example ?
All what i found on the net was some pro question or something beyond what i was looking for.
As per the JavaDoc:
The Generated annoation is used to mark source code that has been generated. It can also be used to differentiate user written code from generated code in a single file.
#Generated is used by meta-programs such as Auto/Value which generate source code so you don't have to manually write it. If you're writing a .java file by hand (which is normally what one does), don't use #Generated.
Fox example are good and bad policies on the border between generated and written code. Way of thinking is (i belive) different in compiled (static) languages, nad interpreted / dynamic.
Worst is to modify generated code (will be lost at next generation, or next generation is then prohibited)
Usually is accepted to derive (manual) class from generated, or generate class what extends core "manual" class.
If someone know good policies in this area, please comment.
Some code linters use the annotation to skip generated code. For example, it doesn't make sense to calculate cyclomatic complexity on generated code.

DLLs for a dynamic Java program?

I'm currently working on a Java project where I have a set of data which I wish to output in several custom formats. I have a class for each format, which takes the raw data and converts it accordingly. However, to begin with I am only implementing two or three of these formats, but wish to allow more formats to be added at a later date without having to do a massive rebuild of the application.
My idea was to create a DLL for each of the format classes, and have my application pass the data to be converted to each of these. This way, I can create a DLL later on and have my main application accessing it. (I would gladly listen to any alternative ways of doing this, as someone who has done this in C++/C# before this felt like the logical solution but it may not be applicable to Java)
My problem is that I have absolutely no idea how to do this - in C++/C# I could write this in a few lines of code but I'm not sure how it works with Java. At the risk of asking a terribly vague question, how can I do this?
Answers are greatly appreciated and cookies and tea will be offered. :)
Thanks in advance,
M
Edit: Sorry, just to add: I am also unsure how to create the DLL, which must be in Java for this project, to be read in the first place. Thanks. :)
Rather than using a DLL per se, it seems like what is wanted is a plugin architecture of some sort.
One reason why I wouldn't recommend using a DLL unless it is necessary is that linking Java code with native code will require using the Java Native Interface (JNI) which would probably require more effort than a pure Java solution.
One relatively simple way to do so is to use the reflection capabilities of Java.
From the information given, I would probably go along the lines of the following:
Define an interface for the output format.
Create a Java class implementing the interface.
Have the class available from the classpath.
Dynamically load the class using reflection. (Using the Class.newInstance method can instantiate objects from class files loaded by the ClassLoader.)
With these steps, it would be possible to implement a simplistic plugin which wouldn't require a full rebuild when support for a new format is required.
Step 1: Define the interface
Let's say we end up with an interface like the following:
public interface Outputter {
public void write(Data d);
}
Step 2: Make an implementation class
Then, we'll make an implementation class.
public class TextOutputter {
public void write(Data d) {
// ... output data to text
}
}
Then, compiling the above, we'll end up with a class file called TextOutputter.class.
Step 3: Make the class available from the classpath
When running the main application, we'll need to have the above TextOutputter.class in the classpath. Normally, one would tell the JVM a list of places to consider as the classpath, and that should include the above class file.
Once that is done, we should be able to load the above class using reflection.
Step 4: Dynamically load the class using reflection
Now, when we actually want to load the above class, we'd do something like the following:
// Note: We load the class by specifying the fully-qualified class name!
Class<?> clazz = Class.forName("TextOutputter");
// Then, we instantiate the class.
// Note that the following method will call the no-argument constructor.
Outputter outputter = clazz.newInstance();
// Now, we can give data to the TextOutputter object that we loaded dynamically.
outputter.write(...);
The Class.forName method is used to attempt to find the TextOutputter class from the default ClassLoader. Once we obtain the class as a Class representation, we can then instantiate an object of that class.
Instantiating the object can be performed by using the Class.newInstance method. If something other than the no-argument constructor should be used, the Constructor of the class would have to be obtained proceed to instantiate the object from there.
The object instantiates via reflection is then placed into a Outputter variable, so the write method can be called on the TextOutputter.
Adding more formats would entail the above process, but changing the fully-qualified class name (e.g. for String, the FQCN is java.lang.String) is all that is needed to load up a different class.
In a nutshell, that's what it will take to dynamically load class files and use it from your application.
(Just as a side note, I did not actually compile the above code, so there may be some errors here and there, but I hope I could illustrate the process it will take.)
I've made such things.
i created an open java based plugin architecture POJO based,that even did reload on the fly of updated plugin classes.
JNI is the interface for dealing with native code.
The only technical part was to rewrite a classloader that enabled DLL reloading dynamically at runtime.
But if you do only make "offline" updates, no such things are needed.
You can load a new DLL at any time with System.loadLibrary(). However you may need to load a java class for it to bind to.
You might find using an OSGi container helpful as this supports both load and unloading of modules (including shared libraries)
I would suggest using karaf with iPOJO but there are many others.
If you want write native codes (compiled to a DLL) to be used in java, you want to look at Java Native Interface (JNI).
Update you can use System.loadLibrary(String libName) (if you know the library name and the library path is set) or System.load(String filename) (library filename) to load library (DLL) in java.
I think you can ignore the JNI path. I have the impression you're using the term dll for lack of a better word, you don't really need a dll.
You could do the same thing in Java, but you'd put your filters in jar files instead of dll.
Define an interface for the file format filters to implement
Put each implementation into a jar, in a specific folder (like 'filters')
At one point in the app, iterate over the folder, generate classloader for the jars
Use reflection to find all implementations of your interface, and create a class for each
Call the methods to do their job
That's basically it.
Java SE 6 introduces the ServiceLoader class:
http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
If you want a proper modular approach consider the NetBeans Platform (especially if it is a desktop application) or OSGi.

How do I include the text of a file in my Java code?

It seems that Java is not set up to do what I have previously done in C++ (no big surprise there). I've got a set of rules that are generated from another application (a series of if-then checks). These rules change from time to time, so in C++ I would do this:
double variableForRules=1;
bool condition=false;
#include "rules.out";
if(condition) //do something
Essentially the if-then checks in rules.out would use the "variableForRules" (and several other variables) to decide whether condition should be set to true. If it gets set to true after the eval of the rules, the program does something.
Is there a similar way to do this in Java? Or is my only option to have rules.out actually be an entire class that needs to be instantiated, etc.?
Thanks!
Since you're autogenerating that rules.out, you could autogenerate your Java function as well. Hopefully it's not too painful to add that functionality.
Since there is no preprocessor in Java, you can't do this. Like you said, you have to implement your logic inside a class.
Maybe you could use scripting for that. You could take a look at the Java Scripting Programmer's guide.
In Java, it would be common for the other application to save the rules into an .xml or .properties file, and then have Java read in that file.
rules.out actually has to be an entire class that needs to be instantiated for code to be executed.
Since rules.out is generated by third-party application, best thing would be to write your own CppToJavaTransformer that reads file rules.out as input and generates Rules.java. This assumes rules.out is available before compile time and Rules.java will be used at compile time. Drawback of this is that there is an extra transformation required.
Alternately you can write code that interprets rules.out and execute required instructions using introspection. This is hard way but rules.out can be changed at runtime as well.
Even if could include the rules file it would be of no help. Your rule are dynamic as you said. Looks like you java code needs to change for a different scenario.
You could try using reflection (See: Creating New Objects and Invoking Methods by Name)
First generate a Rules.java in the manner in which you currently build rules.out and compile it.
Then load the class file into your app at runtime in the manner in which JDBC drivers were traditionally loaded.
Class clazz = Class.forName("com.mydomain.Rules");
If your app runs for long periods of time (longer then the lifetime of a single Rules.class file) then you would have to create your own ClassLoader in order to swap out the underlying class during a single runtime.

Categories