Datanucleus enhancer error: transient method - java

I have a class
#Entity
public class MyClass extends BaseClass {
...
public boolean isOpenAt(Date x) {
return true; // or whatever
}
}
#MappedSuperclass
#Access(AccessType.Field)
public abstract class BaseClass {
...
}
Running mvn datanucleus:enhance I get the error org.datanucleus.metadata.InvalidClassMetaDataException: "MyClass.openAt" : declared in MetaData, but this field doesnt exist in the class! Any idea why?
I'm using org.datanucleus:datanucleus-core:3.2.7, org.datanucleus:datanucleus-accessplatform-jpa-rdbms:3.3.2, org.eclipse.persistence:javax.persistence:2.1.0, org.datanucleus:datanucleus-maven-plugin:3.3.0-release.

Disclaimer: I have no idea what datanucleus is.
That said, it's likely that isOpenAt() method gets treated as a getter (similar to getFirstName(), say), since according to According to the JavaBeans spec,
Boolean properties
In addition, for boolean properties, we allow a
getter method to match the pattern:
public boolean is<PropertyName>();
This "isPropertyName" method may be provided instead of a
"get" method, or it may be provided in addition to a
"get" method. In either case, if the is
method is present for a boolean property then we will use the
"is" method to read the property value. An example
boolean property might be:
public boolean isMarsupial(); public void setMarsupial(boolean m);
Try renaming isOpenAt() into seeIfOpenAt() and see if that helps.

Related

how to read runtime annotations on a field within a class

Imagine an annotation called "MyAnn" with runtime retention, a class MyClass, and an abstract class called MyData. MyClass has a field of type MyData, annotated with MyAnn. Within the instance of MyData, how do see if the annotation MyAnn is present and retrieve its information?
Note - in Java8 I know we can directly annotate the inner class at construction - and that works - but I need this working based on the field annotation.
Thanks for any help!
public MyClass extends MySuperClass() {
#MyAnn(value = "something")
protected MyData mydata;
public void doSomething() {
mydata = new MyData() {};
mydata.initialize();
}
}
public abstract MyData() {
String myValue = null;
public void initialize() {
if (***I am annotated with MyAnn) {
myValue = (***value from annotation MyAnn);
}
}
}
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnn {
String myvalue;
}
MyData cannot directly know whether it has been annotated with MyAnn, because it has no knowledge of whether the current instance is a field or a standalone instance, and if it is a field, then whether the field has or has not been annotated with MyAnn.
So, you will need to somehow obtain and pass the value to initialize(), and you will need to somehow obtain the value at the place where initialize() is called. And from your code, it appears that "something" can be passed as a parameter to initialize(), making the whole thing a lot easier than annotating the field and then checking whether the field is annotated.
But in any case, if you want to check whether a field is annotated, you have to:
obtain the fields of your class with getClass().getDeclaredFields()
loop over the fields; for each field, either
invoke isAnnotationPresent( MyAnn.class ) or
invoke field.getAnnotations(), loop for each annotation, and check whether this annotation instanceof MyAnn.class
Once you have found the annotation, you can get its value with annotation.value();

Exception trying to change a CGLib proxy field value

I created a CGLib dynamic proxy of a class, but when I try to access any field declared in the original class, I obtain java.lang.NoSuchFieldException. I need to obtain the field in order to change its value.
By the way, this is the class the proxy is based on:
public class Person {
private String name;
....
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
...
}
And this is the code snippet (inside the "intercept" method of the "MethodInterceptor") that is raising the mentioned exception (more specifically the first line):
public Object intercept(Object instance, Method jdkMethod, Object[] args, MethodProxy method) throws Throwable {
...
Field field = instance.getClass().getField("name");
field.setAccessible(true);
field.set(instance, "foo");
....
Do you know any other way to access the needed field or change its value?
Thanks.
Apparently, a CGLib proxy is a subclass of the original class. So, the following code worked well:
Field field = instance.getClass().getSuperclass().getDeclaredField("name");
Try:
Field field = instance.getClass().getDeclaredField("name");
As mentioned in this SO answer, getField only works for public fields, but applies to the entire class hierarchy. You can think of it as inspecting the public interface of the class. getDeclaredField works for private fields, and will not inspect the class hierarchy; you can think of it as resolving the implementation of the class.
Even though you already figured out how to fix your problem, here is a short explanation of how cglib works and what is causing you problems. Considering your Person class, cglib creates another class at runtime which is representing your proxy. This class would approximately look like the following in Java source code, however, many of the instances used are cached which is why cglib adds several other fields. Furthermore, the MethodInterceptor is injected by using different static fields:
public class Person$EnhancedByCglib extends Person {
private static class GetNameMethodProxy extends MethodProxy {
#Override
public Object invokeSuper(Object instance,
Object[] arguments) {
return ((Person$EnhancedByCglib) instance).getNameSuper();
}
// ...
}
// ...
private static MethodInterceptor methodInterceptor;
#Override
public String getName() {
return (String) methodInterceptor.intercept(this,
getClass().getDeclaredMethod("getName"),
new Object[0],
new GetNameMethodProxy());
}
private String getNameSuper() {
return super.getName();
}
#Override
public void setName(String name) {
methodInterceptor.intercept(this,
getClass().getDeclaredMethod("setName", String.class),
new Object[] {name},
new SetNameMethodProxy());
}
private void setNameSuper(String name) {
super.setName(name);
}
// ...
}
As you can see, the interception is implemented by overriding any method. This way, your MethodInterceptor is invoked instead of the original method which is still invokable by using the MethodProxy. Due to the interception, calling getMethod or getDeclaredMethod works as expected when using cglib. Fields are however not inherited which is why you need to browse the class hierarchy one class up. This is why:
instance.getClass().getSuperclass().getDeclaredField("name");
works. Note that cglib is not longer maintained. Have a look at my library Byte Buddy in case that you are looking for an alternative. Note however that I am releasing a fully stable version sometime next week. The current v0.1 release contains some premature features.

Issue when java method annotated with #XmlTransient in Jaxb 2.1

I am trying to annotate my java method as #XmlTransient in my java class like below.
#XmlAccessorType(XmlAccessType.PROPERTY)
public abstract class MyClass {
#XmlTransient
public void addsomething{
// do something
}
}
When I try to use this class in my JaxBContext through other class I am getting following exception
JAXB annotation is placed on a method that is not a JAXB property
this problem is related to the following location:
at #javax.xml.bind.annotation.XmlTransient()
,
But when I see XmlTransient() annotation definition(#Target(value={FIELD,METHOD,TYPE})) it's clearly said be to work with methods. And In the JavaDoc(http://docs.oracle.com/javaee/7/api/javax/xml/bind/annotation/XmlTransient.html) it says
The #XmlTransient annotation can be used with the following program elements:
a JavaBean property
field
class
Can't I use #XmlTransient on methods?
The only methods that #XmlTransient can be used are those that begin with get or set. These methods used in combination are used to expose a property in Java. #XmlTransient can be placed on either the get or set method.
Get Method
The get method must take no parameters and return a value:
public String getFoo() {
return foo;
}
Set Method
The set method must take one parameter.
public void setFoo(String foo) {
this.foo = foo;
}

Java - Alternatives to forcing subclass to have a static method

I often find I want to do something like this:
class Foo{
public static abstract String getParam();
}
To force a subclasses of Foo to return a parameter.
I know you can't do it and I know why you can't do it but the common alternative of:
class Foo{
public abstract String getParam();
}
Is unsatisfactory because it requires you to have an instance which is not helpful if you just want to know the value of the parameter and instantiating the class is expensive.
I'd be very interested to know of how people get around this without getting into using the "Constant Interface" anti pattern.
EDIT: I'll add some more detail about my specific problem, but this is just the current time when I've wanted to do something like this there are several others from the past.
My subclasses are all data processors and the superclass defines the common code between them which allows them to get the data, parse it and put it where it needs to go.
The processors each require certain parameters which are held in an SQL database. Each processor should be able to provide a list of parameters that it requires and the default values so the configuration database can be validated or initialised to defaults by checking the required parameters for each processor type.
Having it performed in the constructor of the processor is not acceptable because it only needs to be done once per class not once per object instance and should be done at system startup when an instance of each type of class may not yet be needed.
The best you can do here in a static context is something like one of the following:
a. Have a method you specifically look for, but is not part of any contract (and therefore you can't enforce anyone to implement) and look for that at runtime:
public static String getParam() { ... };
try {
Method m = clazz.getDeclaredMethod("getParam");
String param = (String) m.invoke(null);
}
catch (NoSuchMethodException e) {
// handle this error
}
b. Use an annotation, which suffers from the same issue in that you can't force people to put it on their classes.
#Target({TYPE})
#Retention(RUNTIME)
public #interface Param {
String value() default "";
}
#Param("foo")
public class MyClass { ... }
public static String getParam(Class<?> clazz) {
if (clazz.isAnnotationPresent(Param.class)) {
return clazz.getAnnotation(Param.class).value();
}
else {
// what to do if there is no annotation
}
}
I agree - I feel that this is a limitation of Java. Sure, they have made their case about the advantages of not allowing inherited static methods, so I get it, but the fact is I have run into cases where this would be useful. Consider this case:
I have a parent Condition class, and for each of its sub-classes, I want a getName() method that states the class' name. The name of the sub-class will not be the Java's class name, but will be some lower-case text string used for JSON purposes on a web front end. The getName() method will not change per instance, so it is safe to make it static. However, some of the sub-classes of the Condition class will not be allowed to have no-argument constructors - some of them I will need to require that some parameters are defined at instantiation.
I use the Reflections library to get all classes in a package at runtime. Now, I want a list of all the names of each Condition class that is in this package, so I can return it to a web front end for JavaScript parsing. I would go through the effort of just instantiating each class, but as I said, they do not all have no-argument constructors. I have designed the constructors of the sub-classes to throw an IllegalArgumentException if some of the parameters are not correctly defined, so I cannot merely pass in null arguments. This is why I want the getName() method to be static, but required for all sub-classes.
My current workaround is to do the following: In the Condition class (which is abstract), I have defined a method:
public String getName () {
throw new IllegalArugmentException ("Child class did not declare an overridden getName() method using a static getConditionName() method. This must be done in order for the class to be registerred with Condition.getAllConditions()");
}
So in each sub-class, I simply define:
#Override
public String getName () {
return getConditionName ();
}
And then I define a static getConditionName() method for each. This is not quite "forcing" each sub-class to do so, but I do it in a way where if getName() is ever inadvertently called, the programmer is instructed how to fix the problem.
It seems to me you want to solve the wrong problem with the wrong tool. If all subclasses define (can't really say inherit) your static method, you will still be unable to call it painlessly (To call the static method on a class not known at compile time would be via reflection or byte code manipulation).
And if the idea is to have a set of behaviors, why not just use instances that all implement the same interface? An instance with no specific state is cheap in terms of memory and construction time, and if there is no state you can always share one instance (flyweight pattern) for all callers.
If you just need to couple metadata with classes, you can build/use any metadata facility you like, the most basic (by hand) implementation is to use a Map where the class object is the key. If that suits your problem depends on your problem, which you don't really describe in detail.
EDIT: (Structural) Metadata would associate data with classes (thats only one flavor, but probably the more common one). Annotations can be used as very simple metadata facility (annotate the class with a parameter). There are countless other ways (and goals to achieve) to do it, on the complex side are frameworks that provide basically every bit of information designed into an UML model for access at runtime.
But what you describe (processors and parameters in database) is what I christened "set of behaviors". And the argument "parameters need to be loaded once per class" is moot, it completely ignores the idioms that can be used to solve this without needing anything 'static'. Namely, the flyweight pattern (for having only once instance) and lazy initialization (for doing work only once). Combine with factory as needed.
I'm having the same problem over and over again and it's hard for me to understand why Java 8 preferred to implement lambda instead of that.
Anyway, if your subclasses only implement retrieving a few parameters and doing rather simple tasks, you can use enumerations as they are very powerful in Java: you can basically consider it a fixed set of instances of an interface. They can have members, methods, etc. They just can't be instanciated (as they are "pre-instanciated").
public enum Processor {
PROC_IMAGE {
#Override
public String getParam() {
return "image";
}
},
PROC_TEXT {
#Override
public String getParam() {
return "text";
}
}
;
public abstract String getParam();
public boolean doProcessing() {
System.out.println(getParam());
}
}
The nice thing is that you can get all "instances" by calling Processor.values():
for (Processor p : Processorvalues()) {
System.out.println(String.format("Param %s: %s", p.name(), p.getParam()));
p.doProcessing();
}
If the processing is more complex, you can do it in other classes that are instanciated in the enum methods:
#Override
public String getParam() {
return new LookForParam("text").getParam();
}
You can then enrich the enumeration with any new processor you can think of.
The down side is that you can't use it if other people want to create new processors, as it means modifying the source file.
You can use the factory pattern to allow the system to create 'data' instances first, and create 'functional' instances later. The 'data' instances will contain the 'mandatory' getters that you wanted to have static. The 'functional' instances do complex parameter validation and/or expensive construction. Of course the parameter setter in the factory can also so preliminary validation.
public abstract class Processor { /*...*/ }
public interface ProcessorFactory {
String getName(); // The mandatory getter in this example
void setParameter(String parameter, String value);
/** #throws IllegalStateException when parameter validation fails */
Processor construct();
}
public class ProcessorA implements ProcessorFactory {
#Override
public String getName() { return "processor-a"; }
#Override
public void setParameter(String parameter, String value) {
Objects.requireNonNull(parameter, "parameter");
Objects.requireNonNull(value, "value");
switch (parameter) {
case "source": setSource(value); break;
/*...*/
default: throw new IllegalArgumentException("Unknown parameter: " + parameter);
}
}
private void setSource(String value) { /*...*/ }
#Override
public Processor construct() {
return new ProcessorAImpl();
}
// Doesn't have to be an inner class. It's up to you.
private class ProcessorAImpl extends Processor { /*...*/ }
}

Enum "does not have a no-arg default constructor" with Jaxb and cxf

A client is having an issue running java2ws on some of their code, which uses & extends classes that are consumed from my SOAP web services. Confused yet? :)
I'm exposing a SOAP web service (JBoss5, Java 6). Someone is consuming that web service with Axis1 and creating a jar out of it with the data types and client stubs. They are then defining their own type, which extends one of my types. My type contains an enumeration.
class MyParent {
private MyEnumType myEnum;
// getters, settters for myEnum;
}
class TheirChild extends MyParent {
...
}
When they are running java2ws on their code (which extends my class), they get
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.foo.bar.MyEnuMType does not have a no-arg default constructor.
this problem is related to the following location:
at net.foo.bar.MyEnumType
at public net.foo.bar.MyEnumType net.foo.bar.MyParent.getMyEnum()
The enum I've defined is below. This is now how it comes out after being consumed, but it's how I have it defined on the app server:
#XmlType(name = "MyEnumType")
#XmlEnum
public enum MyEnumType {
Val1("Val1"),
Val2("Val2")
private final String value;
MyEnumType(String v) {
value = v;
}
public String value() {
return value;
}
public static MyEnumType fromValue(String v) {
if (v == null || v.length() == 0) {
return null;
}
if (v.equals("Val1")) {
return MyEnumType.Val1;
}
if (v.equals("Val2")) {
return MyEnumType.Val2;
}
return null;
}
}
I've seen things online and other posts, like (this one) regarding Jaxb's inability to handle Lists or things like that, but I'm baffled about my enum. I'm pretty sure you can't have a default constructor for an enum (well, at least a public no-arg constructor, Java yells at me when I try), so I'm not sure what makes this error possible. Any ideas?
Also, the "2 counts of IllegalAnnotationsExceptions" may be because my code actually has two enums that are written similarly, but I left them out of this example for brevity.
The no-arg constructor for JAXB doesn't have to be public, it can be private:
private String value;
private MyEnumType() {} // for JAXB
MyEnumType(String v) {
value = v;
}
You can't keep the value member final this way, though.
I am certain you can have a default constructor for an enum.
In fact, that what you have when you don't define a constructor explicitely
(like yours with a String parameter).
You can also have several constructors, one no-args and others.
In the precise example you give, it would be simple to avoid the String parameter altogether.
The provided name() method has exactly the value you are provided.
The code would even be simpler:
#XmlType(name = "MyEnumType")
#XmlEnum
public enum MyEnumType {
Val1, Val2;
public String value() {
return name();
}
public static MyEnumType fromValue(String v) {
for(MyEnumType type : values()) {
if (type.value().equals(v)) {
return type;
}
}
return null;
}
}
If you have really some complex parameters to set to each value, and can't have specific constructors because of a library, you could also store your varying values into an EnumMap, and read this as needed.
when you do from-java-to-wsdl, apache check at first is it enum class or not, and only if this check fail, it check for constructor. You can see it in org.apache.axis.wsdl.fromJava.Types::isBeanCompatible. Any normal man, will think that if he write
public enum MyEnum{}
it will be enough. But Apache developers does not think so (IDK why, may be for some compatibility reasons). They do this method - org.apache.axis.utils.JavaUtils::isEnumClassSub.
If you will decomile this class, you will see, that your enum
MUST implement public String getValue() {return name();}
MUST implement public MyEnum fromString(String v){return valueOf(v);}
CAN'T contain public void setValue(){}
MUST implement String toString(), but each object implement it.

Categories