SpringBoot 3 & Spring Security 6 MockMvc 404 error - spring

In the api test through postman, the api works normally, but in the test through mockmvc, a 404 error appears.
My Controller class
#RestController
#RequestMapping("/login")
#EnableWebMvc
public class UserController {
#GetMapping("/hi")
public ResponseEntity<String> hi(){
return new ResponseEntity<>("hi", HttpStatus.OK);
}
}
My SecurityConfig
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers()
.addHeaderWriter(new XFrameOptionsHeaderWriter(
XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))
.and()
.authorizeHttpRequests(authorize -> authorize
.anyRequest().permitAll())
;
return http.build();
}
My Test Class
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = SecurityConfig.class)
#WebAppConfiguration
#WebMvcTest(UserController.class)
class UserControllerTest {
#Test
#DisplayName("Get check")
void getCheck() throws Exception {
mockMvc.perform(get("/login/hi"))
.andDo(print())
.andExpect(status().isOk());
}
}
What should I Do?
Even Spirng Security's docs doesn't come out right.
===============EDIT======================
My UserEntity
package com.hansung.capstone.user;
import jakarta.persistence.*;
import lombok.*;
#Getter
#Setter
#Entity
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class AppUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true)
private String username;
private String password;
#Column(unique = true)
private String email;
}
My User createForm
package com.hansung.capstone.user;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
#Getter
#Setter
#Builder
public class UserCreateForm {
private String username;
private String password1;
private String password2;
private String email;
}
My UserRepository
package com.hansung.capstone.user;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
public interface UserRepository extends JpaRepository<AppUser, Long> {
Optional<AppUser> findByusername(String username);
}
My UserService
package com.hansung.capstone.user;
import com.hansung.capstone.DataNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Optional;
#RequiredArgsConstructor
#Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public AppUser create(String username, String password, String email) {
AppUser user = new AppUser();
user.setUsername(username);
user.setEmail(email);
user.setPassword(passwordEncoder.encode(password));
this.userRepository.save(user);
return user;
}
public Boolean check(AppUser req){
Optional<AppUser> appuser = this.userRepository.findByusername(req.getUsername());
if (!appuser.isPresent()){
throw new DataNotFoundException("AppUser Not Found");
}
if (req.getUsername().equals(appuser.get().getUsername()) && passwordEncoder.matches(req.getPassword(), appuser.get().getPassword())){
return Boolean.TRUE;
} else{
return Boolean.FALSE;
}
}
}
My SecurityConfig
package com.hansung.capstone;
import static org.springframework.security.config.Customizer.withDefaults;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(
authorize ->
authorize
.requestMatchers("/login/ho").fullyAuthenticated()
.anyRequest().permitAll()
)
.formLogin(withDefaults());
;
return http.build();
}
#Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
application.properties
# DATABASE
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:~/local
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# JPA
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.show_sql=true
build.gradle()
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.1'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.hansung'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
runtimeOnly 'com.h2database:h2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
testImplementation('org.junit.jupiter:junit-jupiter-api:5.9.2')
testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.9.2')
compileOnly('org.springframework.boot:spring-boot-devtools')
implementation('org.springframework.boot:spring-boot-starter-security')
testImplementation('org.springframework.security:spring-security-test')
}
tasks.named('test') {
useJUnitPlatform()
}
ErrorContent
Failed to load ApplicationContext for [WebMergedContextConfiguration#44065156 testClass = com.hansung.capstone.UserControllerTest, locations = [], classes = [com.hansung.capstone.CapstoneApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer#6dee4f1b, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer#9da1, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer#bb57d28, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#ce77c022, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#13d73fa, [ImportsContextCustomizer#44ed0a8f key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration, org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration, org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration, org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration, org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration, org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration, org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration, org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcSecurityConfiguration, org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#189aa67a, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#112f364d, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.test.context.web.socket.MockServerContainerContextCustomizer#1b765a2c, org.springframework.boot.test.context.SpringBootTestAnnotation#96666a5e], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration#44065156 testClass = com.hansung.capstone.UserControllerTest, locations = [], classes = [com.hansung.capstone.CapstoneApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer#6dee4f1b, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer#9da1, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer#bb57d28, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#ce77c022, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#13d73fa, [ImportsContextCustomizer#44ed0a8f key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration, org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration, org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration, org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration, org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration, org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration, org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration, org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration, org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebClientAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcWebDriverAutoConfiguration, org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration, org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration, org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcSecurityConfiguration, org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#189aa67a, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#112f364d, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.test.context.web.socket.MockServerContainerContextCustomizer#1b765a2c, org.springframework.boot.test.context.SpringBootTestAnnotation#96666a5e], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:142)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController' defined in file [/Users/devch96/Desktop/workspace/cap/server/capstone/build/classes/java/main/com/hansung/capstone/UserController.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'com.hansung.capstone.user.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798)
at app//org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:245)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1344)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1188)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961)
at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915)
at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at app//org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59)
at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47)
at app//org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1386)
at app//org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:543)
at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:184)
at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:118)
... 87 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.hansung.capstone.user.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1812)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1371)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325)
at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885)
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789)
... 111 more

You are using a so called "Spring Boot Test Slice" (#WebMvcTest) which just configures everything related to the web layer. That is fine. This slice will find your controllers and also pick up your security config.
However, you added #ContextConfiguration. From the docs:
{#code #ContextConfiguration} defines class-level metadata that is used to determine
how to load and configure an {#link org.springframework.context.ApplicationContext
ApplicationContext} for integration tests.
With this, you are effectively disabling the automatic discovery of your UserController and you just get the security config. Nothing more. MockMVC will have probably shown you a 404 error.
How to fix this? Just remove it :)
But when you do so, your custom Spring Security config will go away during tests, too.
To fix this, you have two options: You can import additional config classes on the slice like this:
#WebMvcTest(includeFilters = #Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class))`
OR do a full integration test like this:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
The latter will bring up everything (but an embedded server, but that can be done, too).
As you originally asked for the slice, here's my recommendation (Note that you don't need the extension nor the trickery with the config):
package com.example.demo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
#WebMvcTest(includeFilters = #Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class))
class UserControllerTest {
#Autowired
MockMvc mockMvc;
#Test
#DisplayName("Get check")
void getCheck() throws Exception {
mockMvc.perform(get("/login/hi"))
.andDo(print())
.andExpect(status().isOk());
}
#Test
#WithMockUser("Michael")
void testWithUser() throws Exception {
mockMvc.perform(get("/login/ho"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string("hi Michael"));
}
}
I added a 2nd method to the controller and changed the security config a bit to made clear how to test with a mock user:
package com.example.demo;
import static org.springframework.security.config.Customizer.withDefaults;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class SecurityConfig {
#Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(
authorize ->
authorize
.requestMatchers("/login/ho").fullyAuthenticated()
.anyRequest().permitAll()
)
.formLogin(withDefaults());
;
return http.build();
}
}
and the controller:
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/login")
public class UserController {
#GetMapping("/hi")
public ResponseEntity<String> hi() {
return new ResponseEntity<>("hi", HttpStatus.OK);
}
#GetMapping("/ho")
public ResponseEntity<String> ho(Authentication d) {
return new ResponseEntity<>("hi " + d.getName(), HttpStatus.OK);
}
}
Please note as well that you should really not put #Configuration on classes that are actually implementing your business. Separate those (I am referring to adding #EnableWebMvc to the controller… Also, the annotation itself is superfluous anyhow with the Spring Boot Web MVC starter).
Full pom.xml for reference, too:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Related

Error Creating Application Context on Basic Spring-Boot-Data JPA Project

I am trying to create a basic Spring-Boot project that only deals with #Entity annotated classes and a basic JpaRepository for those entities.
When I try to run a basic test for the basic configuration of the project I get the following exception through JUnit(Jupiter).
java.lang.IllegalStateException:
Failed to load ApplicationContext for
[MergedContextConfiguration#717a8a76
testClass = com.example.demo.PersistenceLayerApplicationTests,
locations = [],
classes = [com.example.demo.PersistenceLayerApplication],
contextInitializerClasses = [],
activeProfiles = [],
propertySourceLocations = [],
propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"],
contextCustomizers =
[org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer#9da1,
org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0,
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#5fd4f8f5,
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#2f8dad04,
org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#44821a96,
org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0,
org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer#22e357dc,
org.springframework.boot.test.context.SpringBootTestAnnotation#978fd0ca],
contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:142)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:141)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:241)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47)
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1386)
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:543)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:184)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:118)
... 72 more
Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747)
... 93 more
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:98)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:68)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:419)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:403)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:272)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:178)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:149)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:117)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:242)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143)
at java.base/java.util.HashMap.forEach(HashMap.java:1421)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:140)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:336)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:415)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1425)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
... 97 more
Caused by: org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:319)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:247)
at org.postgresql.Driver.makeConnection(Driver.java:434)
at org.postgresql.Driver.connect(Driver.java:291)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:284)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:41)
... 115 more
Caused by: java.net.ConnectException: Connection refused: no further information
at java.base/sun.nio.ch.Net.pollConnect(Native Method)
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:539)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:594)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:633)
at org.postgresql.core.PGStream.createSocket(PGStream.java:241)
at org.postgresql.core.PGStream.<init>(PGStream.java:98)
at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:109)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:235)
... 129 more
Here is my build.gradle file
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext {
set('testcontainersVersion', "1.17.6")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.postgresql:postgresql'
runtimeOnly 'org.liquibase:liquibase-core'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:postgresql'
}
dependencyManagement {
imports {
mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
Here is the Spring Boot Application file(PersistencLayerApplication.java)
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class PersistenceLayerApplication {
public static void main(String[] args) {
SpringApplication.run(PersistenceLayerApplication.class, args);
}
}
Here is the #Entity class
package com.example.demo.data.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
#Entity
public class PersonEntity {
#Id
#GeneratedValue
private Long id;
private String firstName;
private String lastName;
protected PersonEntity() {}
public PersonEntity(String firstName, String lastName) {
super();
this.id = null;
this.firstName = firstName;
this.lastName = lastName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Here is the Repository class
package com.example.demo.data.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.data.entity.PersonEntity;
public interface PersonRepository extends JpaRepository<PersonEntity, Long> {
}
Here is my application.yaml file
#Deployment Options for Spring Data and PostgreSQL
#Not yet confirmed to be correct
spring:
jpa:
database: POSTGRESQL
show-sql: true
hibernate:
ddl-auto: create-drop
datasource:
url: "jdbc:postgresql:localhost:5432/datamodel"
username: foo
password: bar
driverClassName: org.postgresql.Driver
sql:
init:
platform: postgres
And here is my test file
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
#SpringBootTest
class PersistenceLayerApplicationTests {
#Test
void contextLoads() {
}
}
I have also tried to use an #DataJpaTest annotated test class thinking that I didn't configure my database properly but that one failed with the same error.
Here is that test file...
package com.example.demo.data;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import com.example.demo.data.PersonJpaTest.DataSourceInitializer;
import com.example.demo.data.entity.PersonEntity;
import com.example.demo.data.repo.PersonRepository;
#Testcontainers
#DataJpaTest
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#ContextConfiguration(initializers = DataSourceInitializer.class)
public class PersonJpaTest {
#Autowired private PersonRepository personRepository;
#Container //
static final PostgreSQLContainer<?> database = //
new PostgreSQLContainer<>("postgres:15.2-alpine") //
.withUsername("postgres");
public static class DataSourceInitializer //
implements ApplicationContextInitializer
<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertySourceUtils.
addInlinedPropertiesToEnvironment( applicationContext,
"spring.datasource.url=" + database.getJdbcUrl(),
"spring.datasource.usernam=" + database.getUsername(),
"spring.datasource.password=" + database.getPassword(),
"spring.jpa.hibernate.ddl-auto=create-drop");
}
}
#BeforeEach
void setUp() {
personRepository.saveAll(
List.of(
new PersonEntity(
"Mike",
"Bolger"),
new PersonEntity(
"Paul",
"Corrigan"),
new PersonEntity(
"Brenda",
"Butler"),
new PersonEntity(
"Gerald",
"Ford"),
new PersonEntity(
"Joe",
"Craig")
));
}
#Test
void findAll() {
List<PersonEntity> allPersons = personRepository.findAll();
for(PersonEntity person : allPersons) {
System.out.println(person.getFirstName() + " " + person.getLastName());
}
}
}
I know that there is a problem with the auto-generated ApplicationContext but I cannot see what I have done wrong. The book that I copied the example code from is essentially the same.
I tried running the test through the H2 database and got the same error.
Here is the application.yaml I used for that test
spring:
datasource:
url: jdbc:h2:mem:mydb
username: sa
password: password
driverClassName: org.h2.Driver
jpa:
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
And here is the build.gradle for the test.
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext {
set('testcontainersVersion', "1.17.6")
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
//runtimeOnly 'org.postgresql:postgresql'
//runtimeOnly 'org.liquibase:liquibase-core'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.testcontainers:junit-jupiter'
//testImplementation 'org.testcontainers:postgresql'
}
dependencyManagement {
imports {
mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}

Spring-boot 2.7.0 with jax-ws 1.9 WSServletContextListener Unable to start embedded Tomcat

What do I do wrong with JAX-WS and SPRING-BOOT?
I use jaxws-spring v1.9, spring-boot-starter-parent v2.7.0.
I don`t have web.xml.
I have #WebService() #SOAPBinding()
My problem is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
but file is in /src/main/resource/WEB-INF/sun-jaxws.xml
2022-08-04 16:47:58.026 ERROR 20076 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:165) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.20.jar:5.3.20]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
at com.thecloud.telecom.TelecomApplication.main(TelecomApplication.java:14) ~[classes/:na]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:479) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:184) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) ~[spring-boot-2.7.0.jar:2.7.0]
... 8 common frames omitted
Caused by: java.lang.IllegalStateException: StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[] failed to start
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.rethrowDeferredStartupExceptions(TomcatWebServer.java:187) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126) ~[spring-boot-2.7.0.jar:2.7.0]
... 13 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:52298', transport: 'socket'
Process finished with exit code 1
It happens when I try to use
JaxWsListener
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import com.sun.xml.ws.transport.http.servlet.WSServletContextListener;
#WebListener
public class JaxWsListener implements ServletContextAttributeListener, ServletContextListener {
private final WSServletContextListener listener;
public JaxWsListener() {
this.listener = new WSServletContextListener();
}
#Override
public void attributeAdded(ServletContextAttributeEvent event) {
listener.attributeAdded(event);
}
#Override
public void attributeRemoved(ServletContextAttributeEvent event) {
listener.attributeRemoved(event);
}
#Override
public void attributeReplaced(ServletContextAttributeEvent event) {
listener.attributeReplaced(event);
}
#Override
public void contextInitialized(ServletContextEvent sce) {
listener.contextInitialized(sce);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
listener.contextDestroyed(sce);
}
}
without this Listener spring-boot (tomcat) started well.
for JAX-WS as well I use this class :
JaxWsServlet
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.xml.ws.transport.http.servlet.WSServlet;
import lombok.extern.log4j.Log4j2;
#Log4j2
#WebServlet(name = "JaxWsServlet", urlPatterns = JaxWsServlet.URL_PATTERN, loadOnStartup = 1)
public class JaxWsServlet extends WSServlet {
public static final String URL_PATTERN = "/jaxws";
public JaxWsServlet() {
LOG.debug("CREATE {}", this.getClass().getSimpleName());
}
#Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
LOG.debug("JAX-WS Init");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
super.doPost(request, response);
LOG.debug("JAX-WS DoPost");
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
super.doGet(request, response);
LOG.debug("JAX-WS DoGet");
}
}
as well I have /WEB-INF/soap-jaxws.xml
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="SoapService"
implementation="com.ws.endpoint.SoapService"
url-pattern="/ws/call1" />
<endpoint name="SoapService2"
implementation="com.ws.endpoint.SoapService2"
url-pattern="/ws/call2" />
</endpoints>
this file parsed in the WSServletContextListener - it is hard coded there.
I solved this issue by putting /WEB-INF/sun-jaxws.xml into **/srv/main/resources/META-INF/resources/**WEB-INF/sun-jaxrs.xml
this helped me
It is enough to have in your spring-boot application:
/WEB-INF/sun-jaxws.xml - BCS it is HARDCODED in the jax-ws
#WebService
#WebListener
spring-boot-starter-parent:2.7.0
org.jvnet.jax-ws-commons.spring:jaxws-spring:1.9 - with exclusions
#Service
#WebService(
name = "SoapService",
endpointInterface = "com.ws.service.SoapService")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class SoapService
implements ISoapService { ....
and #WebListener (look at it above)
#WebListener
public class JaxWsListener implements ServletContextAttributeListener, ServletContextListener {
private final WSServletContextListener listener;
........
You do not need #WebServlet
pom.xml:
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.9</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
</exclusion>
<!-- ? -->
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.stream.buffer</groupId>
<artifactId>streambuffer</artifactId>
</exclusion>
<exclusion>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
</exclusion>
</exclusions>
</dependency>

Error creating bean with name 'projectController': Unsatisfied dependency expressed through field 'service';

I use the following configuration and code to create a spring boot application.
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>2.3.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-pm-project</artifactId>
<dependencies>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-system-cloud-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
</project>
Controller:
package cn.my.pm.project.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import cn.my.pm.project.entity.Project;
import cn.my.pm.project.service.IProjectService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
#RestController
#RequestMapping("/project/project")
#Slf4j
public class ProjectController extends JeecgController<Project, IProjectService> {
#Autowired
private IProjectService projectService;
#GetMapping(value = "/list")
public Result<?> queryPageList(Project project,
#RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
#RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<Project> queryWrapper = QueryGenerator.initQueryWrapper(project, req.getParameterMap());
Page<Project> page = new Page<Project>(pageNo, pageSize);
IPage<Project> pageList = projectService.page(page, queryWrapper);
return Result.OK(pageList);
}
#PostMapping(value = "/add")
public Result<?> add(#RequestBody Project project) {
projectService.save(project);
return Result.OK("add!");
}
#PutMapping(value = "/edit")
public Result<?> edit(#RequestBody Project project) {
projectService.updateById(project);
return Result.OK("edit!");
}
#DeleteMapping(value = "/delete")
public Result<?> delete(#RequestParam(name="id",required=true) String id) {
projectService.removeById(id);
return Result.OK("delete!");
}
#DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(#RequestParam(name="ids",required=true) String ids) {
this.projectService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("batch delete!");
}
#GetMapping(value = "/queryById")
public Result<?> queryById(#RequestParam(name="id",required=true) String id) {
Project project = projectService.getById(id);
if(project==null) {
return Result.error("not found");
}
return Result.OK(project);
}
}
Service:
package cn.my.pm.project.service;
import cn.my.pm.project.entity.Project;
import com.baomidou.mybatisplus.extension.service.IService;
public interface IProjectService extends IService<Project> {
}
ServiceImpl:
package cn.my.pm.project.service.impl;
import cn.my.pm.project.entity.Project;
import cn.my.pm.project.mapper.ProjectMapper;
import cn.my.pm.project.service.IProjectService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
#Service
#Slf4j
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {
}
Mapper:
package cn.my.pm.project.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import cn.my.pm.project.entity.Project;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Service;
public interface ProjectMapper extends BaseMapper<Project> {
}
ProjectMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.my.pm.project.mapper.ProjectMapper">
</mapper>
Entity:
package cn.my.pm.project.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
#Data
#TableName("my_info")
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
private java.lang.String id;
private java.lang.String myName;
private java.lang.String myType;
private java.lang.String myType;
private java.lang.String myManager;
private java.lang.String myInfo;
private java.lang.String myDetails;
private java.lang.String myImage;
}
Application:
package cn.my;
import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
#SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class, ShiroAutoConfiguration.class, ShiroBeanAutoConfiguration.class})
#EnableDiscoveryClient
#EnableFeignClients
public class ProjectApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
}
But when I run the application,the error message is:
ERROR org.springframework.boot.SpringApplication:858 - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'projectController': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'projectServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.my.pm.project.mapper.ProjectMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at cn.my.ProjectApplication.main(ProjectApplication.java:18)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'projectServiceImpl': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.my.pm.project.mapper.ProjectMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1247)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 19 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.my.pm.project.mapper.ProjectMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 32 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:64977', transport: 'socket'
How to fix it?
Spring's complaint is that you haven't defined a Bean of type ProjectMapper, which it is saying that it needs to satisfy an Autowire request. Looking at your code, I don't see a definition for such a Bean in what you've shown us here.
The exact point of the problem is hidden, I'm guessing, because you aren't showing us the definition of the ServiceImpl class. My guess is that that's where the actual reference is that Spring is trying to wire up. Apparently, the field name is baseMapper.
Spring doesn't seem to find Mapper.
try
#Mapper
public interface ProjectMapper extends BaseMapper<Project> {
}
Or
#SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class,
ShiroAutoConfiguration.class, ShiroBeanAutoConfiguration.class})
#EnableDiscoveryClient
#EnableFeignClients
#MapperScan(basePackage="cn.my.pm.project.mapper.*")
public class ProjectApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
}
The reason is that the package is not added with #MapperScan.
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
#MapperScan(value={"org.abc.modules.**.mapper*", "cn.my.pm.**.mapper*"})
public class MybatisPlusConfig {
……
}
Then there is no error.

Spring IntegrationFlow Http.inboundGateway ambiguous parameter type

I'm trying to convert the following spring integration sample to a Java Config version. https://github.com/dsyer/http-amqp-tunnel
We need a slightly modified version of this project to work in a production environment. My problem is that I keep getting the following exception when starting the application.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpInboundGateway' defined in org.springframework.platform.proxy.TunnelApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'httpInboundGateway' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class [Ljava.lang.String;] for method match: [public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.multipartResolver(org.springframework.web.multipart.MultipartResolver), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.replyMapper(org.springframework.integration.mapping.OutboundMessageMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.autoStartup(boolean), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.mappedResponseHeaders(java.lang.String[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.phase(int), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.crossOrigin(org.springframework.integration.dsl.support.Consumer), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(java.lang.String), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.headerMapper(org.springframework.integration.mapping.HeaderMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestMapper(org.springframework.integration.mapping.InboundMessageMapper), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.messageConverters(org.springframework.http.converter.HttpMessageConverter[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestTimeout(long), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadExpression(org.springframework.expression.Expression), public java.lang.Class org.springframework.integration.dsl.core.IntegrationComponentSpec.getObjectType(), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.requestPayloadType(java.lang.Class), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadFunction(org.springframework.integration.dsl.support.Function), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(org.springframework.messaging.MessageChannel)]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.platform.proxy.TestServerApplication.main(TestServerApplication.java:11) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'httpInboundGateway' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class [Ljava.lang.String;] for method match: [public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.multipartResolver(org.springframework.web.multipart.MultipartResolver), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.replyMapper(org.springframework.integration.mapping.OutboundMessageMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.autoStartup(boolean), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.mappedResponseHeaders(java.lang.String[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.phase(int), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.crossOrigin(org.springframework.integration.dsl.support.Consumer), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(java.lang.String), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.headerMapper(org.springframework.integration.mapping.HeaderMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestMapper(org.springframework.integration.mapping.InboundMessageMapper), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.messageConverters(org.springframework.http.converter.HttpMessageConverter[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestTimeout(long), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadExpression(org.springframework.expression.Expression), public java.lang.Class org.springframework.integration.dsl.core.IntegrationComponentSpec.getObjectType(), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.requestPayloadType(java.lang.Class), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadFunction(org.springframework.integration.dsl.support.Function), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(org.springframework.messaging.MessageChannel)]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type [class [Ljava.lang.String;] for method match: [public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.multipartResolver(org.springframework.web.multipart.MultipartResolver), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.replyMapper(org.springframework.integration.mapping.OutboundMessageMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.autoStartup(boolean), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.mappedResponseHeaders(java.lang.String[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.phase(int), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.crossOrigin(org.springframework.integration.dsl.support.Consumer), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(java.lang.String), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.headerMapper(org.springframework.integration.mapping.HeaderMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestMapper(org.springframework.integration.mapping.InboundMessageMapper), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.messageConverters(org.springframework.http.converter.HttpMessageConverter[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestTimeout(long), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadExpression(org.springframework.expression.Expression), public java.lang.Class org.springframework.integration.dsl.core.IntegrationComponentSpec.getObjectType(), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.requestPayloadType(java.lang.Class), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadFunction(org.springframework.integration.dsl.support.Function), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(org.springframework.messaging.MessageChannel)]
at org.springframework.util.Assert.isNull(Assert.java:92) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.findHandlerMethodsForTarget(MessagingMethodInvokerHelper.java:497) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:226) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:149) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:144) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.MethodInvokingMessageProcessor.<init>(MethodInvokingMessageProcessor.java:60) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.ServiceActivatingHandler.<init>(ServiceActivatingHandler.java:37) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:985) ~[spring-integration-java-dsl-1.2.1.RELEASE.jar:na]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:964) ~[spring-integration-java-dsl-1.2.1.RELEASE.jar:na]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:950) ~[spring-integration-java-dsl-1.2.1.RELEASE.jar:na]
at org.springframework.platform.proxy.TunnelApplication.httpInboundGateway(TunnelApplication.java:93) ~[classes/:na]
at org.springframework.platform.proxy.TunnelApplication$$EnhancerBySpringCGLIB$$4e2cc6e6.CGLIB$httpInboundGateway$3(<generated>) ~[classes/:na]
at org.springframework.platform.proxy.TunnelApplication$$EnhancerBySpringCGLIB$$4e2cc6e6$$FastClassBySpringCGLIB$$e8c73d4b.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.platform.proxy.TunnelApplication$$EnhancerBySpringCGLIB$$4e2cc6e6.httpInboundGateway(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
... 19 common frames omitted
Here's my modified version of TunnelApplication. The original can be found in the project link above.
package org.springframework.platform.proxy;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.*;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.*;
import org.springframework.integration.dsl.amqp.Amqp;
import org.springframework.integration.dsl.http.Http;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.HttpRequestHandlerServlet;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableIntegration
public class TunnelApplication
{
public static void main(String[] args)
{
SpringApplication.run(TunnelApplication.class, args);
}
#Value("${urlExpression}")
private String urlExpression;
#Value("${outboundQueue}")
private String outboundQueue;
#Value("${inboundQueue}")
private String inboundQueue;
#Autowired
private ConnectionFactory rabbitConnectionFactory;
#Bean
public Queue requestQueue()
{
return new Queue(outboundQueue, true, false, true);
}
#Bean
public Queue targetQueue()
{
return new Queue(inboundQueue, true, false, true);
}
#Bean
public ServletRegistrationBean httpInboundGatewayServletRegistration()
{
ServletRegistrationBean bean = new ServletRegistrationBean(httpInboundGatewayServlet(), "/tunnel/*");
bean.setName("httpInboundGateway");
return bean;
}
#Bean
public HttpRequestHandlerServlet httpInboundGatewayServlet()
{
return new HttpRequestHandlerServlet();
}
#Bean
public RestTemplate safeRestTemplate()
{
return new RestTemplate();
}
#Bean
public Jackson2JsonMessageConverter jsonMessageConverter()
{
return new Jackson2JsonMessageConverter();
}
#Bean
public AmqpTemplate amqpTemplate()
{
RabbitTemplate result = new RabbitTemplate(rabbitConnectionFactory);
result.setMessageConverter(jsonMessageConverter());
return result;
}
#Bean
public IntegrationFlow httpInboundGateway()
{
return IntegrationFlows.from("outbound")
.handle(Http.inboundGateway("/tunnel"))
.get();
}
#Bean
public IntegrationFlow amqpOutbound(AmqpTemplate amqpTemplate)
{
return IntegrationFlows.from("outbound")
.handle(
Amqp.outboundAdapter(amqpTemplate)
.mappedRequestHeaders("http_*")
.routingKeyExpression("headers['routingKey']")
)
.get();
}
#Bean
public IntegrationFlow amqpInboundGateway(ConnectionFactory connectionFactory)
{
return IntegrationFlows.from("inbound").handle
(
Amqp.inboundGateway(connectionFactory, inboundQueue)
.mappedRequestHeaders("http_*")
.messageConverter(jsonMessageConverter())
)
.get();
}
#Bean
public IntegrationFlow httpOutboundGateway()
{
return IntegrationFlows.from("inbound").handle(Http.outboundGateway(urlExpression)).get();
}
}
When I run TunnelApplication I get the above error. My maven pom file has been modified as follows. The main difference being that I'm using spring boot 1.5.1 and the original project uses 1.1.4.BUILD-SNAPSHOT.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.redi</groupId>
<artifactId>redi-parent</artifactId>
<version>5.0.0</version>
</parent>
<artifactId>http-amqp-tunnel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HTTP AMQP Tunnel</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>org.springframework.platform.proxy.TunnelApplication</start-class>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I'd really appreciate some guidance. This is my first spring integration project and I feel like I'm close.
Thanks in advance for your help.
Revised Configuration
package org.springframework.platform.proxy;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.*;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.*;
import org.springframework.integration.dsl.amqp.Amqp;
import org.springframework.integration.dsl.http.Http;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.HttpRequestHandlerServlet;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableIntegration
public class TunnelApplication
{
public static void main(String[] args)
{
SpringApplication.run(TunnelApplication.class, args);
}
#Value("${urlExpression}")
private String urlExpression;
#Value("${outboundQueue}")
private String outboundQueue;
#Value("${inboundQueue}")
private String inboundQueue;
#Autowired
private ConnectionFactory rabbitConnectionFactory;
#Bean
public Queue requestQueue()
{
return new Queue(outboundQueue, true, false, true);
}
#Bean
public Queue targetQueue()
{
return new Queue(inboundQueue, true, false, true);
}
#Bean
public ServletRegistrationBean httpInboundGatewayServletRegistration()
{
ServletRegistrationBean bean = new ServletRegistrationBean(httpInboundGatewayServlet(), "/tunnel/*");
bean.setName("httpInboundGateway");
return bean;
}
#Bean
public HttpRequestHandlerServlet httpInboundGatewayServlet()
{
return new HttpRequestHandlerServlet();
}
#Bean
public RestTemplate safeRestTemplate()
{
return new RestTemplate();
}
#Bean
public Jackson2JsonMessageConverter jsonMessageConverter()
{
return new Jackson2JsonMessageConverter();
}
#Bean
public AmqpTemplate amqpTemplate()
{
RabbitTemplate result = new RabbitTemplate(rabbitConnectionFactory);
result.setMessageConverter(jsonMessageConverter());
return result;
}
#Bean
public IntegrationFlow httpInboundGateway()
{
return IntegrationFlows.from(Http.inboundGateway("/tunnel")).channel("outbound")
.get();
}
#Bean
public IntegrationFlow amqpOutbound(AmqpTemplate amqpTemplate)
{
return IntegrationFlows.from("outbound")
.handle(
Amqp.outboundAdapter(amqpTemplate)
.mappedRequestHeaders("http_*")
.routingKeyExpression("headers['routingKey']")
)
.get();
}
#Bean
public IntegrationFlow amqpInboundGateway(ConnectionFactory connectionFactory)
{
return IntegrationFlows.from
(
Amqp.inboundGateway(connectionFactory, inboundQueue)
.mappedRequestHeaders("http_*")
.messageConverter(jsonMessageConverter())
)
.channel("inbound")
.get();
}
#Bean
public IntegrationFlow httpOutboundGateway()
{
return IntegrationFlows.from("inbound").handle(Http.outboundGateway(urlExpression)).get();
}
The error I am now getting when I navigate to http://localhost:9000/tunnel is the following:
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'httpInboundGateway' is expected to be of type 'org.springframework.web.HttpRequestHandler' but was actually of type 'org.springframework.integration.dsl.StandardIntegrationFlow'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:378) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1087) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.context.support.HttpRequestHandlerServlet.init(HttpRequestHandlerServlet.java:57) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at javax.servlet.GenericServlet.init(GenericServlet.java:158) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1183) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at
}
.handle(Http.inboundGateway("/tunnel"))
You can't invoke an inbound gateway from a .handle() method.
Inbound endpoints are not consumers.
It looks like it should be .from(Http.in...).
You have the same issue with the amqp inbound endpoint.

How to Spring 3.2 + hibernate 4 on javaconfig correctly

I want to make test in Spring 3.2 + Hibernate 4 + javaconfig
Content of build.gradle is the next:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.9'
}
}
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'war'
apply plugin: 'tomcat'
ext.springVersion = '3.2.4.RELEASE'
ext.springMobileVersion = '1.1.0.RELEASE'
ext.thymeleafVersion = '2.0.19'
ext.aspectJVersion = '1.6.9'
ext.cglibVersion = '2.2'
ext.slf4jVersion = '1.6.1'
ext.servletJstlVersion = '1.2'
ext.servletApiVersion = '3.0.1'
ext.servletJspVersion = '2.1'
ext.junitVersion = '4.11'
ext.tomcatVersion = '7.0.42'
ext.pgsqlVersion = '9.1-901.jdbc4'
ext.mockiteoCoreVersion = '1.9.5'
ext.mailVersion = '1.4.7'
ext.dataBindVersion = '2.2.3'
ext.hbVersion = '4.2.7.Final'
ext.guavaVersion = '15.0'
ext.javassistVersion = '3.18.0-GA'
war {
webInf {
include "src/main/webapp/resources/**"
}
}
dependencies {
compile("org.springframework:spring-context:$springVersion") {
exclude module: 'commons-logging'
}
compile "org.springframework:spring-context-support:$springVersion"
compile "org.springframework:spring-web:$springVersion"
compile "org.springframework:spring-webmvc:$springVersion"
compile "org.springframework.mobile:spring-mobile-device:$springMobileVersion"
compile "org.springframework:spring-tx:$springVersion"
compile "org.springframework:spring-orm:$springVersion"
compile "com.fasterxml.jackson.core:jackson-databind:$dataBindVersion"
compile "javax.mail:mail:$mailVersion"
compile "org.thymeleaf:thymeleaf-spring3:$thymeleafVersion"
compile "org.aspectj:aspectjrt:$aspectJVersion"
compile "cglib:cglib-nodep:$cglibVersion"
compile "javax.inject:javax.inject:1"
compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "org.slf4j:jcl-over-slf4j:$slf4jVersion"
compile "org.slf4j:slf4j-log4j12:$slf4jVersion"
compile "javax.servlet:jstl:$servletJstlVersion"
providedCompile("javax.servlet:javax.servlet-api:$servletApiVersion")
providedCompile("javax.servlet.jsp:jsp-api:$servletJspVersion")
// Persistence
compile "postgresql:postgresql:$pgsqlVersion"
compile "org.hibernate:hibernate-core:$hbVersion"
compile "org.hibernate:hibernate-entitymanager:$hbVersion"
compile "org.apache.tomcat:tomcat-dbcp:$tomcatVersion"
compile "org.javassist:javassist:$javassistVersion"
// Tools
compile "com.google.guava:guava:$guavaVersion"
// TEST
testCompile "junit:junit:$junitVersion"
testCompile "org.mockito:mockito-core:$mockiteoCoreVersion"
testCompile "org.springframework:spring-test:$springVersion"
testCompile "org.hamcrest:hamcrest-core:1.3"
testCompile "org.hamcrest:hamcrest-library:1.3"
testCompile "org.apache.commons:commons-lang3:3.1"
// TOMCAT
tomcat("org.apache.tomcat.embed:tomcat-embed-core:$tomcatVersion",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:$tomcatVersion")
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:$tomcatVersion") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
}
repositories {
mavenCentral()
maven { url 'http://repo.spring.io/libs-release' }
}
task wrapper(type: Wrapper) {
gradleVersion = '1.8'
}
PersistenceConfig content is the next:
#Configuration
#EnableTransactionManagement
#PropertySource({ "classpath:pgsql.properties" })
#ComponentScan(basePackages = {"com.example.persistence"})
public class PersistenceConfig
{
#Autowired
private Environment env;
#Bean
public DataSource dataSource()
{
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.example.persistence.domain" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public HibernateTransactionManager transactionManager()
{
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory().getObject());
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
{
return new PersistenceExceptionTranslationPostProcessor();
}
Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
setProperty("hibernate.globally_quoted_identifiers", "true");
}
};
}
}
ProductServiceTest content is the next:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {PersistenceConfig.class})
public class ProductServiceTest
{
private static final Logger LOG = LoggerFactory.getLogger(ProductServiceTest.class);
#Autowired
private ProductService productService;
#Autowired
private ApplicationContext applicationContext;
#Test
public final void listApplicationBeans() throws Exception
{
List<String> beans = Arrays.asList(applicationContext.getBeanDefinitionNames());
for (String bean: beans)
{
LOG.info(String.format("--> App Beans [%s]", bean));
}
}
}
persistence.properties content is the next:
# jdbc
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://some_address:5432/some_database
jdbc.user=someuser
jdbc.pass=somepassword
# hibernate
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop
Product content is the next:
#Entity
public class Product implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name) {
this.name = name;
}
public Product(String name)
{
setName(name);
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append(Product.class.getSimpleName()).append(" [\n");
builder.append("id = ").append(id).append("\n");
builder.append("name = ").append(name).append("\n");
builder.append("]");
return builder.toString();
}
}
ProductDao content is the next:
import org.springframework.stereotype.Repository;
import com.example.persistence.dao.common.AbstractDao;
import com.example.persistence.domain.Product;
#Repository
public class ProductDao extends AbstractDao<Product>
{
public ProductDao()
{
super();
setClazz(Product.class);
}
}
ProductService content is the next:
#Service
public class ProductService extends AbstractService<Product>
{
#Autowired
private ProductDao dao;
public ProductService()
{
super();
}
#Override
protected IOperation<Product> getDao()
{
return dao;
}
}
Result of gradle clean test:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:105)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:47)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.persistence.dao.impl.ProductDao com.example.persistence.service.impl.ProductService.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.persistence.dao.impl.ProductDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 44 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.persistence.dao.impl.ProductDao com.example.persistence.service.impl.ProductService.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.persistence.dao.impl.ProductDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 60 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.persistence.dao.impl.ProductDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 62 more
According to the stacktrace:
Could not autowire field: private com.example.persistence.dao.impl.ProductDao
com.example.persistence.service.impl.ProductService.dao; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
When I found such issue I eliminate the following:
The bean is not annotated or not covered by component scan.
You defined
#ComponentScan(basePackages = {"com.example.persistence"})
It covers your package com.example.persistence.dao.impl.ProductDao
Look’s fine here.
Make sure annotations are correct: ProductDao is annotated #Repository
Looks ok.
Make sure that com.example.persistence.dao.impl.ProductDao is in the classpath.
You are executing the command gradle clean test, which means your code will be compiled before test execution (as test depend on the compile task).
If it compiles I guess that ProductDao is in your classpath
Make sure that the JUnit has the required configuration for bootstrapping
spring application context.
#ContextConfiguration
class points to your configurations class.
loader attribute was not defined so spring will use the default DelegatingSmartContextLoader (no #WebAppConfiguration in your configuration and version >3.2).
Looks good to me.
Unfortunately I cannot find any issue and everything looks fine (I hope this check list will help someone).
So I would guess that the issue is somewhere in the missing details; like you have to class of ProductDao under different packages and you are using the wrong one in the ProductService or the wrong interface etc.
Hope this helps
I share with you an example of my Hibernate java configuration.
I hope you love it:
Pre-requirement: pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.0.6.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.9.Final</version>
</dependency>
<!-- POSTGRESQL -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
</dependency>
</dependencies>
Step 1: application.properties
################### DataSource Configuration ##########################
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost/curso_db
jdbc.username=alumno
jdbc.password=alumno
#################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
packagesToScan=com.curso.online.model
Step 2: Config.java
package com.curso.online;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#PropertySources(value = { #PropertySource("classpath:/application.properties") })
#ComponentScan(basePackages = "com.curso.online")
public class Config {
#Value("${jdbc.driverClassName}")
private String KEY_DRIVER_CLASS;
#Value("${jdbc.url}")
private String KEY_JDBC_URL;
#Value("${jdbc.username}")
private String KEY_JDBC_USERNAME;
#Value("${jdbc.password}")
private String KEY_JDBC_PASSWORD;
#Value("${hibernate.dialect}")
private String KEY_HIBERNATE_DIALECT;
#Value("${hibernate.show_sql}")
private String KEY_HBERNATE_SHOW_SQL;
#Value("${packagesToScan}")
private String KEY_ENTITIES_PKG;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setPackagesToScan(KEY_ENTITIES_PKG);
factory.setHibernateProperties(hibernateProperties());
return factory;
}
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", KEY_HIBERNATE_DIALECT);
properties.setProperty("hibernate.show_sql", KEY_HBERNATE_SHOW_SQL);
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(
SessionFactory sessionFactory) {
return new HibernateTransactionManager(sessionFactory);
}
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(KEY_DRIVER_CLASS);
dataSource.setUrl(KEY_JDBC_URL);
dataSource.setUsername(KEY_JDBC_USERNAME);
dataSource.setPassword(KEY_JDBC_PASSWORD);
return dataSource;
}
}
I came across a similar problem with my Spring Hibernate project in my test suites.
The only way I could solve the problem was to autowire the class by using its super class as its type (AbstractService in your case) and then use a #Qualifier to tell Spring which child class I am referring to. It will look something like this in your case:
#Qualifier("ProductService")
#Autowired
private AbstractService productService;
It is painful as then in the test function you have to cast productService object to ProductService every time you use a method that belongs to the child class. So if you have already solved this using another solution please share it with us.

Resources