Can't autowire a component into a utility class - java

I'm having a problem autowiring a component into a utility class. The utility class initially had static methods in it, but then I just made them instance methods.
I defined the utility class with #Component and within the class put in
class MyUtilityClass {
#Autowired
ExistingComponent existingComponent
...
}
The package the utility class is in is under the specified parent directory for #ComponentScan, where value="top-level-directory" that also contains the packages for all the other autowired components.
To get the utility class to run I had to pass the ExistingComponent into a constructor for the utility class.
Using Spring 4.1.6.
This is probably something basic, but it's not clicking. What am I missing here?
Thanks.
UPDATE 1
The class that is calling the utility class looks like the following:
class UsingClass {
#Autowired
MyUtilityClass myUtilityClass
...
def method1() {
String variable1 = "some data"
myUtilityClass.utilityMethod(variable1)
...
}
}
Originally I had the internal utility method as static and tried to use the utility class without autowiring it.

Do you have this somewhere within your beans XML configuration files?
<context:component-scan base-package="com.your.package" />
The base-package indicates where your components are stored.
This allows Spring to scan the package so that it can find the beans annotated with #Component.
This is explained in more depth here.

Related

Is it OK to inject value directly inside Bean function?

I was wondering how to do dependency injection in the most effective way inside my code.
I have this code:
#Configuration
public class SomeName {
#Autowired
private Other other;
#Bean
public void method() {
other.someMethod();
// some code
}
}
Can this code be changed into the following code(other will be used only inside this function)?
#Configuration
public class SomeName {
#Bean
public void method(Other other) {
other.someMethod();
// some code
}
}
You should avoid #Autowired if possible and inject using a constructor or method.
Starting with Java 9 and java modules (project jigsaw) there are some strict rules that make it harder for your framework to change the values of a private field.
What Spring is doing in the first example is essentially that - it breaks encapsulation to change the value of a private value. (There is a way to overcome this with "opens" directive in module-info..)
You are also becoming dependent on the framework you are using and your code becomes harder to test compared to when using a simple setter.
You are also not explicitly declaring that your class depends on another class since I can easily instantiate it and "Other" will be null.
Some resources:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-scanning-autodetection (search for jigsaw)
https://blog.marcnuri.com/field-injection-is-not-recommended/
PS: You are probably missing #Configuration on your class

How do I fix Dagger 2 error '... cannot be provided [...]'?

This is a Canonical Question because this is a common error with Dagger 2.
If your question was flagged as a duplicate please read this post carefully and make sure to understand what this error means and why it occured. If this post does not work for you make sure to include where and how you provide the mentioned classes and include the full error message in your question like the one here.
I tried to use a dependency with Dagger 2, but I receive the following error when I try to compile my project:
error: com.example.MyDependency cannot be provided without an #Inject constructor or from an #Provides-annotated method.
com.example.MyDependency is provided at
com.example.MyComponent.myDependency()
What does this mean and how can I fix it?
I have a component and tried to provide a dependency. My basic setup looks like this:
// this is the dependency I try to use
class MyDependency {}
#Component
interface MyComponent {
// I want to make it accessible to be used with my component
MyDependency myDependency();
}
tl;dr You forgot to either add an #Inject to your constructor so that Dagger can use Constructor Injection to provide the object, or you need some method in one of your Modules that creates or binds the object.
What's going on?
Have a good look at the error message: It states that you try to request a dependency but Dagger has no way to provide or create it. It simply does not know how to, because it cannot be provided without an #Inject constructor or from an #Provides-annotated method.
A close look at the error message shows the class (a) that you are trying to provide and the component (b) that needs it.
com.example.MyDependency (a) is provided at
com.example.MyComponent.myDependency() (b)
You have to make sure that (b) can create or provide (a) to fix your issue.
It looks a bit more complex if you tried to inject your dependency somewhere else, but you can still see the full stack of events—in this case a constructor injection missing a dependency. The class (a) that you are trying to provide and the location (b) where Dagger tried injecting it. It also tells you where that dependent class was created (c) and again the component (d) that failed providing (a).
com.example.MyDependency cannot be provided without an #Inject constructor or from an #Provides-annotated method.
com.example.MyDependency (a) is injected at
com.example.DependentClass.(dependency) (b)
com.example.DependentClass is provided at (c)
com.example.MyComponent.myDependency() (d)
The same applies here: Make sure that (d) knows how to provide (a) and you're good to go.
How do I fix this?
Have a look at the error as shown above. Make sure you understand where it occured and what you are trying to inject. Then tell Dagger how to provide your object.
an #Inject constructor
As the error states, you try to use MyDependency but MyComponent does not know how to do that. If we have a look at the example it becomes clear why:
class MyDependency {}
The class has no #Inject annotated constructor! And there is no other module in the component, so there is nothing Dagger could do.
If you want to use constructor injection you can just add an #Inject annotated constructor and are done. Dagger will see this constructor and know how to create your class.
class MyDependency {
#Inject
MyDependency() { /**/ }
}
That is all you have to do when you can make use of constructor injection.
from an #Provides-annotated method
The error message states a second option, which allows you to provide an object if you don't want—or can't—use constructor injection. You can also add a #Provides annotated method to a module and add this module to your component.
#Module
class MyModule {
#Provides
MyDependency provideMyDependency() {
return new MyDependency();
}
}
#Component(modules = MyModule.class)
interface MyComponent {
MyDependency myDependency();
}
This way Dagger can use your module to create and provide your dependency. It is a little bit more boilerplate than using Constructor Injection, but you will have to use Modules for everything that needs further setup or that does not have an annotated constructor, e.g. third party libraries like Retrofit, OkHttp, or Gson.
There are also other ways to provide a dependency from a component. A #SubComponent has access to its parents dependencies, and a component dependency can expose some of its dependencies to its dependent components. But at some point everything Dagger provides needs to either have an #Inject constructor or a Module providing it.
But I did add MyDependency!
Pay close attention to the details. You probably are using an interface when you are only providing the implementation, or try to use a parent class when Dagger only knows about the subclass.
Maybe you added a custom #Qualifier or used #Named("typeA") with it. To Dagger this is a completely different object! Double check that you actually provide and request the same dependency.
Read the error and make sure that you either have an #Inject annotated constructor, a module that has a #Provides method that provides that type, or a parent component that does.
What if I want to provide an implementation for my interface?
A simple example like the following shows how one class extends another:
class MyDependency extends MyBaseDependency {
#Inject MyDependency() { super(); }
}
This will inform Dagger about MyDependency, but not about MyBaseDependency.
If you have one class implementing an interface or extending a super class you have to declare that. If you provide MyDependency this does not mean that Dagger can provide MyBaseDependency. You can use #Binds to tell Dagger about your implementation and provide it when the super class is required.
#Module
interface MyModule {
#Binds
MyBaseDependency provideMyBaseDependency(MyDependency implementation);
}

Testing Jersey app, Injecting classes using Jersey Injection built-in framework (HK2)

I need to create tests for some class. This class in main project (src/main/java/..) is injected easily into another classes, since I have custom ResourceConfig class which declares which packages have to be scanned to seek for service classes.
Now I created test directories (in src/test/java/..) and created a class, something like:
public class TheMentionedClassIntegrationTest {
#Inject
private TheMentionedClass theMentionedClass ;
#Test
public void testProcessMethod() {
assertNotNull(theMentionedClass);
}
}
But the problem is that whatever I do the class is always null. In another tests in the project I was using JerseyTest class. So I tried to do the same here, extend TheMentionedClassIntegrationTest with JerseyTest, override configure method, create my private ResourceConfig class which registers Binder (default for whole project) and register TheMentionedClassIntegrationTest as well.
It didnt work. I did many different attempts but none of them were successfull. I think working with HK2 is extremly difficult, there is no good documentation or so..
Do you guys have an idea how to inject TheMentionedClass into the test class? Maybe my approach is wrong?
Thanks!
The easiest thing to do is to just create the ServiceLocator and use it to inject the test class, as see here. For example
public class TheMentionedClassIntegrationTest {
#Inject
private TheMentionedClass theMentionedClass;
#Before
public void setUp() {
ServiceLocator locator = ServiceLocatorUtilities.bind(new YourBinder());
locator.inject(this);
}
#Test
public void testProcessMethod() {
assertNotNull(theMentionedClass);
}
}
You could alternatively use (make) a JUnit runner, as seen here.
For some other ideas, you might want to check out the tests for the hk2-testing, and all of its containing projects for some use case examples.

Where to place a private method that shared by multiple Spring java config file?

I have several Spring Java config classes and they have same private method. Should I create the private method in each Java config class or do I have other options to avoid listing duplicate method. By the way, I have a CommonConfig.java class imported by all other config classes. Can I make the private method and place it inside CommonConfig.java?
By the way, all other Spring Java Config classes import CommonConfig like bellow.
#Import({ CommonConfig.class, })
You can initialize the method in CommonConfig.java class, do not make it private else the extending classes won't be able to use it.
If the implementation of that method is different as per the classes you can make an interface & declare that method in that.

Need some help to understand Anotations - Spring annotations

I am trying to learn Spring and Hibernate and i am really struggling to understand Annotations and how they work. Most of the example i am seeing on the Internet are annotation based examples so i need to understand how the annotations work first before i can learn Spring or Hibernate
I have an idea of what they are and what they are used for. I know that they replace the xml configuration. I.e. You can configure beans directly within Java code using annotations. What i dont understand is how to use them and when they can be used.
Trying to understand how this can be done i think it would be helpful if i see the difference between the two. I have here a simple Spring program. If i was to convert this sample program to use annotations what would i need to do?
The reason i want to do it this way is because the program i have provided below is one that i understand very well (an example from the Spring in Action book that i am currently reading). If it is converted to an annotations version i will get an idea as to how and where annotations can be used.
Any suggestions?
Thanks in advance
instrumentalist.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="saxophone" class="com.sia.ch1.instrumentalist.Saxophone" />
<bean id="piano" class="com.sia.ch1.instrumentalist.Piano" />
<!-- Injecting into bean properties Ken 1 -->
<bean id="kenny" class="com.sia.ch1.instrumentalist.Instrumentalist">
<property name="song" value="Jingle Bells"/>
<property name="instrument" ref="piano"/>
</bean>
</beans>
Instrumentalist interface
package com.sia.ch1.instrumentalist;
public interface Instrument {
void play();
}
Instrumentalist implementor
package com.sia.ch1.instrumentalist;
import com.sia.ch1.performer.PerformanceException;
import com.sia.ch1.performer.Performer;
public class Instrumentalist implements Performer{
private Instrument instrument;
private String song;
public Instrumentalist(){}
public void perform() throws PerformanceException{
System.out.print("Playing " + song + " : ");
instrument.play();
}
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
public void setSong(String song) {
this.song = song;
}
}
Instruments - Piano
package com.sia.ch1.instrumentalist;
public class Piano implements Instrument{
public Piano(){}
public void play(){
System.out.println("PLINK PLINK");
}
}
Instruments - Saxophone
package com.sia.ch1.instrumentalist;
public class Saxophone implements Instrument{
public Saxophone(){}
public void play(){
System.out.println("TOOT TOOT TOOT");
}
}
Main class
package com.sia.ch1.instrumentalist;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import com.sia.ch1.performer.PerformanceException;
import com.sia.ch1.performer.Performer;
public class InstrumentalistApp {
public static void main(String[] args){
ApplicationContext ctx = new FileSystemXmlApplicationContext("c:\\projects\\test\\conf\\instrumentalist.xml");
Performer performer = (Performer) ctx.getBean("kenny");
try {
performer.perform();
} catch (PerformanceException e) {
e.printStackTrace();
}
}
}
Exception
package com.sia.ch1.performer;
public class PerformanceException extends Exception {
public PerformanceException() {
super();
// TODO Auto-generated constructor stub
}
public PerformanceException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public PerformanceException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public PerformanceException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
Edit 1
To try and convert the above i am going through these two simple examples:
Ex1: http://jroller.com/habuma/entry/reducing_xml_with_spring_2
Ex2: http://www.theserverside.com/tutorial/Spring-Without-XML-The-Basics-of-Spring-Annotations-vs-Spring-XML-Files
I kind of understand the examples in the first URL but the second one confused me a bit. In the example in the second URL, what is purpose of the SummaryConfig class? It looks as though the SummaryConfig class is a Java version of the XML file. This approach was not used in the example in the first example. What is the difference between the two?
Could it be that when you using annotations you can put the configuration details in a Java class (e.g. SummaryConfig) and you can also put the annotations in the beans themselves as in the examples in the first URL?
Thanks
Edit 2
Here is what i have done so far,
I have modified the xml document to remove the configuration and enable the auto-scan of components (Note: i changed the package name for the modified versions)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="com.sia.ch1.instrumentalist.annotate" />
</beans>
Added the #Component annotation to the Piano and Saxophone classes. I think this tells the container that this class should be included in the classes to be auto-scanned. right?
package com.sia.ch1.instrumentalist.annotate;
import org.springframework.stereotype.Component;
#Component
public class Piano implements Instrument{
public Piano(){}
public void play(){
System.out.println("PLINK PLINK");
}
}
package com.sia.ch1.instrumentalist.annotate;
import org.springframework.stereotype.Component;
#Component
public class Saxophone implements Instrument{
public Saxophone(){}
public void play(){
System.out.println("TOOT TOOT TOOT");
}
}
This is where i am stuck (the Instrumentalist class).
Is the #Component annotation required in this class? Or is it only required if the class is to be referenced from another class?
I know that i need to #Autowire the instrument and song properties but how do i know if i want to autowire byname or bytype etc
How would i autowire the String property if in this class there is no bean that represents it? i.e the instrument property would refer to the piano class but what would the song property be autowired with?
package com.sia.ch1.instrumentalist.annotate;
//
import org.springframework.stereotype.Component;
import com.sia.ch1.performer.PerformanceException;
import com.sia.ch1.performer.Performer;
//
#Component
public class Instrumentalist implements Performer{
private Instrument instrument;
private String song;
public Instrumentalist(){}
public void perform() throws PerformanceException{
System.out.print("Playing " + song + " : ");
instrument.play();
}
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
public void setSong(String song) {
this.song = song;
}
}
I think i am right in that no annotations are required on any of the other classes.
Thanks
This is where i am stuck (the Instrumentalist class).
Is the #Component annotation required in this class? Or is it only
required if the class is to be referenced from another class?
Yes, it is, if you want the annotation scanning to create the bean from the class for you without separate xml-configuration. Since you ask for an Instrumentalist -implementation with the bean name kenny (by name, not by type Instrumentalist) in your main-method, it also needs to be named.
Classes annotated with #Component, #Repository, #Controller and #Service are the ones that Spring scans for when the ApplicationContext is configured. The difference between these four annotations is semantical (differentiating the role of the class in the code), they all do exactly the same thing (unless for example you have some AOP-stuff that handles only certain annotation-types; for now you don't need to care about this).
Annotating a class with of any of the aforementioned annotation is same as declaring a bean in the xml:
<bean id="saxophone" class="com.sia.ch1.instrumentalist.Saxophone"> ... </bean>
is same as
#Component
public class Saxophone implements Instrument{
Note that by default the bean is named same as the class, except the first letter of the class name is changed to lowercase (so #Component public class SomeClass would create a bean called "someClass").
If you want to name your bean, you give the name as a parameter to the annotation:
#Component("kenny")
public class Instrumentalist implements Performer {
is same as
<bean id="kenny" class="com.sia.ch1.instrumentalist.Instrumentalist">
Another way to give the parameter to the annotation would be using #Component(value="kenny"). The reason the value= -part is optional, is because the annotations work like this: if there is only one parameter given without telling the field-name and the annotation contains a field called value, the parameter will be set to the value-field. If the field name is something else, or you want to set multiple fields of the annotation, you need to explicitly define the fields: #SomeAnnotation(field1="some string", field2 = 100) or #SomeAnnotation(value="someValue", anotherField="something else"). This is a bit besides the point, but it's good to know, as it can be confusing at first.
So, the #Component-annotation tells the Spring context that you want to create a bean (or beans, see #Scope) from the annotated classes. When there's no #Scope -annotation set, the beans will be created as singletons by default (you can autowire the bean to multiple classes, but they all see the same, single instance). For more information about the different scopes, I suggest reading the official documentation.
I know that i need to #Autowire the instrument and song properties
but how do i know if i want to autowire byname or bytype etc
Usually, if you only have a single implementation of a type (interface), it's more convenient to autowire by type. Autowiring by type works, when there is only a single implementation, because otherwise Spring cannot decide which implementation to instance and inject.
In your case you have two different classes implementing the Instrument-interface: Saxophone and Piano. If you try to autowire by-type the Instrument-field of the Instrumentalist, you will get an exception when Spring is constructing the Instrumentalist-bean:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.sia.ch1.instrumentalist.annotate.Instrument] is defined: expected single matching bean but found 2: [piano, saxophone]
Since there are two Instrument-implementations, Spring doesn't have enough information to determine which one you want injected in the Instrumentalist. This is where the #Qualifier -annotation steps in. With the #Qualifier, you tell Spring to inject the autowired dependency by-name. To inject the Piano-implementation of Instrument using the #Qualifier in the Instrumentalist is done by:
#Component(value="kenny")
public class Instrumentalist implements Performer
{
#Autowired
#Qualifier("piano")
private Instrument instrument;
is same as
<bean id="kenny" class="com.sia.ch1.instrumentalist.Instrumentalist">
<property name="instrument" ref="piano"/>
</bean>
Note that there's no need (but you can if you want to) to use #Component("piano") in the Piano-class, as the default naming changes the first letter of the class to lowercase and then uses it as the bean-name.
How would i autowire the String property if in this class there is no bean that
represents it? i.e the instrument property would refer to the piano class but what would > the song property be autowired with?
This is where the line is drawn with annotations (AFAIK); you cannot declare a bean of type String with annotations (Since java.lang.String is not an interface, cannot be extended as it's final and doesn't have an interface). However, with xml-configuration this is possible:
<bean id="songName" class="java.lang.String">
<constructor-arg value="Valley of the Queens"/>
</bean>
You can mix-and-match XML and annotations, and refer to beans declared in xml from annotations and vice versa, to inject this bean into Instrumentalists' song-field:
#Autowired
#Qualifier("songName")
private String song;
Hope this helped you to understand Springs' annotations in general and get started, I'd still strongly suggest you to read the official documentation, as there's a LOT more. If you prefer to read books instead of from screen, I'd suggest for example Appress's Spring Recipes (but I'm sure there are many other good books too).
Annotations could be used as markers like marker interfaces
class Foo implements java.io.Serializable{
...
}
Serializable is just a marker interface so that your application can know information about
the class at runtime (basically by reflection).
The problem with marker interfaces is that you can't use them to mark fields or methods,this why annotations were introduced.
assume that you have this annotation
public #interface myAnnotation{
}
you can simply get methods or fields which are decorated by this marker at run-time.
Hibernate and Spring as many frameworks require some information about your code or classes ,how would you achieve this,if you were the developer of these frameworks ?of course annotations are the best solution(at least the cleaner way)
Don't consider marker interfaces obsolete.There is also some advantages for using markers because they ensure type safety.
void M(Serializable s)
you can't pass any object to this method unless it implements the Serializable marker.For more details consider reading Effective Java there is a great explanation there.

Categories