Alternatives to #Deprecated SerializationFeature.WRITE_EMPTY_JSON_ARRAYS - java

I'm having difficulties figuring out the correct way to fix the deprecation warnings on SerializationFeature.WRITE_EMPTY_JSON_ARRAYS.
Javadocs state that
Since 2.8 there are better mechanism for specifying filtering;
specifically using com.fasterxml.jackson.annotation.JsonFormat or
configuration overrides.
but I would assume that
ObjectMapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
is a configuration override, although the line above triggers a deprecation warning.
What are other alternatives that do not pollute model classes with yet another annotation? I want to configure the behaviour globally.

At the class level, you can use the #JsonInclude like:
#JsonInclude( JsonInclude.Include.NON_EMPTY )
public class MyClass ...
Also, at the mapper level you can do something like:
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

The Javadoc is just plain wrong.
"using com.fasterxml.jackson.annotation.JsonFormat": There are plenty of cases where annotations are patently NOT better, most notably when you can't annotate the POJOS because you don't own them, or when you need to override the annototations to get a different behavior than you usually want.
"configuration overrides": That would be great, but to my knowledge there are no other overrides that will take precedence over annotations.
From the user perspective, the only thing bad about the deprecated option is that it is deprecated, and thus might not be supported in the future. That is of course a real concern - you might one day have to choose between a vital security update and keeping your code working without a rewrite.

Related

When is it appropriate to annotate something as #NotNull in Java?

This is my first question on here and I'm pretty new to Java, so please pardon me if this is kind of a silly question.
I am working on "documenting" the expected behavior of my application from within using JavaDocs and annotations, but I'm just curious if it's appropriate or good practice to use #NotNull on a method that SHOULDN'T ever return null, but may due to future developer error.
Thanks.
This really depends on what tooling you're using. The #NotNull annotation doesn't actually do anything. Actually, there are several different #NotNull annotations provided by different libraries. None of them do anything on their own, other than signalling the programmer's intent.
To make the annotation do anything, you need to combine it with a tool that will process the annotation (either at compile time or at run time) and apply some validation to your code or your data. For example:
IntelliJ IDEA contains tools which will check that your code abides by the nullability annotations you've included.
Bean validation can be used at runtime to check, for example, that user input doesn't violate the nullability constraints.
Even without the tooling, I would say that yes, these annotations can be useful to signal intent. You can always remove the annotation if it becomes untrue.
It sounds like it would be a good idea in your case for all contributors to the codebase to use a tool, like IntelliJ IDEA, that will check for compliance with these annotations at compile time. That will help you to avoid the type of developer error that you describe.
As far as I'm aware, there is not enforced standard globally to use these types of annotations. It makes sense to use them when writing a public API, but this is project specific.
In any case, feel free to do so in your project if it would help with code clarity and readability.
It's not an anti-pattern to have javadocs with annotations.
Also, if you are considering of warning the user of your method that it shouldn't return a null, but there is a chance of that happening (since you cannot enforce it), you might want to look into the Optional class.
yes it is good practice to use #NotNull. The #NotNull Annotation is, actually, an explicit contract declaring the following:
A method should not return null.
A variable (like fields, local variables, and parameters)cannot hold a null value.
So to keep it simple, it is a good practice.

working of Java Annotations

I want to know, if I've got it correct or not. I've been reading about annotations and wanted to know how all the magic happened. Here's what I think happens. Please let know if otherwise.
Firstly, let's take some annotation. Say AssertTrue. Now, the specs of the annotation is provided in javax.validation.constraints. Now, as such, AssertTrue does not really do anything. i.e. if I were to do the following
public class MyClass{
#AssertTrue(message = "MyMessage")
public myMethod(){
//something
}
}
Now, this particular piece of code is not going to do anything but save the metadata info that on this method myMethod I have some additional info i.e. message and annotation. How I make use of this info is upto me.
This is where the hibernate-validator framework comes into picture.
What it does is, that it provides a bunch of classes and it takes in the object that is supposed to be validated. On that object, it will check if AssertTrue annotation is there. If found, it will invoke the method isValid that is provided in the implementation of the AssertTrueImpl.
Is this what is happening?
Also, I have a few questions. say I have my own custom annotation and I want to provide a framework that checks something. For the sake of argument, let's say I want to do what the hibernate-validator is doing. Now how does one go about it?
Also, when the JVM encounters some annotation, what happens behind the scene? Does it look for some implementation? What exactly does it look for?
i.e. what will JVM do if it encountered AssertTrue in my code. Surely it does not have to do much but store some information, and it does not have to go looking for any implementation too, since whenever I call validator.validate() that's when it will look for hibernate-validator implementation.
let me know if I have understood it correctly.
You are correct. The annotation by itself does nothing, it's just metadata that may be used by a processing tool. In this case, Hibernate validator.
The usual procedure for those tools is to scan on the classpath what classes have metadata that they can use to build or enhance a class (by injecting a proxy, or registering an interceptor, or any other kind of operation). They either do scan the classpath, or an external configuration mechanism (xml, json, annotations on a config class [Spring way]) specifies this for the framework so that it knows where to look for annotated classes.
And so, you too, can benefit from annotations on your project, following the same discovery method. In fact, if you happen to work with CDI, you will probably use them a lot. They're quite useful for bean interception, or for providing metadata on your classes that would otherwise have to be treated with a lot of boilerplate code.
I encourage you to use them profusely.
Cheers!
You understand annotations correctly - they are just metadata on specific members (fields, methods, classes, ...). Some of them are intended for compile time only, some of them are intended for runtime. The latter will be available via Reflection API (basically forming additional metadata on annotated members). There are numerous possibilities of what you can do with this feature, where declarative validation defined by JSR-303 (and implemented by Hibernate Validator) is just one of them.

Where does the processing of an annotation happen?

I've been reading about annotations lately, and I'm a bit confused. I've used the annotation #NotNull but I don't really know how it checks if the variable is not null. No where in the code do I see anything checking values for null. That makes sense because it's an interface, so where does the actual processing happen and why isn't this location specified in the code? The examples I've seen usually just make an annotation that takes values, but doesn't do anything else, so I'm confused as to where the implementation occurs.
Annotation is just a metadata, no more no less.
When you want to specify some details about the class you put annotations on it.
Think about them (to some extent) as an alternative to the old well known XML way to define metadata.
Now, its obvious that someone reads your XML and runs the code that makes something with the metadata. The same happens with annotations: a framework to which annotation belongs to is responsible to read the annotation and make something with this information. In the case of #NotNull, its hibernate-validator project. The API exposed by java allows to access the information in the annotations by reflection (the classes like java.lang.Class, Method, Field, and so on). So somewhere inside hibernate validator there is a code that goes to your class, reads the annotations by reflection and checks whether the class adheres these annotations.
These annotation usually have retention policy 'runtime' which means that they're preserved in the bytecode and loaded along with the class that carries these annotations.
There are also annotations that should be processed by Java compiler. Like #Deprecated, #SuppressWarnings and so on. The benefit of having such annotation is that you can find some code issues during the compilation phase.
You can also put the annotation processors and 'plug' them during the compilation phase, buts its entirely different story.
Hope this clarifies a little the usage of annotations

Why java annotations?

i want to ask why are the java annotations used so much... I know that they replaced xml configuration in for example jpa, but why is this kind configuration used at all?
Consider this piece of code:
#Entity
class Ent{
// some fields
}
//... somewhere in the other file far far away
class NonEnt{
// whatever here
}
Now, when I try to put this in persistence context, with EntityManager's persist method, I get runtime error(better would be to get compile error) with trying to persist NonEnt instance. There is obvious solution for me, force the entities to implement some no-method interface instead of using #Annotations. But this isn't popular among framework designer, what is the drawback of this solution?
Thanks for answering...
When compared to marker interfaces, annotations have some advantages:
they can be parameterized
they are more fine grained - you can attach them not only to classes but also to other class elements (fields, methods, method arguments, etc)
Annotations are also supposedly less intrusive, but this point is matter of taste and debatable.
See also:
Annotations (official JDK documentation)
What is the use of marker interfaces in Java?
The use of annotations is a lot less invasive than forcing the client to implement a interface or extend a class.
There is obvious solution for me,
What you describe is called a "marker interface" and it's an abuse of the interface concept. I suspect the only reason why you consider it obvious is because of Serializable - which only exists because there were no annotations at that time.
force the entities to implement some
no-method interface instead of using
#Annotations. But this isn't popular
among framework designer, what is the
drawback of this solution?
What are its advantages? Annotations have the huge advantage that they can have parameters, and they are much more fine-grained. Marker interfaces only work at the class level.
Citing the java tutorial:
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Annotations have a number of uses,
among them:
Information for the compiler — Annotations can be used by the
compiler to detect errors or suppress
warnings.
Compiler-time and deployment-time processing — Software tools can
process annotation information to
generate code, XML files, and so
forth.
Runtime processing — Some annotations are available to be
examined at runtime.
As you can see, annotations are a way of specifying meta-data about your types in java, including interfaces, they are in no way a replacement for them.
Java annotation are really helpful when you want to add some additional information to your class, method or instance variable. There are a lot of libraries which use these annotations heavily. These annotations keep the code simple and readable with the power of making changes to the code at runtime.
For example if you have used lombok library, which creates setter, getter and constructor at compile time and saves you lines of code and time.
When compiler executes the code, lomok searches for all the fields marked with #Setter or #Getter annotation and add setter and getter for that field in the class.
One other example is Junit test runner. How junit differentiates between normal helper method in test class and a test. To differentiate between the two it uses #Test annotation.
This tutorial explains how you can use java annotations to create you own test runner.

Useful Java Annotations

I'm interested in finding out exactly which Java annotations people think are most useful during development. This doesn't necessarily have to limited to the core Java API, you may include annotations you found in third party libraries or annotations you've developed yourself (make sure you include a link to the source).
I'm really interested in common development tasks rather than knowing why the #ManyToOne(optional=false) in JPA is awesome...
Include the annotation and a description of why it's useful for general development.
I doled out a bunch of upvotes for other users, but just to give my two cents the only three annotations I use with any regularity in development are the main annotations used directly by the compiler:
#Override - Great for making it explicit in your code when you're overriding another method. Also has the extra benefit of being flagged as a compilation error if you don't override a method the way you think you are (see this other SO post). This flag informs the compiler that you're intending to override something, so if you don't (e.g. you forget an argument in the method signature), the compiler will catch it.
#Deprecated - Indicate whatever you're marking as something that should not be used from this point forward. The compiler will generate warnings for use of any code elements you've marked as deprecated. In general, deprecation says "this was in here in the past, but it may go away in a future version." Make sure you also use the associated "#deprecated" Javadoc flag in conjunction with this too to tell people what they should use instead.
#SuppressWarnings - Tell the compiler to suppress specific warnings it would otherwise generate. This can be useful for things like when you intentionally want to use deprecated methods, you can block out the deprecation warning. I tend to use it a lot to block out everyone's favorite "Serialization UID" warning on serializable classes (whether or not you should do that is another debate for another time). Just handy for those cases where you know something you're doing is generating a warning, but you're 100% sure it's the proper behavior you want.
Look at the Sun Annotations Guide and check out the section "Annotations Used by the Compiler". These three are given a fairly lengthy discussion.
The Java Concurrency in Practice annotations
Very useful for describing exactly how your code is or isn't thread safe...
I find the he concurrency-related annotations defined by Brian Goetz in his book "Java Concurrency In Practice" to be very useful:
#GuardedBy
#Immutable
#NotThreadSafe
#ThreadSafe
They're particularly useful as FindBugs has patterns that use them.
A jar and documentation is freely available at http://www.javaconcurrencyinpractice.com/
#Override has my vote. It makes it instantly clear what your method is about and makes your code more readable.
#Test
(JUnit 4) It's made writing and understanding test files quite a bit cleaner. Plus, the ability to add the expected attribute has saved a few lines of code here and there.
#Deprecated
Introduced in Java 5.
It helps developers see what's deprecated in IDEs. (Prior to this, most IDEs could still pull a #deprecated out of the javadoc comments for a particular method, but this annotation was a nice way to make it meta-information about the method itself, rather than a comment in documentation.)
It's also used by the compiler to print out warnings when you're using deprecated methods.
Personally I've been looking at the JSR303 Bean Validation and the annotations it provides, I imagine these will become more commonplace, there's only a few implementations of the JSR so far, but they provide annotations such as:
#NotNull private String name;
#NotNull #Size(min = 5, max = 30) private String address;
More info here: http://jcp.org/en/jsr/detail?id=303
these should be useful, you can define them in your projects to better communicate intentions:
#ThreadSafe
#Immutable
#ValueObject
#BagOfFunctions (e.g. java.util.Collections)
etc
Here are some Annotations I use in day to day development
Spring:
#Autowired - used to Auto wire beans
#Rollback - If set to true it will rollback all DB operations done inside the test case
JUnit:
#Test - Tell that a method is a test case
#Ignore - If you want to ignore any of the test cases
#Before - Code that should run before each test case
JPA:
#Entity - To tell that a POJO is a JPA Entity
#Column - Map the property to DB column
#Id - tell that a java property is Primary key
#EmbeddedId - Used for Composite Primary Keys
#Transient - This property should not be persisted
#Version - Used to manage optimistic locking
#NamedQuery - Used to declare Native SQLs
#OneToMany - One to Many relationship
#ManyToOne - Many to one Relationship
I have included only the most essential ones.You can find details about all the JPA annotations from the following links.
http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html
http://www.hiberbook.com/
We started using a compile time tool called lombok (http://projectlombok.org/). You annotate classes, members, etc. and methods are automatically generated at compile time. It's a great productivity boost and saves hundreds of lines of tedious coding.
Do you want a toString() method to be automatically generated? Just annotate your class with #ToString.
Tired of having to define getters and setters for your members? Annotate your class with #Getter and / or #Setter and they're automatically added.
Want to have an SLF4J logger to log stuff? #Slf4j creates a private static final logger for you.
#Data
public class MyBean {
// Getters for x and y, setter for y and constructor with x as arg automatically created!
// toString() and hashCode() methods are there too!
private final int x;
private int y;
}
.
#Slf4j
public class SomeClass {
public void doSomething() {
log.info("I've got log.");
}
}
Setting it up is very easy: just add a provided maven dependency. There's also a tiny Eclipse / IntelliJ plugin.
Check out the full list of features there: http://projectlombok.org/features/index.html
Junit 4 provides very useful annotations. Here's a tutorial illustrating the usage of annotations to define tests.
e.g.
#Test(expected= IndexOutOfBoundsException.class) public void empty() {
new ArrayList<Object>().get(0);
}
As Dan pointed out below, TestNG did this originally.
#Given
allows one JUnit test to build upon the return value of another test. Requires JExample.
#FunctionalInterface
Useful to communicate that a particular interface is meant to be functional. If the single abstract method is removed, it'll throw a compilation error.
I started a weekend project to implement a Programming By Contract framework using method and parameter annotations e.g.
//...
myMethod (#NotNull String a, #NotNullOrEmpty String b){
if ( !validate() ){
//raiseException
}
}
I got stuck at the point of getting param values automatically. Java reflection does not have it. never understood several people's ranting on Java till I came across this limitation.

Categories