IS it possible to use the java reflection api in GWT client side? I want to use reflections to find the value of a property on a Javabean. Is this possible?
You can use the GWT Generators functionality that allows you to generate code during the GWT compile phase.
Your bean, that you want to introspect, can extend a class that has a method defined as
public Object getProperty(String propertyName){}
Let's call this class IntrospectionBean.
Let's say that you then have your bean defined as:
public class MyBean extends IntrospectionBean {
private String prop1;
private String prop2;
}
The GWT generator will have access to all fields of MyBean and it can generate the getProperty(String propertyName) method during GWT compile time, after iterating through all fields of MyBean.
The generated class might look like this:
public class MyBean extends IntrospectionBean {
private String prop1;
private String prop2;
public Object getProperty(String propertyName) {
if ("propr1".equals(propertyName)) {
return prop1;
}
if ("propr2".equals(propertyName)) {
return prop2;
}
return null;
}
}
You could simply then use myBean.getProperty("prop1") in order to retrieve a property based on it's name at runtime.
Here you can find an example of how to implement a gwt generator
I've been there and the solution indeed is to use Deferred Binding and Generators. You can see a use of Generators to overcome the lack of Reflection in GWT client here:
http://jpereira.eu/2011/01/30/wheres-my-java-reflection/
Hope it helps.
Since GWT code is translated to Javascript direct usage of reflection API is not supported.
There is a small project GWT-Reflection, that allows to use reflection in GWT.
I have made my gwt-reflection library public.
https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-reflect
https://github.com/WeTheInternet/gwt-sandbox/tree/xapi-gwt/user/src/com/google/gwt/reflect
Due to classpath issues with trying to make Gwt pick my version of Class.java over its own, I finally just forked Gwt, added java 8 and reflection support, and now maintain net.wetheinter:gwt-*:2.7.0 which has this support baked in (I will release a 2.8 some time after Gwt 2.8 goes live)
It supports three levels of reflection:
Monolithic:
// Embeds all data needed to perform reflection into hidden fields of class
GwtReflect.magicClass(SomeClass.class);
SomeClass.getField(fieldName).set(null, 1);
Lightweight:
// Allows direct reflection, provided ALL parameters are literals, or traced to literals
SomeClass.class.getField("FIELD_NAME").set(null, 1);
Flyweight:
// Skips creating a Field object entirely, and just invokes the accessor you want
// All params must be literals here as well
GwtReflect.set(SomeClass.class, "FIELD_NAME", null, 1);
These examples also work for Methods and Constructors. There's basic support for annotations, and more to come in the future.
GWT not support reflection fully, you can see bellow link :
http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsCompatibility.html
You should note the border between java and javascript. In GWT, all code compiles to javascript, so you have to check if JavaScript is a well-defined reflection.
If you just want to use reflection to grab a private field, consider using jsni (javascript native interface) instead; it has no notion of private or public, so you can just grab anything you want like so:
package com.foo;
class SomeClass {
private String someField;
private static int someInt;
}
//accessors:
native String ripField(SomeClass from)
/*-{
return from.#com.foo.SomeClass::someField;
}-*/;
native int ripInt()
/*-{
return #com.foo.SomeClass::someInt;
}-*/;
Also, I am in the middle of finishing up emulation for java.lang.Class newInstance / reflection.
I'll post back here with a link in about two days if you'd like to play with it.
It requires that you pass a class through a method which I route to a custom generator
(like GWT.create, except it returns a generated java.lang.Class with field and method accessors that just point to jsni methods / fields. :)
Related
I'm using Kotlin with Apache Beam and I have a set of DTOs that reference each other and all serialize great for any encoder with Kotlinx Serialization. When I try to use them with Beam I end up having issues because it's looking for all objects, type parameters and nested objects to implement the Java Serializable interface. Problem is, I'm not in control of that with all object types because some come from 3rd-party libraries.
I've implemented my own CustomCoder<T> type that uses Kotlinx Serialization but then I run into issues with my custom coder not being serializable, particularly due to the Kotlinx Serialization plugin-generated Companion object serializer not serializing. Since it's compile-time generated code I don't really have control over that and I can't flag it as #Transient. I tried implementing Externalizable on the coder and it fails as soon as I pass a type argument for T that doesn't implement Serializable or has a nested type argument that doesn't.
Also, Kotlinx Serialization is nice because it doesn't use reflection. It would make a lot of my current headaches disappear if I could just swap out the serialization mechanism somehow and not have to rely on standard Java serialization methods at all or somehow implement Externalizable in a way that just calls out to my own serialization mechanism and ignores the type parameter. Are there any solutions? I don't care how hacky it is, even if the solution involves messing with stuff in the Gradle build config to override something. I'm just not sure how to go about it so any pointers would be a great help!
Alternatively, if I abandon Kotlinx Serialization, are there any simple solutions to make any arbitrarily complex data type serialization just work with Java, even using reflection, without a lot of custom, manual work to handle encoding and decoding? I feel like maybe I'm just missing something obvious. This is my first project with Apache Beam but so far the google is little help.
Mybe late, I develop an annotation processor called beanknife recently, it support generate DTO from any class. You need config by annotation. But you don't need change the original class. This library support configuring on a separate class. Of course you can choose which property you want and which you not need. And you can add new property by the static method in the config class. The most power feature of this library is it support automatically convert a object property to the DTO version. for example
class Pojo1 {
String a;
Pojo b; // circular reference to Pojo2
}
class Pojo2 {
Pojo1 a;
List<Pojo1> b;
Map<List<Pojo1>>[] c;
}
// remove the circular reference in the DTO
#ViewOf(value = Pojo1.class, includePattern = ".*", excludes={Pojo1Meta.b})
class ConfigureOfPojo2 {}
// use the no circular reference versioned dto replace the Pojo1
#ViewOf(value = Pojo2.class, includePattern = ".*")
class ConfigureOfPojo2 {
// convert b to dto version
#OverrideViewProperty(Pojo2Meta.b)
private List<Pojo1View> b;
// convert c to dto version
#OverrideViewProperty(Pojo2Meta.c)
private Map<List<Pojo1View>>[] c;
}
will generate
// meta class, you can use it to reference the property name in a safe way.
class Pojo1Meta {
public final String a = "a";
public final String b = "b";
}
// generated DTO class. The actual one will be more complicate, there are many other method.
class Pojo1View {
private String a;
public Pojo1View read(Pojo1 source) { ... }
... getters and setters ...
}
class Pojo2Meta {
public final String a = "a";
public final String b = "b";
public final String c = "c";
}
class Pojo2View {
private String a;
private List<Pojo1View> b;
private Map<List<Pojo1View>>[] c;
public Pojo1View read(Pojo2 source) { ... }
... getters and setters ...
}
The interest things here is you can safely use the class not exist yet in the source. Although the compiler may complain, all will be ok after compiled. Because all the extra class will be automatically generated just before compiled.
A better approach may be to compile step by step, first add #ViewOf annotations, and then compile, so that all the classes that need to be used later are generated. Compile again after the configuration is complete. The advantage of this is that the IDE will not have grammatical error prompts, and can make better use of the IDE's auto-complete function.
With the support of using generated DTO in the configure class. You can define a Dto without circular reference just like the example. Furthermore, you can define another dto for Pojo2, and remove all property reference the Pojo1 and use it to replace the property b in Pojo1.
I went through some of the samples that have used libraries to generate bean classes from JSON, XML etc. What I would like to know is, whether there's a way to dynamically generate a java bean class, with the parameters I give?
For example if I give an array of Strings as arguments which would represent the properties of the Pojo class for now, how can I generate the POJO?
Arguments: {"field1", "field2", "field3"}
Generate POJO would be:
public class TestBean {
private String field1;
TestBean() {
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
}
It should be the same for field2 and field3 as well.
Here I'm assuming that all the properties above are String and the class name is constant for now. Is there any way I can achieve this? Thanks in advance.
The problem with generating an actual Java class at runtime is that there is no way you can access it using standard Java syntax as the compiler doesn't know about it.
In practice therefore, most people just use a map in this circumstance. The only case I can think where you would need to generate a real class is where there is some other code you can't change that requires a Java object and inspects it dynamically using reflection or otherwise.
If you don't need this you are better off using a map, or possibly some utility class designed to emulate a Java Bean.
The Apache BeanUtils package provides the DynaBean interface to implement dynamic Java Beans. That said, the classes are only recognised as beans if accessed from the rest of the BeanUtils package.
There are several subclasses depending on what you want, for example, LazyDynaBean:
DynaBean myBean = new LazyDynaBean();
myBean.set("myProperty", "myValue");
C# 6.0 introduced the nameof() operator, that returns a string representing the name of any class / function / method / local-variable / property identifier put inside it.
If I have a class like this:
class MyClass
{
public SomeOtherClass MyProperty { get; set; }
public void MyMethod()
{
var aLocalVariable = 12;
}
}
I can use the operator like this:
// with class name:
var s = nameof(MyClass); // s == "MyClass"
// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"
// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"
// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".
This is useful since the correct string is checked at compile time. If I misspell the name of some property/method/variable, the compiler returns an error. Also, if I refactor, all the strings are automatically updated. See for example this documentation for real use cases.
Is there any equivalent of that operator in Java? Otherwise, how can I achieve the same result (or similar)?
It can be done using runtime byte code instrumentation, for instance using Byte Buddy library.
See this library: https://github.com/strangeway-org/nameof
The approach is described here: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/
Usage example:
public class NameOfTest {
#Test
public void direct() {
assertEquals("name", $$(Person.class, Person::getName));
}
#Test
public void properties() {
assertEquals("summary", Person.$(Person::getSummary));
}
}
Sadly, there is nothing like this. I had been looking for this functionality a while back and the answer seemed to be that generally speaking, this stuff does not exist.
See Get name of a field
You could, of course, annotate your field with a "Named" annotation to essentially accomplish this goal for your own classes. There's a large variety of frameworks that depend upon similar concepts, actually. Even so, this isn't automatic.
You can't.
You can get a Method or Field using reflection, but you'd have to hardcode the method name as a String, which eliminates the whole purpose.
The concept of properties is not built into java like it is in C#. Getters and setters are just regular methods. You cannot even reference a method as easily as you do in your question. You could try around with reflection to get a handle to a getter method and then cut off the get to get the name of the "property" it resembles, but that's ugly and not the same.
As for local variables, it's not possible at all.
You can't.
If you compile with debug symbols then the .class file will contain a table of variable names (which is how debuggers map variables back to your source code), but there's no guarantee this will be there and it's not exposed in the runtime.
I was also annoyed that there is nothing comparable in Java, so I implemented it myself: https://github.com/mobiuscode-de/nameof
You can simply use it like this:
Name.of(MyClass.class, MyClass::getProperty)
which would just return the String
"property"
It's also on , so you can add it to your project like this:
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
or for Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
I realize that it is quite similar to the library from strangeway, but I thought it might be better not to introduce the strange $/$$ notation and enhanced byte code engineering. My library just uses a proxy class on which the getter is called on to determine the name of the passed method. This allows to simply extract the property name.
I also created a blog post about the library with more details.
Lombok has an experimental feature #FieldNameConstants
After adding annotation you get inner type Fields with field names.
#FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"
I need to implement a solution as part of Test framework & I am considering singleton pattern for reasons explained below. However, I am not able to achieve my intended solution & therefore would need some suggestions/inputs on possible implementations.
Problem Statement :
I have a environment (env of the product I am testing) configuration properties file which I want to load & make the value of the parameters accessible globally to the test framework.
I figured using the singleton pattern because these properties are one-time values (should report an exception if tried to initialize more than once), should be available globally & have an one-point access to the methods.
However, the list of properties/parameters is really long & therefore it's wise to break it into modules (classes). For the below explanation, I tried with composition.
For e.g.
public class Configuration {
private static Configuration configObj;
private static Database dbDetails;
private static Machine macDetails;
//...
//... many more modules
public static synchronized void createInstance(Properities envProps){
//Should create only one instance of Configuration
// and should also initialize Database & Machine objects.
}
public static Configuration getConfigObject(){
return configObj;
}
}
public class Database {
private static String dbConnectString;
public Database(String dbcs){
dbConnectString = dbcs;
}
public static String getDbConnectString(){
return dbConnectString;
}
}
public class Machine {
private static String hostname;
private static String loginUsername;
public Machine(String hostname,String loginUsername){
this.hostname = hostname; //It may include some trimming/cleaning
this.loginUsername = loginUsername;
}
public static String getHostName(){
return hostname;
}
}
PS: Just a sample typed-in code for the understanding of my problem statement.
Expectation : The expectation now is that when trying to get the hostname, I should have a single point of access via Configuration static object (assuming that I have initialized all member variables successfully) i.e.
String hostname = Configuration.getHostname();
OR
String hostname = Configuration.getConfigObject().getHostname();
Current Issue :
How to create one static object that will refer to all methods using either composition or inheritance (Conceptually, composition would be the right approach).
Multiple Inheritance would have solved the issue but Java doesn't support so ruled out. Cannot consider Interfaces either because overriding all methods is tedious & lengthy & the parameters/methods will keep changing over-time.
All suggestions are welcome even if it requires to scrap this design pattern & try something different.
You will not be able to "automatically" delegate static calls to modules. And even if the calls were not static, as you stated, Java does not support multiple inheritance.
Option 1:
Have your main Configuration class provide static methods that return instances to your modules. Whenever you want to read a configuration entry, first get the module instance, then query the entry itself:
Configuration.getDatabaseConfiguration().getServerName();
This method has the advantage that it is very clear which part of your configuration you are referring to. If you would just use Configuration.getServerName(), you cannot distingish whether you want to retrieve the database's server name, or the webserver's.
Option 2:
If you are able to use Java 8 and your configuration is large, but very simple (statically known at compile time or extractable from very few instances), you could consider using the new default interface methods (https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/).
You would then create an interface for each module, where all getters have default implementations. Your main configuration class would implement all the module interfaces without overriding any of the methods. This way all configuration entries can be queried from one object, but you still have to obtain this object by a static method. This is as close to multiple inheritance as you can get. I would definitely recommend option 1 though.
I have a bunch of constants throughout my code for various adjustable properties of my system. I'm moving all of them to a central .properties file. My current solution is to have a single Properties.java which statically loads the .properties file and exposes various getter methods like this:
public class Properties {
private static final String FILE_NAME = "myfile.properties";
private static final java.util.Properties props;
static {
InputStream in = Properties.class.getClassLoader().getResourceAsStream(
FILE_NAME);
props = new java.util.Properties();
try {
props.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getString(Class<?> cls, String key) {
return props.getProperty(cls.getName() + '.' + key);
}
public static int getInteger(Class<?> cls, String key) {
return Integer.parseInt(getString(cls, key));
}
public static double getDouble(Class<?> cls, String key) {
return Double.parseDouble(getString(cls, key));
}
}
The only problem with that is that for every constant that I get from this file, I have some boilerplate:
private final static int MY_CONSTANT = Properties.getInteger(
ThisClass.class, "MY_CONSTANT");
I don't think I want to use Spring or the like as that seems like even more boilerplae. I was hoping to use a custom annotation to solve the issue. I found this tutorial, but I can't really sort out how to get the functionality that I want out of the annotation processing. The Java docs were even less helpful. This should be a thing I should be able to do at compile time, though. I know the names of the class and field.
What I'm thinking is something like this:
#MyAnnotation
private static final int MY_CONSTANT;
Anyone know how I would go about doing this or at least best practices for what I want to do?
First of all, you shouldn't do it. It's practical, but too hacky and if you ever want to write a test using different settings, you'll run into problems. Moreover, nobody's gonna understand how it works.
An annotation processor can probably do nothing for you. A Lombok-style-hacking processor can. You want to make
#MyAnnotation
private static final int MY_CONSTANT;
work like
private final static int MY_CONSTANT =
Properties.getInteger(ThisClass.class, "MY_CONSTANT");
The original expression doesn't compile (due to the uninitialized final variable), but it parses fine and Lombok can do its job. There's already something related there:
#Value changes the modifiers to final private
#UtilityClass makes all fields static
So actually, you could write just
#MyAnnotation
int MY_CONSTANT;
and let your annotation change also the modifiers. I'd look at the eclipse and javac handlers for #UtilityClass, I guess all you need is to generate the initializer (which is quite some work because it's all damn complicated).
I don't think Lombok itself will implement this anytime soon, since
all the static stuff is non-testable and mostly bad style
and not everyone wants this in their code
it's not that much boilerplate
it also magically refers to the class Properties, but this could be solved via configuration
but I guess a contribution might be accepted.
Actually not quite clear why and what do you want to archive.
As I correctly undestand, you want use special kind of annotations to automatically assign values for static final constants from some properties file. Unfortunatelly it is impossible without special hacks. And annotations have nothing to do with this.
The reason is that final fields must be initialized and it is compiler's request. There aren't special annotations in java which will provide such syntactic sugar which you want.
But if you insist on this there are two ways:
Extrim way. Init all properties field with default value. Then using this hack in some static init section initialize this value using reflection mechanism and you code via reading values from properties.
Less extrim way: refuse request of final modifiers for properties fields, and using only reflection fill these fields values.
And additionally, for these ways, yes you can use annotations. But you will have to solve following technical issues:
1) Find all fields in all classes in classpath, which are annotated with you special annotation. Look at:
Get all of the Classes in the Classpath and Get list of fields with annotation, by using reflection
2) Force your Properties class to be initialized in all possible enter points of your application. In static section in this class you will load your properties file, and then using (1) method with reflection and classloader, assign values to all constants.