I am trying to run my first junit class in eclipse. When I right click on the new class and select run as junit it gives me a failed to load applicationcontext error. The direct path to the spring-servlet.xml is correct.
Here's the code:
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"file:C:/MyProject/WEB-INF/spring-servlet.xml"
})
public class MyUnitTest {
#Autowired
private ApplicationContext applicationContext;
#Before
public void setUp() {
}
#Test
public void testFunctionality() throws Exception {
assertTrue(true);
}
}
error -
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'aop:scoped-proxy'.
The direct path to the
spring-servlet.xml is correct.
No, it's not. If it was, JUnit would have found it.
I think it should look like this:
#ContextConfiguration(locations={"file:///C:/MyProject/WEB-INF/spring-servlet.xml"
http://en.wikipedia.org/wiki/File_URI_scheme
UPDATE:
The error message you posted says you did read the context XML, but there's an error.
I find that it's helpful to paste any error message I get into Google. When I did that with yours, it sent me this:
http://forum.springsource.org/showthread.php?35417-The-matching-wildcard-is-strict-but-no-declaration-can-be-foun...-aop-scoped-proxy
Check for missing JARs.
Related
I have a spring boot application I'm building, and at the start, I need to check some system files and prepare some database pools using the information the app finds there. Normally, I'd include this in the main method of the #SpringBootApplication annotated class, however, when I deploy my app as a WAR file to an external Tomcat server, that main class doesn't seem to run. I've checked around at what you're supposed to have in that main class, and my main application class now looks like this:
package com.companyname.projectname;
import com.companyname.projectname.database.DatabasePoolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class WebApplication extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(WebApplication.class);
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(WebApplication.class, args);
DatabasePoolManager dpm = applicationContext.getBean(DatabasePoolManager.class);
dpm.setUpPools();
logger.error("\n\nIS ANYBODY OUT THERE?\n\n");
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
logger.error("\n\nIS ANYBODY OUT THERE? (But in the configure method)\n\n");
return builder.sources(WebApplication.class);
}
}
This is different than my original setup because of the extends and override of configure.
So far, this still runs fine with my Intellij IDE, but once moved and deployed to the tomcat server, none of the log messages appear. The app still works, but is clearly missing some setup that grants it's functionality (connections to databases). How would I go about running some setup code on the application start, when I deploy this app as a WAR file?
Thanks again to M. Deinum in the comments above, to run once on startup, I used this new class shown below:
package com.companyname.projectname;
import com.companyname.projectname.database.DatabasePoolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
#Component
public class AppStartupRunner implements ApplicationRunner {
#Autowired
ApplicationContext applicationContext;
private static final Logger logger = LoggerFactory.getLogger(AppStartupRunner.class);
#Override
public void run(ApplicationArguments args) throws Exception {
DatabasePoolManager dpm = applicationContext.getBean(DatabasePoolManager.class);
dpm.setUpPools();
}
}
I have a new springboot application I am attempting to get started.
The error I receive is
org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ReactiveWebApplicationContext due to missing ReactiveWebServerFactory bean.
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:76) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
src/main/java/bubbleshadow/RootController.java
package bubbleshadow;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
#RestController
public class RootController {
public RootController() {
}
#GetMapping("/")
public Mono<HttpStatus> returnOk() {
return Mono.just(HttpStatus.OK);
}
}
src/test/java/test/bubbleshadow/RootControllerTest.java
package test.bubbleshadow;
import bubbleshadow.RootController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes=RootController.class, webEnvironment = WebEnvironment.RANDOM_PORT)
#AutoConfigureWebTestClient
public class RootControllerTest {
#Autowired
WebTestClient webTestClient;
#Test
public void baseRouteShouldReturnStatusOK() {
webTestClient.head().uri("/").exchange().expectStatus().isOk();
}
}
Your configuration is not sufficient for reactive tests.
The reactive WebTestClient as well as ReactiveWebApplicationContext need reactive server in the application context. Add annotation #EnableAutoConfiguration to your RootControllerTest and let Spring's do it for you.
The autoconfiguration searches your class path and after find reactive classes and reactive context then create ReactiveWebServerFactory bean.
I assume you are using maven to get your dependencies.
I solved the problem by using:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
Instead of:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
For me, the error was being caused by a missing #SpringBootApplication annotation on the Spring class containing the main() method entry point which actually starts the Boot application. Using the following resolved the error:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Likely a corrupt download. Try removing ~/.m2/repository.
You actually just need to change webEnvironment = WebEnvironment.RANDOM_PORT to webEnvironment = WebEnvironment.MOCK in your #SpringBootTest annotation.
#vdou's answer helped me to resolve my issue.
In addition to adding #EnableAutoConfiguration, I also had to manually add the spring application type:
spring:
main:
web-application-type: reactive
There is obviously something in my dependencies that is causing Spring not to be able to discover the type.
I hope this helps somebody...
If you are using Kotlin, check if in your Application class that contains the main method, doesnt have this:
runApplication<Application>{
webApplicationType = WebApplicationType.REACTIVE
}
Then change the "REACTIVE" to "SERVELET", will work like a charm.
If None of the above solutions work, try adding
#ContextConfiguration(loader = AnnotationConfigContextLoader.class)
It may help you
import org.springframework.test.context.support.AnnotationConfigContextLoader;
Yet another reason this can occur is if you're importing in a configuration class for your test that is not marked with #TestConfiguration annotation
I'm learning Spring as it seems to be a very powerful framework. I've already did many getting started guides and now I'm trying with this tutorial. In it, all classes are put in the same package, but to make it more interesting I tried using different packages according to the class (entity, controller, etc.). I was about to test it before the Testing a REST Service section but got an error building the application. This is how my project is structured:
The only difference with the classes in the tutorial is the marked ServletInitializer which comes with the initializr utility (actually I used the one that comes with STS, but it's the same). As far as I understand, it has nothing to do with the problem so the content of this class is irrelevant.
Another minor difference with the tutorial is that the Application class here is called RestServicesApplication but the content is the same.
When I try to build the application (using Gradle's bootRun instead of Maven) I got the following error message:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method init in com.example.restservices.RestServicesApplication required a bean of type 'com.example.repository.AccountRepository' that could not be found.
Action:
Consider defining a bean of type 'com.example.repository.AccountRepository' in your configuration.
:bootRun FAILED
So I tried to annotate AccountRepository with #Bean but it gives me a compilation error saying that the annotation is disallowed for that location. Next I tried with the #Component annotation (also on BookmarkRepository) and adding #ComponentScan("com.example") in RestServicesApplication. After that the error remains but the message changed to
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.controller.BookmarkRestController required a bean of type 'com.example.repository.BookmarkRepository' that could not be found.
Action:
Consider defining a bean of type 'com.example.repository.BookmarkRepository' in your configuration.
:bootRun FAILED
I added #Component annotation to BookmarkRestController but the same error message remains. What am I missing here?
Thanks in advance for your answers.
Edit #1
The classes involved in the problem are the following (copied from my project, not the ones in the tutorial, although the differences are minimal):
RestServicesApplication
package com.example.restservices;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import com.example.entity.Account;
import com.example.entity.Bookmark;
import com.example.repository.AccountRepository;
import com.example.repository.BookmarkRepository;
#SpringBootApplication
#ComponentScan("com.example")
public class RestServicesApplication {
public static void main(final String[] args) {
SpringApplication.run(RestServicesApplication.class, args);
}
#Bean
CommandLineRunner init(final AccountRepository accountRepository,
final BookmarkRepository bookmarkRepository) {
return (evt) -> Arrays.asList(
"jhoeller,dsyer,pwebb,ogierke,rwinch,mfisher,mpollack,jlong".split(","))
.forEach(
a -> {
final Account account = accountRepository.save(new Account(a,
"password"));
bookmarkRepository.save(new Bookmark(account,
"http://bookmark.com/1/" + a, "A description"));
bookmarkRepository.save(new Bookmark(account,
"http://bookmark.com/2/" + a, "A description"));
});
}
}
BookmarkRestController
package com.example.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.repository.AccountRepository;
import com.example.repository.BookmarkRepository;
#RestController
#RequestMapping("/{userId}/bookmarks")
public class BookmarkRestController {
private final BookmarkRepository bookmarkRepository;
private final AccountRepository accountRepository;
#Autowired
public BookmarkRestController(final BookmarkRepository bookmarkRepository,
final AccountRepository accountRepository) {
this.bookmarkRepository = bookmarkRepository;
this.accountRepository = accountRepository;
}
// #RequestMapping methods...
}
AccountRepository
package com.example.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import com.example.entity.Account;
#Component
public interface AccountRepository extends JpaRepository<Account, Long> {
Optional<Account> findByUsername(String username);
}
BookmarkRepository
package com.example.repository;
import java.util.Collection;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import com.example.entity.Bookmark;
#Component
public interface BookmarkRepository extends JpaRepository<Bookmark, Long> {
Collection<Bookmark> findByAccountUsername(String username);
}
Note: I added the imports so you can see where the classes and annotations come from
Edit #2
I tried another thing: I refactored my Project to fit the tutorial and I put everithing in the same package (com.example.bookmarks) and removed the extra annotations. The Project compiles but when I run the Project I get a 404 HTTP status when trying to accesss a REST service. I'm still interested in make it run with my original structure but I want to let you know that this refactoring makes the Project work.
To have Spring create a bean that implements JpaRepository interface, you need to use Spring JPA namespace and activate the repository support using the appropriate element. In xml:
<jpa:repositories base-package="com.example.repository" />
In annotation:
#EnableJpaRepositories
See this docs
This scans all packages below com.example.repository for interfaces extending JpaRepository and creates a Spring bean for it that is backed by an implementation of SimpleJpaRepository.
I think you have to create package again. You packing looking not right. Recreate your package
I have the following test code:
package soundSystem;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class )
#ContextConfiguration(classes = CDPlayerConfig.class)
public class SonyCDPlayerTest {
#Autowired
private ICompactDisk cd;
#Test
public void cdShouldNotBeNull() {
assertNotNull(cd);
}
}
This is a maven project, the problem is the exact same code would run in eclipse, but not in intellij.
I just can't find a way to resolve #RunWith
The #RunWith annotation has been replaced with #ExtendWith in JUnit 5.0 and above (which the latest spring version is now using).
Example:
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = { SpringTestConfiguration.class })
public class GreetingsSpringTest {
// ...
}
Quoted from Baeldung:
Note that SpringExtension.class is provided by Spring 5 and integrates
the Spring TestContext Framework into JUnit 5.
Ref: https://www.baeldung.com/junit-5-runwith
Simple: your IDE is not configured to for unit testing.
In other words: you are missing all the JUnit related classes. You can see that all those JUnit imports are underlined; as IntelliJ simply doesn't know about the JARs that contain the corresponding classes.
See here on how to fix that.
I am trying to run my first test with junit on a Spring Web Flow Project from within Eclipse and also from the console with mvn test and but give me the same error.
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [WEB-INF/spring/root-config.xml]; nested exception is java.io.FileNotFoundException: class path resource [WEB-INF/spring/root-config.xml] cannot be opened because it does not exist
I checked and I do have this file in the location so I dont know why Eclipse and Maven is not finding it. Can someone please help me out... below is my test classs
package org.uftwf.memberinquiry.text;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.uftwf.memberinquiry.model.MemberInquiryInformation;
import org.uftwf.memberinquiry.model.MemberRequest;
import org.uftwf.memberinquiry.service.MemberInquiryService;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:/WEB-INF/spring/root-config.xml")
public class TestApp {
#Autowired
private MemberInquiryService service;
#Test
public void testgetMemeberRequestInformation() {
MemberRequest inMemberRequest = new MemberRequest();
MemberInquiryInformation testInfo = service.getMemeberRequestInformation(inMemberRequest);
inMemberRequest.setRequestor("cpilling04#aol.com.dev");
Assert.assertEquals(testInfo.getFirst_Name(), "Christine");
Assert.assertEquals(testInfo.getLast_Name(), "Pillings");
}
}
#ContextConfiguration(locations = {classpath:spring/root-config.xml})
or create
TestApp-context.xml
I updated to the up to date spring-test and junit and now everything is find
#ContextConfiguration(locations = "classpath:WEB-INF/spring/root-config.xml")
When you start the path by /, it is understood, as an absolute path.