AnnotationConfigApplicationContext has not been refreshed yet - what's wrong? - java

My very basic spring application stopped working and I can't understand what's happened.
pom.xml:
<properties>
<spring.version>4.1.1.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
Config class:
#Configuration
public class MyConfig {
#Bean
public HelloWorld helloWorld() {
return new HelloWorld();
}
}
Bean class:
public class HelloWorld {
private String message;
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Entry point of application:
public class MainApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(MyConfig.class);
HelloWorld bean = ctx.getBean(HelloWorld.class);
bean.setMessage("ladjfaj");
System.out.println(bean.getMessage());
}
}
And I'm getting an error
Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext#6ebf8cf5 has not been refreshed yet
at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:943)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:967)
at com.nikolas.config.MainApp.main(MainApp.java:12)

You have to call ctx.refresh() before you can call ctx.getBean(HelloWorld.class);

If you dont want to call ctx.refresh() explicitly, just initialize ApplicationContext like this:
new AnnotationConfigApplicationContext(MyConfig.class), then configuration will be registered and refreshed implicitly

Just in case someone has a similar issue and can´t relate directly to the example above, this may help:
I ran into the problem when I had one of my repositories outside of the folder that was included in
#EnableJpaRepositories(basePackages = {"com.myproject.repositores"})
Which lead to this first exception:
Description: Field profileRepository in
com.myproject.featurepackage.config.ProfileService required a bean of
type 'com.myproject.featurepackage.ProfileRepository' that could not
be found. The injection point has the following annotations: -
#org.springframework.beans.factory.annotation.Autowired(required=true)
When I afterwards accessed the ApplicationContext to instanciate a bean, I ran into the error
org.springframework.context.annotation.AnnotationConfigApplicationContext#4983159f
has not been refreshed yet

Related

How to find a Bean instance of MongoRepository?

I am trying to use a MongoRepository, but Spring complains, that no instance of the MonoRepository-Interface is in the context.
#SpringBootApplication
public class BackendApplication {
public static void main(String[] args) {
SpringApplication.run(BackendApplication.class, args);
}
}
#Document(collection = "tableItems")
class TableItem {
#Id
public String id;
public int roundNbr;
}
interface TableItemsRepository extends MongoRepository<TableItem, String> {
}
#Service
class TableItemsService {
#Autowired
public TableItemsService(TableItemsRepository tableItemsRepository) {
}
}
The server complains:
Parameter 0 of constructor in backend.TableItemsService required a bean of type 'backend.TableItemsRepository' that could not be found.
Action:
Consider defining a bean of type 'backend.TableItemsRepository' in your configuration.
my maven pom.xml:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.4.0</version>
</dependency>
How can I get a bean instance of my MongoRepository?
The dependency is incorrect.
spring-data-mongodb only makes it compile:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.4.0</version>
</dependency>
But you need additional dependencies, to make it run. For convenience you can import spring-boot-starter-data-mongodb, which will import all required artifacts as transitive dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

Parameter 0 of constructor in "" required a bean of type "" that could not be found

The #RestController and its setup works well. I hit a snag when I was trying to add the service to the controller and auto-wiring them.
As far as I know everything looks like they've been wired well: it builds fine, and the IDE can't detect any problems. But I seem to be lacking something because it won't run.
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in org.church.id.controller.ChapterController required a bean of type 'org.church.id.service.ChapterService' that could not be found.
Action:
Consider defining a bean of type 'org.church.id.service.ChapterService' in your configuration.
ChapterController.java
#RestController
#Log4j
public class ChapterController {
#Getter
private Map<Integer, Chapter> chapters;
private ChapterService chapterService;
#Autowired
public ChapterController(ChapterService chapterService) {
this.chapterService = chapterService;
}
public void loadChapters() throws SQLException {
log.debug("Loading chapters...");
if (chapters != null) {
chapters.clear();
}
chapters = chapterService.findAll().stream().collect(Collectors.toMap(Chapter::getId, Function.identity()));
}
#GetMapping("/chapter/list")
public String list() throws SQLException {
if (chapters == null) {
loadChapters();
}
return chapters.values().stream().map(Chapter::getName).collect(Collectors.joining(", "));
}
}
Inside my applicationContext.xml (My bad. I originally typed pom.xml)
...
<bean id="chapterController" class="org.church.id.controller.ChapterController">
<constructor-arg name="chapterService" ref="chapterService"/>
</bean>
<bean id="chapterService" class="org.church.id.service.impl.ChapterServiceImpl">
<constructor-arg name="config" ref="dbConfig"/>
<constructor-arg name="addressUtil" ref="addressUtil"/>
</bean>
...
The real pom.xml
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
...
ChapterServiceImpl.java
#Log4j
#AllArgsConstructor
#Setter
#Service
public class ChapterServiceImpl implements ChapterService {
private DBConfig config;
private AddressUtil addressUtil;
...
}
ChapterService.java (Interface)
public interface ChapterService extends Service<Chapter> {
Collection<Chapter> findByCountry(Country country) throws SQLException;
}
I've looked around here but the following have /not/ worked for me
[x] Adding (exclude = {DataSourceAutoConfiguration.class}) to #SpringBootApplication
[x] Prepending #Qualifier("chapterService") to the constructor's param: ChapterService chapterService
Also to note:
I've modified it to have only a default constructor, but the same type of error happens when I try to inject through a setter. I don't know what's wrong. :(
EDIT:
MainClassController.java
#SpringBootApplication
public class MainClassController {
private ClassInfo model;
private HashMap<Integer, String> classMap;
public MainClassController() {
loadData();
}
public void loadData() {
}
public static void main(String[] args) {
SpringApplication.run(MainClassController.class, args);
}
}
A little background: I started my project years ago, but got side tracked and now picking it up again.
What worked for me was starting with a base spring-boot project and adding my classes and fixing as I went.
As what #JoãoDias linked in the comments: https://www.baeldung.com/spring-boot-start is where I got my base spring boot. (Check Spring Initializr in the article).
Also advised by #AbhijitSarkar was that "no one uses Spring XML config anymore" which actually is a reflection on when I started this project. Very perceptive too that he was able to get the hint that my problem was due to combined internet searches.

Required a bean of type Repository that could not be found

I am setting up a new Spring project for some fun learning/tutorial at home and I seem to run into a fairly common issue but I have tried all possible solutions I found on here but with no luck. Basically what I have is as follows:
Controller class:
#RestController
#RequestMapping(value = "/shop")
public class ShopController {
#Autowired
ShopService shopService;
#GetMapping(value = "/{id}")
public #ResponseBody Shop getTestData(#PathVariable String id) {
return shopService.getShopBasedOnId(id);
}
}
Service class:
#Service
public class ShopService {
#Autowired
private ShopRepository shopRepository;
public ShopService(ShopRepository shopRepository){
this.shopRepository = shopRepository;
}
public Shop getShopBasedOnId(String id) {
return shopRepository.findByShopId(id);
}
}
Repository class:
#Repository
public interface ShopRepository extends PagingAndSortingRepository<Shop, String> {
Shop findByShopId(String shopId);
}
Application class:
#SpringBootApplication
#EnableJpaRepositories("com.example.reservations.repository")
public class ReservationsApplication {
public static void main(String[] args) {
SpringApplication.run(ReservationsApplication.class, args);
}
}
Last but not least my pom.xml with the dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>4.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
So the error code I am getting is as follows:
Description:
Parameter 0 of constructor in com.example.reservations.services.ShopService required a bean of type 'com.example.reservations.repository.ShopRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.reservations.repository.ShopRepository' in your configuration.
My structure of folders is:
main
|_java
|_com.example.reservations
|_controllers
|_ShopController.java
|_repository
|_ShopRepository.java
|_services
|_ShopService.java
|_ReservationsApplication.java
Turns out I had to have a config file for couchbase repository. What I did was follow the following link and now it all compiles fine!
The problem could be #Autowired in ShopService
#Service
public class ShopService {
#Autowired
private ShopRepository shopRepository;
public ShopService(ShopRepository shopRepository){
this.shopRepository = shopRepository;
}
public Shop getShopBasedOnId(String id) {
return shopRepository.findByShopId(id);
}
}`
should be
#Service
public class ShopService {
private ShopRepository shopRepository;
public ShopService(ShopRepository shopRepository){
this.shopRepository = shopRepository;
}
public Shop getShopBasedOnId(String id) {
return shopRepository.findByShopId(id);
}
}
You can also add #Autowired just above the constructor but it is no longer required if there is only one constructor
In my situation, I had spring boot with multiple modules. So I had to the below to make it work.
#SpringBootApplication (scanBasePackages={"com.sample.test"})
#EnableJdbcRepositories(basePackages={"com.sample.test"})
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}

Springboot javax.xml.ws.service Nullpointerexception while instantiating it

I am developing a backend using springboot. I need to implement a soap client within my springboot application but I am facing an issue that I cannot understand why it is raised and how.
#WebServiceClient(name = "WSCryptDecrypt", targetNamespace = "example", wsdlLocation = "Example")
public class WSCryptDecrypt extends Service {
private final static QName WSCRYPTDECRYPT_QNAME = new QName("Example", "WSCryptDecrypt");
public WSCryptDecrypt(URL wsdlLocation) {
super(wsdlLocation, WSCRYPTDECRYPT_QNAME);
}
}
I instantiate this class like this:
WSCryptDecrypt wsCryptDecrypt = new WSCryptDecrypt(new URL("<WSDL-URL>"));
But I get this error:
Caused by: java.lang.NullPointerException: null
at javax.xml.ws.Service.<init>(Service.java:112) ~[jaxws-api-2.3.1.jar:na]
at com.mybackend.model.WSCryptDecrypt.<init>(WSCryptDecrypt.java:43) ~[classes/:na]
I don't get why and how this error is thrown. The url of the wsdl, that I pass as parameter, is correct for sure. I tried the code outside the springboot environmente and it works well. Springboot instead is complaining throwing this error.
UPDATE:
As #Laurens suggested I tried this approach:
Annotate WSCryptDecrypt class with #Component and then into WsCryptDecryptService class I do like that
#Autowired
WSCryptDecrypt wsCryptDecrypt;
In addition I annotated WsCryptDecryptService class with #Service
UPDATE 2:
javax.xml.ws.service class when instantiated it calls this.getClass().
Maybe this is the error, Spring did not create the Service object yet, so this is null. But I don't know how may I fix that.
UPDATE 3:
New fully updated code:
#Component
#WebServiceClient(name = "WSCryptDecrypt", targetNamespace = "example", wsdlLocation = "Example")
public class WSCryptDecrypt extends Service {
private final static QName WSCRYPTDECRYPT_QNAME = new QName("Example", "WSCryptDecrypt");
public WSCryptDecrypt(URL wsdlLocation) {
// Here it throws the error
super(wsdlLocation, WSCRYPTDECRYPT_QNAME);
}
}
Service class
#Service
public class WsCryptDecryptService {
//this is the soap service
private WSCryptDecryptSoap wsCryptDecryptSoap;
#Autowired
WSCryptDecrypt wsCryptDecrypt;
/**
* Creates the service pointing to TEST Environment.
* #throws MalformedURLException
*/
public WsCryptDecryptService() {
wsCryptDecryptSoap = wsCryptDecrypt.getWSCryptDecryptSoap();
}
}
UPDATE 4
I thought that maybe it is a problem of dependency. Those are the dependency that I put in my pom for javax.xml.ws (They are more than needed just because I wanted to check that I load all the possible libraries)
<dependency>
<groupId>javax.jws</groupId>
<artifactId>javax.jws-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.jws</groupId>
<artifactId>jsr181</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.jws</groupId>
<artifactId>com.springsource.javax.jws</artifactId>
</dependency>
<dependency>
<groupId>javax.jws.jsr181-api</groupId>
<artifactId>jsr181-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.jaxws-api-2.0</artifactId>
<version>4.0-m1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>rt</artifactId>
<version>2.3.1</version>
</dependency>
Don't instantiate your services, let Spring take care of this using #Autowired. I wouldn't recommend using a constructor as this is bad practise, just call the method when you need to request your WSCryptDecryptSoap
#Service
public class WsCryptDecryptService {
#Autowired
private WSCryptDecrypt wsCryptDecrypt;
public WSCryptDecryptSoap getWSCryptDecryptSoap() {
return wsCryptDecrypt.getWSCryptDecryptSoap();
}
}

Autowired bean in spock test null after downgrading spring from 4.3.x to 3.2.x

I downgrade my application from spring 4.x to 3.x and now when I fire simple test in spock which using autowired bean, this bean is null.
#ContextConfiguration(classes = Configuration.class)
class SomeTestClass extends Specification {
#Autowired
SomeService someService
def "someService"(){
expect:
someService.returnHelloWorld() == "Hello World" // (<- NullPointer)
}
}
My pom.xml file:
<dependencies>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.12</version>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>1.1-groovy-2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>1.1-groovy-2.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.1.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
After when I downgrade also spock-core/spring to 0.6-groovy-1.8 and groovy-all to 1.8 and fire my test it throws this exception:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'someAnotherBean' defined in file
../SomeBean.class: Instantiation of bean failed; nested exception
isorg.springframework.beans.BeanInstantiationException: Could
notinstantiate bean class [..SomeBean.class]: No default
constructorfound; nested exception is
java.lang.NoSuchMethodException:..SomeBean.()
This bean contains contructor which i used to intizialize final fieds in class:
#Component
#PropertySource("classpath:someproperties.properties")
public class HeaderFactory {
private final SomeObject someObject;
public HeaderFactory(#Value("${someProperty1}") String someProperty1, #Value("${someProperty2}") String someProperty2) {
SomeObject someObject = new SomeObject(someProperty1,someProperty2);
this.someObject = someObject;
}
}
Everything worked pretty well before I dowgraded spring version. Any ideas?
You could create a configuration class and define the problematic beans there:
#Configuration
class MyConfig {
#Value("${someProperty1}") String prop1;
#Value("${someProperty2}") String prop2
#Bean
public SomeBean someBean() {
SomeBean bean = new SomeBean(prop1, prop2);
return bean;
}
}
Documentation here: https://docs.spring.io/spring/docs/3.2.0.RELEASE/spring-framework-reference/html/new-in-3.0.html#new-feature-java-config
I resolved my issue by this way:
#Component
public class UrlBuilder {
private final String host;
private final String port;
private final String protocol;
#Autowired
public UrlBuilder(Environment env) {
this.protocol = env.getRequiredProperty("app.server.protocol").toLowercase();
this.serverHost = env.getRequiredProperty("app.server.host");
this.serverPort = env.getRequiredProperty("app.server.port", Integer.class);
}
}
Source

Categories