Are there any tool that will compile a java .properties file to a class which I can use in Java EE (tomcat) application? Similar to android where the eclipse plugin produces a static R.strings class.
I found this article:
http://www.techhui.com/profiles/blogs/localization-in-gwt-using
But it is dependant on GWT. Any help appreciated.
I have never heard about such tool. GWT has a great deferred-binding based technique but it is not the thing you are looking for. However I think it is possible to implement a basic code generator for such tasks.
But the answer to your question is: as far as I know there isn't.
To internationalize applications I implemented a Message Compiler, which creates the resource bundle files and constant definitions as Java enums or static final strings for the keys from one single source file. So the constants can be used in the Java source code, which is a much safer way than to use plain strings. In this case you also get a compile time error, when you use a key constant, that doesn't exist. The message compiler cannot only be used for Java. It creates also resource files and constants for Objective-C or Swift and can be extended for other programming environments.
What about ResourceBundle?
// refers to "src/config.properties"
ResourceBundle config = ResourceBundle.getBundle("config");
String property1 = config.getString("property1");
I think one could write a very simple grammar for properties files using ANTLR in a custom a maven plugin (or Ant task) that just generates the Java source before the compilation step.
How about storing your properties in a JSON file. The JSON object stored in the file should map to a Java class, use Jackson mapper to deserialize. With Jackson you can enforce that all fields must be non-null on deserialize.
You can also use GSON and write a custom deserializer that performs checks as strict as you want them. Example - you can enforce not null along with not empty for strings.
Compiler Assisted Localization (CAL10N) is not exactly what you asked, but may be of help.
Although it does not generate Java classes from .properties, using enums as message keys is still better than strings, as you get some help from the compiler.
Declare a enum, bind it to .properties with annotation and use enum values in message lookups. I have not tried it yet, though. See manual.
Related
Similar to dynamic SQL, wherein a String is executed as an SQL at runtime, can we have Java code run dynamically? Like I return a String which is a Java code and then I execute at runtime. Is this possible?
For real Java code, this is possible using the JavaCompiler interface. However, it's very inconvenient to use since it's just an interface to a real Java compiler that expects to compile entire class definitions found in files.
The easiest way to execute code supplied at runtime would be to use the Rhino JavaScript engine.
Both of these options have been only in Java 6, though I believe the scripting interface existed before, so you could use Rhino in an earlier JRE if you download and add it to the classpath.
Javassist
You would need to use a bytecode manipulation library such as Javassist (Wikipedia), in order to run an arbitrary string that is provided at runtime. Javassist allows you to create a CtClass based on a string representing source code; and can then turn this into compiled Class object via a particular classloader, so that the class is then available to your application. Other libraries would need to do something similar to these two steps in order to achieve the same thing.
So it is possible, but it's very heavyweight and is likely to make your application very hard to reason about. If at all possible, consider designing a very flexible class statically, and having it accept parameters that control its behaviour.
If you want to do more than invoke an existing method dynamically, you may need to compile your String into bytecode. An easy way to do this is to include the Eclipse/JDT compiler jar in your classpath, and then you can use that to compile your String into a Class, which can then be loaded.
This type of dynamic code generation and execution is used to convert JSP files into Servlets and is used in other packages such as JasperReports to turn a report specification into a Class that is then invoked.
Remember that just as with SQL you must be careful to prevent code injection security problems if any of the String contains user-specified data.
You also may want to look at Java 6 scripting support:
http://download.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.htm
Here is a version of hello world that creates array of strings and prints a first one:
import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval("var a=java.lang.reflect.Array.newInstance(java.lang.String, 1);a[0]='Hello World';print(a[0])");
}
}
Yes it is possible. Look at the Java Compiler API. Have a look here:
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html
Have a look at Beanshell. It provides an interpreter with java like syntax.
I am trying to let users of my program rename classes and methods in the class. The new names can be read in and configured at run time and they will call these classes and methods in a scripting language using Java Script Engine. I need a way to bind their new names to the real names of the classes and methods. I have been looking at Reflection but I do not think this can provide me with the capability I need, or is this even possible?
Ex:
public class RealName {
public void printHello() {
System.out.println("Hello");
}
}
Then in maybe Paython say
obj = new NewName()
obj.hello()
Tell me if this is impossible please!
You can not change the method names, but you can bind an instance of an object to a given name and inject that into the context of the scripting language.
This would only work for that instance of the class, not for instantiating new instances.
If you really want this you may be able to generate sub classes with the new name and method names in the target scripting language and inject them into to the context to get the effect you are looking for.
Having said all that I can't really come up with a good reason to do any of this.
To answer my question from what I've found no you cannot use reflection to bind a class to a new name. In fact I found no easy way to do dynamic renaming.
What I did to overcome this was to write code from a string to a file, save that file with extension .java, compile that file, then use it with reflection or better yet use it inside a script using the Java ScriptEngine API (that way you can avoid the ugly reflection code and actually have everything dynamic and on the fly).
Here's a starting point for creating the file,
Dynamic in-memory compilation
And here's something for scripting Java,
Scripting for Java
I've just finished reading the chapter of 'Thinking in Java' concerning type information and reflection. While instanceof seems quite natural to me, some examples of reflection made me confused. I want to know if reflection is widely used in Java projects? What are 'the good parts' of reflection? Can you suggest any interesting lectures about reflection and type information with more good and worthy examples?
Edit (one more question):
Why is it useful to access private methods and fields withjava.lang.reflect.Method.setAccesible()?
Thanks in advance.
if you could post some of the examples I would be glad to explain it for you.
Reflection is wildly used with frameworks that need to extract meta-info about the running object (e.g. frameworks which depends on Annotations or the fields in your objets, think about Hibernate, Spring and a lot others).
On a higher layer, I sometimes use reflection to provide generic functionality (e.g. to encode every String in an object, emulate Duck Typing and such).
I know that you already read a book which covers the basics about reflection, but I need to point Sun (erm.. Oracle) official Tutorial as a must read: http://download.oracle.com/javase/tutorial/reflect/
One good example in my opinion is instantiating objects based on class names that are known only at runtime, for example contained in a configuration file.
You will still need to know a common interface to the classes you're dynamically instantiating, so you have something to cast them too. But this lets a configuration drive which implementation will be used.
Another example could be when you have to cast an object to a class that it's a descendant. If you are not sure about the type of that object, you can use instanceof to assure that the cast will be correct at runtime avoiding a class cast exception.
An example:
public void actionPerformed (ActionEvent e){
Object obj = e.getSource();
if (obj instanceof objType)
objType t = (objType) obj; // you can check the type using instanceof if you are not sure about obj class at runtime
}
The reason to provide such features in Reflection is due to multiple situations where tool/application needs meta information of class, variables, methods. For example:-
IDEs using auto completion functionality to get method names and attribute names.
Tomcat web container to forward the request to correct module by parsing their web.xml files and request URI.
JUnit uses reflection to enumerate all methods in a class; assuming either testXXX named methods as test methods or methods annoted by #Test.
To read full article about reflection you can check http://modernpathshala.com/Forum/Thread/Interview/308/give-some-examples-where-reflection-is-used
In Ruby, you can do "var1".constantize to get the actual variable var1.
Ruby also has Model.Send("method name, parameters can be here, etc"), and it would be the same as actually calling that method.
What I want to do.. is... kinda tricky... I want the string "var1 == var2" to be converted to actual variables in my java app, then evaluated.
Is there a way to do this?
Have you considered using JRuby?
As to your questions:
There is no peer to constantize that will allow for an eval like syntax where you can pass in a String and convert it to code in Java. You can do things like Class.forName to load a particular class from a String, but it doesn't sound that is what you are looking for.
You can use the Java reflection API to dynamically invoke methods on a class Check out Jakarta Commons BeanUtils for some utility methods that may help.
In Java, similar behaviour is achieved through the Reflection API. However, since Java is a compiled language, local variables' (within methods, constructors, parameters, etc) information is erased on compilation.
However you still have complete access to class names, hierarchies, methods and fields (class variables).
A good starting point is the Reflection API tutorial or the getClass() method of Object.
In Java if you want a dynamic lookup of variables, you would typically place them in a Map and lookup use the keys of that Map.
Can you explain what you are trying to do in more detail, I suspect what you are trying to do can be done simply a different way in Java.
Similar to dynamic SQL, wherein a String is executed as an SQL at runtime, can we have Java code run dynamically? Like I return a String which is a Java code and then I execute at runtime. Is this possible?
For real Java code, this is possible using the JavaCompiler interface. However, it's very inconvenient to use since it's just an interface to a real Java compiler that expects to compile entire class definitions found in files.
The easiest way to execute code supplied at runtime would be to use the Rhino JavaScript engine.
Both of these options have been only in Java 6, though I believe the scripting interface existed before, so you could use Rhino in an earlier JRE if you download and add it to the classpath.
Javassist
You would need to use a bytecode manipulation library such as Javassist (Wikipedia), in order to run an arbitrary string that is provided at runtime. Javassist allows you to create a CtClass based on a string representing source code; and can then turn this into compiled Class object via a particular classloader, so that the class is then available to your application. Other libraries would need to do something similar to these two steps in order to achieve the same thing.
So it is possible, but it's very heavyweight and is likely to make your application very hard to reason about. If at all possible, consider designing a very flexible class statically, and having it accept parameters that control its behaviour.
If you want to do more than invoke an existing method dynamically, you may need to compile your String into bytecode. An easy way to do this is to include the Eclipse/JDT compiler jar in your classpath, and then you can use that to compile your String into a Class, which can then be loaded.
This type of dynamic code generation and execution is used to convert JSP files into Servlets and is used in other packages such as JasperReports to turn a report specification into a Class that is then invoked.
Remember that just as with SQL you must be careful to prevent code injection security problems if any of the String contains user-specified data.
You also may want to look at Java 6 scripting support:
http://download.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.htm
Here is a version of hello world that creates array of strings and prints a first one:
import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval("var a=java.lang.reflect.Array.newInstance(java.lang.String, 1);a[0]='Hello World';print(a[0])");
}
}
Yes it is possible. Look at the Java Compiler API. Have a look here:
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html
Have a look at Beanshell. It provides an interpreter with java like syntax.