Warning: field is used but is never assigned a non-"null" value - java

I have implemented a Java EE page which connects to an inventory webservice. I have implemented an inventory controller as shown below:
public class InventoryController {
#Autowired
private WebServiceTemplate inventoryWsTemplate;
...
}
inventoryWsTemplate is declared as a bean in web-servlet.xml.
The program works but I'm getting a warning that says:
field is used but is never assigned a non-"null" value
What should I do?

Just add a SuppressWarnings annotation:
#Autowired
#SuppressWarnings("null")
private WebServiceTemplate inventoryWsTemplate;
Normally I'd add a comment to justify the annotation (e.g. // Used by guice) but in this case coming hot on the heels of an Autowired annotation, I don't think it's necessary.
EDIT: I can't reproduce the problem on Eclipse to start with, so I'm not sure which annotation value is required. You should check the list of supported annotation values for your compiler.

If you don't like suppressing warnings, you can change private to any other access modifier. Package-private probably being the best choice (besides private).

Related

PMD Ignore Spring Field Injections in gradle config

Currently I have several Controllers that inject dependencies through a field marked with #Autowired. When I try to run gradle build the following violations come up.
These all correspond to the instances of where a spring component has been injected.
I am aware of the ignoreAnnotations property that seems to exist for PMD, however, I am not sure if one can actually specify this in a gradle configuration?
Any help would be appreciated.
The root cause is: field injection is code smell and bad design practice.
When #Autowired is used on a non-transient field it can cause issues with serialization. This is because the field will not be properly initialized when the object is deserialized, leading to a NullPointerException when the object is used.
To fix this issue either make the fields transient or -- much better -- use constructor injection. To use constructor injection add a constructor to your class that takes all of the required dependencies as arguments, and annotate the constructor with #Autowired (the annotation is optional in modern Spring versions).
#Component
class MyClass {
private final Dependency1 dependency1;
private final Dependency2 dependency2;
#Autowired
public MyClass(Dependency1 dependency1, Dependency2 dependency2) {
this.dependency1 = dependency1;
this.dependency2 = dependency2;
}
}

Is it possible to make Optional<T> and #Lazy work together in Spring?

I have to make me #Component #Lazy as it is used rarely and creates circular dependency problem
I have to make it Optional<T> because feature it represents can be disabled on startup (#ConditionalOnProperty) so it might not be available at runtime
Problem:
When I use Optional<T> as injection point, bean is initialized eagerly.
So the questions:
Is it possible to make it work like that?
Can I replace Optional<T> with Provider<T>? will it simply return null if feature is disabled or it will throw exception?
Can it be replaced with ObjectProvider<T>?
I would like to stick to #Resource or #Inject annotation so #Autowired(required=false) will be last resort for me.
There is no code to share here actually (as it would be class and field declarations as those are relevant onl IMHO)
Since you do not belive me the code is worthless here, let me share :)
#Comonent
#Lazy
public class MyType{
}
injection point
#Lazy
#Autowired
private Optional<MyType> myType;
usage
MyType instance=myType.getOrThrow(()->throw something)
Iv tested Optional and debugger hits MyType upon application startup. It is skipped when I use plain field, provider or object provider.
In situations like this I do not wire the Component directly, but lazily. There are different options:
Go through the ApplicationContext and retrieve MyType when you need it. You would only retrieve it, when you know it is enabled:
#Autowire
private ApplicationContext context;
...
MyType instance = context.getBean(MyType.class);
Provider or Factory approach, where you have an autowired service which provides you an instance of MyType. This service is also only called when the feature is enabled.
#Autowire
private MyTypeFactory factory;
...
MyType instance = factory.getMyType();
Using the Provider would require you to define a bean in your configuration, so it might be easier to just have a POJO service on which you can slap #Service, that does the same.
Let me present an alternative Point of View. I think that using Optional dependency for this is not justified.
The class that has an Autowired MyType probably counts on this dependency (notwithstanding the fact that usage of Optional for data fields if a kind of bad practice).
The reason for Laziness of the component also seems to be more "hack" than intention (circular dependency is never a good thing).
So, if we'll pretend that this class makes something "Optionally available", one way is to provide an additional no-op implementation for this MyType problematic bean:
interface MyType {
void doSomeHeavyStuff();
}
public class MyTypeRegularImpl() implements MyType {
public void doSomeHeavyStuff() {
....work..work..work..
}
}
public class NoOpMyType implements MyType {
public void doSomeHeavyStuff() {
// do nothing here
}
}
Now the trick is to provide two mutually exclusive conditions and make sure that only one bean out of these two loads (otherwise it will produce an ambiguity in beans and probably fail during the application startup).
So the class that uses MyType won't need Optional at all.
Now regarding the Laziness.
In general, Lazy beans only get ini
Lazy Bean can still be used since the bean will be initialized during the first call in a class that has that lazy dependency.
For no-op beans it won't matter at all.

Is it possible to add annotations to static factorymetods with lombok

If I create a class like
#Value
#AllArgsConstructor(staticName = "of", onConstructor = #__(#JsonCreator))
public class Test {
String value;
}
The onConstructor properties is added to the constructor (which makes sense). However I need to add an annotations to the factory metod. Is this possible?
My root problem is trying to make
{
"test": 2018
}
deserialize to:
SomeJavaClass:
private final Test test
This doesn't work because of the ConstructorProperties.
Putting the annotation on the static factory method would be the most reasonable thing to do when both staticName and onConstructor are set. In that case, the regular constructor becomes private and, thus, cannot be used from elsewhere (except for ugly reflection tricks). Therefore, annotations only make sense on the static factory method in most cases.
However, this is not Lombok's current behavior, and there is no way to configure Lombok differently. I suggest you create a feature request at GitHub.
However, be aware that the onX feature is an experimental feature, so this feature request may be declined or deferred.

Why not #NotNull anotation remove the warning?

I have wrote a class that implements the comparable interface. I used #NotNull annotation to suppress the waring in the method parameter. But it still shows a warning.The IDE automatically import this package com.sun.istack.internal.NotNull for the #NotNull. Why this is happing? Without using this annotation how to remove this warning ?
I am using Inteij Ultimate with java 8 SE.
Here is my code snippet.
Thank you.
Apparently, you should be using
public int compareTo(#NonNull Node node) {
instead of
public int compareTo(#NotNull Node node) {
The compiler can determine cases where a code path might receive a null value, without ever having to debug a NullPointerException.
From here.
For these annotations you need Checker Framework installed. Or you can try what the other answer says.
Change your import, you can use intellij's own com.intellij.annotations.NotNull, javax.annotation.Nonnull or javax.validation.constraints.NotNull.
This is an IntelliJ feature and it was actually possible to configure which nullable/notnull annotation to use, see this guide.
If this doesn't fix it, and the message seems to imply this, try removing the #override, you are adding an annotation to a parameter that didn't have it in the super class.

User defined Validations coupling issue

Have an API defined that clients will be able to utilize. Clients will be connected via a variety of means. One of them is java-to-java. In this specific case, am having an issue. Obviously, the API should be as decoupled from the implementation as possible. I haven't had the chance to test this yet, but won't user defined validations break this model?
I am enabling the Validation via Spring #Validated on the API server-side implementation. Did not want to put this into #Controller class as that is not the only way into the service (API).
For example, if I have this method defined in the Interface:
SomeObject updateOperation( AnInputClass param) ...
I can then annotate with JSR-303 validations and still be de-coupled:
#NonNull
SomeObject updateOperation( #NonNull AnInputClass param) ...
But if I want custom validation on the various pieces/parts of the input "param", I need to make my own Annotation, which has an #Constraint(validatedBy) part This part will tie to the validation implementation. The abbreviated form of this would look like:
SomeObject updateOperation ( #CheckInput AnInputClass param)...
...where the annotation is defined as
...
#Constraint(validatedBy = CheckInputValidator.class) // this is the coupling issue
public #interface CheckInput { ....
Since this all happens server-side, there should be no need to have Java clients have to have this CheckInputValidator class; however, I am seeing no options. First, I like having the validations in the API - they tell users what will be validated. If I could break the dependency and move the validation down to the implementation that would seem like an acceptable tradeoff. However that results in the exception below so it seems like I am stuck. Can anyone help?
javax.validation.ConstraintDeclarationException: Only the root method of an
overridden method in an inheritance hierarchy may be annotated with parameter
constraints, but there are parameter constraints defined at all of the
following overridden methods
Found the answer myself, I should have realized this earlier!
All I needed to do was to use the "#Valid" annotation in the interface/API layer. Then, making sure the #Target annotation on the User Defined / Custom annotation has "TYPE" defined, apply the #CheckInput annotation to the desired class and everything works perfectly!

Categories

Resources