Running Spring Security and Struts JUnit tests in tandem - java

Currently, in my web application, I'm trying to run a series of unit tests for Struts 2.0.6 and Spring 3. In doing so, I've come across an issue where I have both tests call on the context configuration paths separately in their own respective tests and throw exceptions saying that certain beans have already been wired.
For my Struts unit test, I've extended the BaseStrutsTestCase, found here:
http://depressedprogrammer.wordpress.com/2007/06/18/unit-testing-struts-2-actions-spring-junit
I've configured the context configuration path as follows for the struts action test:
private static final String CONFIG_LOCATIONS = "classpath:applicationContext-test.xml";
Then I've gone ahead and created a separate Spring JUnit test for the login functionality for Spring Security:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration({"classpath:applicationContext-test.xml"})
public class UserAuthenticationTest {
#Autowired
protected UserManagementService userManagementService;
#Test
public void testUserSuccess() {
ArrayList<GrantedAuthority> grantedAuthorities =
new ArrayList<GrantedAuthority>();
ConsoleUser consoleUser =
userManagementService.getConsoleUser("user#test.com","password");
if (consoleUser == null){
Assert.assertTrue(consoleUser == null);
} else {
for (ConsoleRole role : consoleUser.getRoles()){
StringBuilder permissions = new StringBuilder();
for (ConsolePermission permission : role.getPermissions()){
grantedAuthorities.add(new GrantedAuthorityImpl(permission.getPermissionType().toString()));
permissions.append(permission.getPermissionType().toString() + " ");
}
}
Authentication authentication = new UsernamePasswordAuthenticationToken(consoleUser.getEmail(), consoleUser.getPassword(), grantedAuthorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
Assert.assertTrue(true);
}
}
}
So I ran my unit test suite (1 struts action and 1 Spring test), and the following exception gets thrown in my logs:
2974 [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource' defined in class path resource [spring-messagesource-config.xml]: Cannot resolve reference to bean 'messageBundleLocation' while setting bean property 'basename'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageBundleLocation' defined in class path resource [spring-messagesource-config.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.googlecode.ehcache.annotations.config.internalEhCacheCachingAdvisor': Cannot resolve reference to bean 'com.googlecode.ehcache.annotations.impl.CacheStaticMethodMatcherPointcut#0' while setting bean property 'pointcut'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.googlecode.ehcache.annotations.impl.CacheStaticMethodMatcherPointcut#0': Cannot resolve reference to bean 'com.googlecode.ehcache.annotations.impl.CacheAttributeSourceImpl#0' while setting bean property 'cacheAttributeSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.googlecode.ehcache.annotations.impl.CacheAttributeSourceImpl#0': Cannot resolve reference to bean 'facadeCacheManager' while setting bean property 'cacheManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facadeCacheManager' defined in class path resource [spring-cache-config-test.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Another CacheManager with same name 'API_CACHE_MANAGER' already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: InputStreamConfigurationSource [stream=sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream#327df0b7]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:329)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1387)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1128)
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:198)
at org.springframework.context.support.AbstractApplicationContext.initMessageSource(AbstractApplicationContext.java:786)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:467)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at BaseStrutsTestCase.setUp(BaseStrutsTestCase.java:80)
at junit.framework.TestCase.runBare(TestCase.java:139)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)
Is there a way to run these tests one after another, either by persisting the beans already created by my Spring unit tests or destroying the context configuration after the Spring unit test is done running and then having Struts use the context configuration within BaseStrutsTestCase?

Related

Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'com.sportswin.soa.spark.controller.ISparkGameUserController' method

Today when I start the spring boot project, shows error like this:
2022-01-21 14:52:04.659 ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/root/soa-spark-service-1.0.0-SNAPSHOT.jar!/BOOT-INF/lib/springfox-spring-webmvc-3.0.0.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'com.sportswin.soa.spark.controller.ISparkGameUserController' method
public abstract com.sportswin.soa.misc.contract.response.Response com.sportswin.soa.spark.controller.ISparkGameUserController.sparkGameUserFirstVote(com.sportswin.soa.spark.contract.request.vote.SparkGameUserVoteRequest)
to {POST /spark/game/user/vote/first}: There is already 'sparkGameUserController' bean method
public com.sportswin.soa.misc.contract.response.Response com.sportswin.soa.spark.controller.impl.SparkGameUserController.sparkGameUserFirstVote(com.sportswin.soa.spark.contract.request.vote.SparkGameUserVoteRequest) mapped.
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.13.RELEASE.jar!/:5.1.13.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:218) ~[spring-beans-5.1.13.RELEASE.jar!/:5.1.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1340) ~[spring-beans-5.1.13.RELEASE.jar!/:5.1.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1186) ~[spring-beans-5.1.13.RELEASE.jar!/:5.1.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.13.RELEASE.jar!/:5.1.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.13.RELEASE.jar!/:5.1.13.RELEASE]
I check the code, and did not found the Controller two method define with the same path. this is the rest controller method define:
#GetMapping("/vote/first/{gameId}")
Response<List<SparkGameUserVoteFirstResponse>> queryFirstVoteSparkGameUser(#PathVariable(value = "gameId") Long gameId);
#PostMapping("/vote/first")
Response sparkGameUserFirstVote(#RequestBody #Valid SparkGameUserVoteRequest request);
why did this happen? what should I do to fix it?I feel like the controller initial twice.
Try running a global text searching on text "/vote/first"? (Based on error msg you may have an api prefix "/spark/game/user" on this controller. Maybe somewhere else also produce the contacted api "/spark/game/user/vote/first")

HstSiteConfigurer: ComponentManager initialization failed

I'm working on One Hippo CMS, when I run the Tomcat server I'm getting this error
5.02.2019 18:23:45 ERROR main [DefaultHstSiteConfigurer.initializeComponentManager:264] HstSiteConfigurer: ComponentManager initialization failed.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.hippoecm.hst.content.beans.manager.ObjectConverter' defined in class path resource [org/hippoecm/hst/site/container/SpringComponentManager-content-beans.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Annotated class 'org.example.myproject.beans.Urldemo' for primarytype 'myproject:urldemo' is a duplicate of already registered class 'org.example.myproject.beans.Simple'. You might have configured a bean that does not have a annotation for the jcrType and inherits the jcrType from the bean it extends, resulting in 2 beans with the same jcrType. Correct your beans.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745) ~[spring-beans-5.1.1.RELEASE.jar:5.1.1.RELEASE]
Check the annotations on:
org.example.myproject.beans.Urldemo
org.example.myproject.beans.Simple
They should each have an annotation similar to:
#Node(jcrType = "project:doctype")
Each needs a unique jcrType value.

How to solve Quartz class not found error for quartz 1.8.5 jar in spring 4 Or how to create dynamic scheduler in spring 4? [duplicate]

I'm trying to migrate from spring 3.0.5 to spring 4.1.X .
Spring 3 has Class named as "org.springframework.scheduling.quartz.CronTriggerBean"
But Spring 4 doesn't include this class name.
[5/28/15 20:10:16:798 EDT] 00000092 ClassPathXmlA W
org.springframework.context.support.AbstractApplicationContext
__refresh Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot
find class [org.springframework.scheduling.quartz.CronTriggerBean] for
bean with name 'beanIdName' defined in class path resource
[config/spring/WxsCacheContext.xml]; nested exception is
java.lang.ClassNotFoundException:
org.springframework.scheduling.quartz.CronTriggerBean
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1328)
I have tried alternative like "spring-support" which has the same class. But no luck.
After getting that jar, it is giving errors about the quartz
[5/28/15 15:37:02:665 EDT] 0000006e SystemOut O ERROR (?:?) -
java.lang.Exception: Bean from
SpringUtils.getSpringBean(hostnameVerifierSetter) error message:
Unable to initialize group definition. Group resource name
[classpath*:beanRefFactory.xml], factory key [beanContext]; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'beanContext' defined in URL
[file:/C:/Program%20Files%20(x86)/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/cellName/Project.ear/configurations/beanRefFactory.xml]:
Bean instantiation via constructor failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.context.support.ClassPathXmlApplicationContext]:
Constructor threw exception; nested exception is
java.lang.NoClassDefFoundError: org.quartz.impl.JobDetailImpl
From Spring 3.1+, Change the Class names for the CronTriggerFactoryBean & JobDetailFactoryBean as like below
org.springframework.scheduling.quartz.CronTriggerBean
org.springframework.scheduling.quartz.CronTriggerFactoryBean
org.springframework.scheduling.quartz.JobDetailBean
org.springframework.scheduling.quartz.JobDetailFactoryBean
So your steps are:
Change
CronTriggerBean to CronTriggerFactoryBean
JobDetailBean to
JobDetailFactoryBean
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/quartz/CronTriggerFactoryBean.html
Since Spring3.1, it has changed.

Spring Boot and Teradata UnsatisfiedDependencyException

I am trying to create a simple Spring application with Teradata database.
It was working with mySql database and driver but after changing to Teradata driver/databased i receive following exception :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.lang.IllegalArgumentException: URL must start with 'jdbc'
Application Properties :
spring.datasource.url =jdbc:teradata://servername/db
spring.datasource.username = dbc
spring.datasource.password = dbc
spring.datasource.driverClassName=com.ncr.teradata.TeraDriver
I think that is problem of Spring you might be using #Autowire on constructor but spring can't inject class with that name. To solve the problem, just define a DataSource in your context - at which point Spring will be able to inject the bean and correctly bootstrap the context.

Implementing annotation based Spring AspectJ (JavaConfig)

We're trying to implement AspectJ #Aspect into our existing software for executing some code after a service call is made.
Note:
We have service interfaces and implementations being #Autowired
throughout the project via rest controllers as well as other service implementations.
This project is entirely a Java Configuration with no XML whatsoever.
We're using Spring 4.1.2 RELEASE deployed on Tomcat 7.0.54.
Issue:
When we added #EnableAspectJAutoProxy into our main #JavaConfig, we experience the following exception:
Unresolvable circular reference.
Which fails every #Autowired attempt on a long list of beans.
Tried:
Removed the #EnableAspectJAutoProxy annotation which autowires everything correctly but our #Aspect never gets invoked.
Added the CGLIB support in the annotation by declaring
proxytargetclass=true to no avail.
We've tried following this documentation directly from Spring: #EnableAspectJAutoProxy Javadoc
This seems to be an issue with AspectJ's proxy mechanism dealing with autowired dependencies.
Why does this occur when we add the #EnableAspectJAutoProxy?
Our Java Config:
#Configuration
#EnableWebMvc
#EnableJpaRepositories(basePackages ={"com.company.product.persistence.repository"})
#EnableTransactionManagement
#EnableSwagger
#EnableAspectJAutoProxy
#PropertySource({"classpath:hibernate.properties",
"classpath:auth.properties",
"classpath:mail.properties",
"classpath:locations.properties"
})
#ComponentScan(basePackages = {"com.company.product"})
public class WebConfig extends WebMvcConfigurerAdapter {
//Bean declarations here.
//Note: All services/repos/controllers are annotation based.
}
Aspect implementation:
#Aspect
#Component
public class PostMessageAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#After("execution(*com.company.product.persistence.serviceImpl.event.eventServiceImpl.methodCall(..))")
public void postMessageRun(final JoinPoint joinPoint) {
logger.info("CALLED AFTER METHOD");
}
}
Update:
Managed to get AOP/AspectJ working perfectly fine on one dev machine only requiring a minor change to our Spring Security config. We are both using Intellij, openJDK 1.7.0_65 on Ubuntu 14.0.4 running on default instances of Tomcat 7.0.56. On the other machine running the same software stack, gets the following.
Stack Trace:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dispatchingMessageController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.event.DispatchingEventService com.apx.efm.controllers.message.DispatchingMessageController.dispatchingEventService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dispatchingEventServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.building.BuildingAd dressesService com.apx.efm.persistence.serviceImpl.event.DispatchingEventServiceImpl.buildingAddressesService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'buildingAddressServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.building.BuildingService com.apx.efm.persistence.serviceImpl.building.BuildingAddressServiceImpl.buildingService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'buildingServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.building.BuildingAddressesService com.apx.efm.persistence.serviceImpl.building.BuildingServiceImpl.buildingAddressesService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.aopalliance.intercept.MethodInterceptor]: Factory method 'methodSecurityInterceptor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.apx.efm.persistence.service.user.EfmUserService com.apx.efm.application.config.SecurityConfig.efmUserService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'efmUserServiceImpl' defined in file [/home/apxdev4/Development/GitRepositories/efim-restful-web-service/target/EFIM/WEB-INF/classes/com/apx/efm/persistence/serviceImpl/user/EfmUserServiceImpl.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'methodSecurityInterceptor': Requested bean is currently in creation: Is there an unresolvable circular reference?
This was entirely an issue with our Spring configuration. Our Spring Security configuration was trying to #Autowired beans while they were still in the middle of being processed by our main application configuration. We solved this by ensuring that Spring Security gets configured after the main #Configuration.
#Override
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
// Initialize web mvc
appContext.setDisplayName("APP");
appContext.register(WebConfig.class);
appContext.register(SecurityConfig.class);
// Rest omitted (listeners, dispatcher servlet, etc.)
}

Categories