I have a property that that is #JsonIgnored on a class. And I wanted to make it available on some particular flow. I know that on a subclass, one can just use #JsonIgnored(false), and it overrides the base class annotation.
However, this does not seem to work via the MixIn, what works though is adding the #JsonProperty in the MixIn Interface/Abstract class. However, I am not too sure if this is safe and is consistent behavior.
Thanks.
Related
My code use a default ObjectMapper without filters defined, but the target class with a #JsonFilter annotation. My expectation is to Jackson will ignore the annotation and do a normal thing.
And in another case, if I want to use the filter and I also give the filter defined, why must add #JsonFilter to the class otherwise jackson will work as no filter.
#JsonFilter looks a redundant thing. We already defined the filters. The real issue is the problem described at beginning. We can't modify the class with annotation, we just serialize the class with normal behavior.
There's way to create a dummy filter and set setFailOnUnknownId(false). But this looks not so general.
What I have known are:
annotation was added in java 5
annotation can be using in method, class, and property
annotation can work in RUNTIME, CLASS, SOURCE( I don't know how to work with CLASS and SOURCE, and their's features)
annotation with retention which is RUNTIME can be implement when java program is running.
And I want to implement a annotation to have follows features:
ensure class only being allowed to create a instance
ensure methods only being allowed to access method in the class
it is like as friend in c++
it is same as public and private , but more dynamicall, like
#MyAnnotation(allowMethods={xxx.doSomething})
public void getValue(){}
the getValues method only can be accessed in the instance self and xxx.doSomething() method
What should I do and learn in next?
And Where can I learn about these?
I think you might be misunderstanding something there. Annotations are descriptive elements, not parts of your program. You can write as many annotations as you want, and people who use your code will still be able to ignore them.
That said, an annotation that enforces a policy (as yours does) can actually be implemented, either at compile or at runtime, but you need an external mechanism to help you. I can think of 3:
Annotation processing lets you interact with the compiler and process annotations by generating code or by omitting compiler errors. Unfortunately, I don't think it will work for your case, as you want to protect your annotated type from instantiation, and that means the call site doesn't actually have an annotation. Annotation processing only gives you access to the actual code pieces that have annotations, not to those that refer to them.
AspectJ allows you to write policy enforcement aspects and omit compiler errors, based on static pointcuts. The problem here is that static pointcuts have very limited semantics, so while you could forbid the instantiation of your class altogether, or from certain packages, you could not limit the your class instantiations to 1.
The third way, and probably the only sane way is that you use a container like Spring or Guice and configure your class as singleton. As long as you only retrieve your class from the container, it will never create a second instance.
Finally: If you want to limit the number of instantiations of your class, you can always use a classic Singleton pattern approach.
I need to figure out the annotated class in my custom ConstraintValidator but I didn't find a way without using provider specific API like:
ConstraintValidatorContextImpl x = (ConstraintValidatorContextImpl)constraintContext;
getValidationContext().getCurrentOwner();
Is there a non provider specific approach to figure out the annotated class?
Thanks a lot for your support.
Oli
Based on your comment I'd recommend to either implement two separate constraints, one for each target class (they could share implementation code using a delegate or super-class).
Or you implement a class-level constraint, which naturally has access to the validated class and all its properties. Note that you can still let the resulting constraint validation point to a specific property of the class using the constraint builder API in your validator implementation.
I recommend to Implement 2 ConstraintValidators, one for each class. The would both use the same Annotation which references them in the validateBy() method.
For the sake of my own education, I wanted to build a simple Dependency Injection framework that functions similar to the way Google's Guice does. So that when a class is loaded, it pre-populates annotated fields with data from a factory class.
I am using Reflections to scan all my factory classes at compile time and save those classes in a static list so that when it comes time to load my classes, I have a reference to my factories that I can then scan methods and return the appropriate data.
Where i'm stuck at is how to pre-populate my classes annotated fields without actually doing any of the work in the actual class. In other words, when a class is loaded, I need to be able to determine if any of the fields are annotated with a specific annotation, and if they are, retrieve the value from the factory class.
Is there some way of performing reflection on a class right before it is loaded, pre-populate specific fields and then return an instance of that class to be used?
I could extend all of my classes that require dependency injection with a base class that does all of this work, but I figure there must be a better way so that I can simply use an #Inject (or whatever annotation I decide to use to say that this field requires DI) and "magically" all the work is done.
The way that Guice approaches this is that it will only populate the fields of an instance that was itself created by Guice1. The injector, after creating the instance, can use the Reflection API to look at the fields of the Class and inspect their annotations with Field.getDeclaredAnnotations().
This is also the reason why, when you want to inject into a static field, you need to use Binder.requestStaticInjection() to populate the static fields.
Guice does not simply scan your code for annotations; all injections recurse from an explicit request (e.g. requestStaticInjection(), Injector.getInstance(), etc). Now often that initial, explicit request will have been made in some library code.
For example, if you're using guice-servlet you let Guice create the instances of your servlet by using the serve().with() calls. But if you didn't do that, and instead left your servlet config in your web.xml, Guice would not inject into your servlet.
1 - You can also request explicit injection using Binder.requestInjection().
I'm trying to write a web service for the java.util.logging api. So I wrote a class MyLogRecord that inherits from LogRecord. I annotated this class with JAX-B annotations, including #XmlAccessorType(XmlAccessType.NONE) so it would ignore non-annotated fields and properties. When I start up tomcat, I get errors that java.util.logging.Level and other java.util.logging classes do not have a default constructor, but none of my annotated methods make any reference to the Level class or any of the other java.util.logging classes. These are referenced by the parent class.
My sub-class has everything it needs defined. How can I get JAX-B to ignore the parent class completely?
Update: I found another post on this, which suggests modifying the parent class. This is obviously not possible because I am extending a java.util class. IS there any way to do this without modifying the superclass?
Update2: I found a thread on java.net for a similar problem. That thread resulted in an enhancement request, which was marked as a duplicate of another issue, which resulted in the #XmlTransient annotation. The comments on these bug reports lead me to believe this is impossible in the current spec.
You need to mark the parent class #XmlTransient. Since the parent class is in the JRE and cannot be modified by you, you need an alternate mechanism.
The EclipseLink JAXB (MOXy) implementation offers a means of representing the metadata as XML that you could use:
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
You can specify some of the metadata using annotations, and the rest as XML. Below is what your document would look like:
<java-types>
<java-type name="java.util.logging.LogRecord" xml-transient="true"/>
</java-types>