Spring Cache Abstraction VS interfaces VS key param ("Null key returned for cache operation" error) - spring

While implementing, I came across a problem with Spring Cache Abstraction VS interfaces.
Lets say I have the following interface:
package com.example.cache;
public interface IAddItMethod
{
Integer addIt(String key);
}
And the two following implementations:
package com.example.cache;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
#Component
public class MethodImplOne implements IAddItMethod
{
#Override
#Cacheable(value="integersPlusOne", key="#keyOne")
public Integer addIt(String keyOne)
{
return new Integer(Integer.parseInt(keyOne) + 1);
}
}
.
package com.example.cache;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
#Component
public class MethodImplTwo implements IAddItMethod
{
#Override
#Cacheable(value="integersPlusTwo", key="#keyTwo")
public Integer addIt(String keyTwo)
{
return new Integer(Integer.parseInt(keyTwo) + 2);
}
}
Note that the IAddItMethod is not the one specifying #Cacheable. We could have other implementation (ex MethodImplThree) without the #Cacheable annotation.
We’ve got a simple beans.xml with:
context:component-scan base-package="com.example.cache"
Adding to that, two jUnit test cases:
package com.example.cache;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:beans.xml"})
public class MethodImplOneTest
{
#Autowired
#Qualifier("methodImplOne")
private IAddItMethod classUnderTest;
#Test
public void testInit()
{
int number = 1;
assertEquals(new Integer(number + 1), classUnderTest.addIt("" + number));
}
}
.
package com.example.cache;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:beans.xml"})
public class MethodImplTwoTest
{
#Autowired
#Qualifier("methodImplTwo")
private IAddItMethod classUnderTest;
#Test
public void testInit()
{
int number = 1;
assertEquals(new Integer(number + 2), classUnderTest.addIt("" + number));
}
}
When I run the tests individually, they succeed.
However, if I run them both together (selecting the package, right-click, run as), the second one (not necessarily MethodImplTwoTest, just the second one running) will fail with the following exception:
java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) CacheableOperation[public java.lang.Integer com.example.cache.MethodImplOne.addIt(java.lang.String)] caches=[integersPlusOne] | condition='' | key='#keyOne'
at org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheables(CacheAspectSupport.java:297)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:198)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy16.addIt(Unknown Source)
at com.example.cache.ITMethodImplOneIntegrationTest.testInit(ITMethodImplOneIntegrationTest.java:26)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
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:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
note: I'm using Eclipse STS 3.0 and the "Add variable attributes to generated class files" is enabled.
IMPORTANT: If I don't specify the "key" in the #Cacheable annotations, it works.
Is there anything I forgot to specify? config? annotations?
Thanks in advance!

My guess is that for jdk proxy the parameter name is fetched from the interface method so it's key and not keyTwo.
update: You can try to use parameter indexes instead
If for some reason the names are not available (ex: no debug
information), the parameter names are also available under the p<#arg>
where #arg stands for the parameter index (starting from 0).
see http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html#cache-spel-context

Related

Eureka and Feign MicroWebservice failing to startup

i have managed to build a microservice with one Eureka server and two client servers, one of the server is using Feign and ribbon to call other service , and this service is getting shutdown immediately after startup. i tried to search for possible problem but i couldn't find any. please help me to resolve it.
controller class
package com.booter.Company.controller;
import java.util.List;
import javax.websocket.server.PathParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.booter.Company.dto.CompanyDTO;
import com.booter.Company.dto.EmployeeDTO;
#RestController
#RequestMapping("/company")
public class CompanyController {
private Logger log = LoggerFactory.getLogger(CompanyController.class);
#Autowired
private CompanyControllerProxy proxy;
#RequestMapping(path= {"/{name}"}, method= {RequestMethod.GET})
public CompanyDTO companyDetails(#PathParam("from") String name) {
CompanyDTO dto = new CompanyDTO();
dto.setName(name);
dto.setAffiliatedTo("HCL Group Of Companies..");
List<EmployeeDTO> employees = proxy.returnEmployeeList();
log.info("{}",employees);
dto.setEmployees(employees);
return dto;
}
}
feign proxy class to call other service
package com.booter.Company.controller;
import java.util.List;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import com.booter.Company.dto.EmployeeDTO;
#FeignClient(name="person-service")
#RibbonClient(name="person-service")
public interface CompanyControllerProxy {
#GetMapping("/api/persons")
public List<EmployeeDTO> returnEmployeeList();
}
Bootstrap class
package com.booter.Company;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
#SpringBootApplication
#EnableFeignClients("com.booter.Company.controller")
#EnableDiscoveryClient
public class CompanyApplication {
public static void main(String[] args) {
SpringApplication.run(CompanyApplication.class, args);
}
}
application.properties file::
spring.application.name = company-service
server.port = 8200
eureka.client.serviceUrl.defaultZone=http://localhost:8005/eureka
Log
org.springframework.context.ApplicationContextException: Failed to start bean 'eurekaAutoServiceRegistration'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:184) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:52) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:157) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:121) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:885) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:161) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE]
at com.booter.Company.CompanyApplication.main(CompanyApplication.java:15) [classes/:na]
Hi Yogendra,
The problem was with pom.xml indeed, i was explicitly adding ribbon dependency in pom.xml while it's already been part of eureka client because of this i was getting this problem. after removing the ribbon client from pom.xml everything is fine.

Autowiring with spring java config for beans in different packages not working

I am trying to implement a simple Spring AOP example.
Use case:
I have a compact disc (SgtPeppers) class with attributes such as artist, title. It has a method to play a specific track. I have created an aspect to count the number of times a track is being played. I have a test class to test the same.
Problem:
Compact disc class is in a different package from the aspect and the test class. Beans are configured using spring java config method. However, autowiring doesn't seem to work for compact disc class. It throws BeanCreationException.
Please find the code below:
Compact disc class (Here, it's configured as SgtPeppers)
package com.springinaction.soundsystem.autoconfig;
import java.util.List;
public class SgtPeppers implements CompactDisc {
private String title, artist;
public SgtPeppers(String title, String artist) {
super();
this.title = title;
this.artist = artist;
}
public SgtPeppers() {
// TODO Auto-generated constructor stub
}
public String getTitle() {
return title;
}
public String getArtist() {
return artist;
}
#Override
public void play() {
System.out.println("Playing "+title+" by "+ artist);
}
public void playTrack(int tracknumber) {
System.out.println("Playing track "+ tracknumber);
}
}
TrackCounter Aspect:
package com.springinaction.aspects.concert.trackCounter;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
#Aspect
public class TrackCounter {
private Map<Integer,Integer> trackCounts = new HashMap<Integer, Integer>();
#Pointcut("execution(** com.springinaction.aspects.concert.trackCounter.SgtPeppers.playTrack(int)) && args(trackNumber)")
public void trackPlayed(int trackNumber){}
#Before("trackPlayed(trackNumber)")
public void countTrack(int trackNumber) {
int trackCount = getTrackCount(trackNumber);
trackCounts.put(trackNumber, trackCount+1);
}
public int getTrackCount(int trackNumber) {
return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0;
}
}
TrackCounterConfig:
package com.springinaction.aspects.concert.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.springinaction.aspects.concert.trackCounter.SgtPeppers;
import com.springinaction.aspects.concert.trackCounter.TrackCounter;
#Configuration
#EnableAspectJAutoProxy
public class TrackCounterConfig {
#Bean
public SgtPeppers sgtPeppers() {
SgtPeppers cd = new SgtPeppers("Sgt. Pepper's Lonely Hearts Club Band", "The Beatles");
return cd;
}
#Bean
public TrackCounter trackCounter() {
return new TrackCounter();
}
}
TrackCounterTest:
package com.springinaction.aspects.concert.trackCounter;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.springinaction.aspects.concert.config.TrackCounterConfig;
import com.springinaction.soundsystem.autoconfig.SgtPeppers;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=TrackCounterConfig.class)
public class TrackCounterTest {
#Autowired
private TrackCounter trackCounter;
#Autowired
private SgtPeppers sgtPeppers;
#Test
public void testTrackCounter() {
sgtPeppers.playTrack(1);
sgtPeppers.playTrack(1);
sgtPeppers.playTrack(2);
sgtPeppers.playTrack(2);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(3);
sgtPeppers.playTrack(7);
sgtPeppers.playTrack(7);
assertEquals(2, trackCounter.getTrackCount(1));
assertEquals(2, trackCounter.getTrackCount(2));
assertEquals(4, trackCounter.getTrackCount(3));
assertEquals(2, trackCounter.getTrackCount(7));
}
}
Here, SgtPeppers class is in com.springinaction.soundsystem.autoconfig package. TrackCounter and TrackCounterconfig are in com.springinaction.aspects.concert.config package. I get the following exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.springinaction.aspects.concert.trackCounter.TrackCounterTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.springinaction.soundsystem.autoconfig.SgtPeppers com.springinaction.aspects.concert.trackCounter.TrackCounterTest.sgtPeppers; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.soundsystem.autoconfig.SgtPeppers] 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:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:384)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:213)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:290)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
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:176)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.springinaction.soundsystem.autoconfig.SgtPeppers com.springinaction.aspects.concert.trackCounter.TrackCounterTest.sgtPeppers; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.soundsystem.autoconfig.SgtPeppers] 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:509)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290)
... 26 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.soundsystem.autoconfig.SgtPeppers] 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:1118)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:481)
... 28 more
Note: I have tried ComponentScan with basePackages, basePackageClasses. But, it didn't work. I don't use spring boot configuration as it's for learning purpose.
I have created the same SgtPeppers bean inside com.springinaction.aspects.concert.config package. Autowiring worked. Why java config way of bean creation doesn't work for beans defined in different packages?
Any suggestion would be helpful.
Thanks.

Wicket - Getting broken pipe exception when accessing DB

In my wicket application I have this service class:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
#Component
#Transactional
public class DatabaseService {
#Autowired
SessionFactory sessionFactory;
public void save(Message m) {}
}
This service class is "injected" into a wicket panel:
public class MyPanel extends Panel {
#SpringBean()
private DatabaseService service;
}
It works fine. But if I open the application hours later (server is still running), I receive following error:
java.net.SocketException: Datenübergabe unterbrochen (broken pipe)
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
[...]
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3634)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2460)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2547)
at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4874)
at org.apache.commons.dbcp.DelegatingConnection.setAutoCommit(DelegatingConnection.java:371)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.setAutoCommit(PoolingDataSource.java:328)
[...]
(JdbcResourceLocalTransactionCoordinatorImpl.java:214)
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1525)
at org.springframework.orm.hibernate5.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:500)
[...]
at de.project.database.DatabaseService$$EnhancerBySpringCGLIB$$8fa0ab80.getMessages(<generated>)
at WICKET_de.project.database.DatabaseService$$FastClassByCGLIB$$68e55e7c.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.apache.wicket.proxy.LazyInitProxyFactory$AbstractCGLibInterceptor.intercept(LazyInitProxyFactory.java:350)
at WICKET_de.project.database.DatabaseService$$EnhancerByCGLIB$$a9cbdf2b.getMessages(<generated>)
at de.project.pms.MyPanel.<init>(MyPanel.java:26)
at de.project.home.projectHome.<init>(projectHome.java:17)
Is it connected with the (un)detach mechanismn of wicket?
MySQL connections usually time out after a period of time. This causes exceptions if you are using a datasource/connection pool and do not use connection validation. From the stack trace you've pasted I see that you are using apache dbcp as a datasource, so I think you should set the following parameters on it:
validationQuery, testOnCreate, testOnBorrow, testOnReturn, testWhileIdle

Spring issue with profile

I am trying to get the variables uploaded directly based on environment in which the code is running. I wrote some code and ran into issues. Can you please point me what i am doing wrong.
WebAppInitializer.java
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext sc) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
root.scan("com.configs");
root.getEnvironment().setActiveProfiles("dev");
root.refresh();
// Manages the lifecycle of the root application context
sc.addListener(new ContextLoaderListener(root));
// Handles requests into the application
ServletRegistration.Dynamic appServlet = sc.addServlet("appServlet",
new DispatcherServlet(new GenericWebApplicationContext()));
appServlet.setLoadOnStartup(1);
Set<String> mappingConflicts = appServlet.addMapping("/");
if (!mappingConflicts.isEmpty()) {
throw new IllegalStateException(
"'appServlet' could not be mapped to '/' due "
+ "to an existing mapping. This is a known issue under Tomcat versions "
+ "<= 7.0.14; see https://issues.apache.org/bugzilla/show_bug.cgi?id=51278");
}
}
}
DynamicConfig.java
#Configuration
#Profile("dev")
#PropertySource("classpath:/devel.properties")
public class DynamicConfig {
#Autowired
Environment env;
#Bean
public TestClass testClass(){
TestClass testClass = new TestClass();
testClass.setEnvironment(env.getProperty("environment"));
return testClass;
}
}
TestClass is simple class with one instance variable which will come from config based on environment.
TestCase:
package com.tester;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.configs.DynamicConfig;
import com.configs.EnvironmentDetector;
import com.tester.TestClass;
public class TestClassTest {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DynamicConfig.class);
#Test
public void test(){
ApplicationContext context = new AnnotationConfigApplicationContext(DynamicConfig.class);
context.getEnvironment().setActiveProfiles("dev");
context.scan("com.configs");
TestClass test = context.getBean(TestClass.class);
System.out.println(test.getEnvironment());
}
}
Now I am getting below error
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.282 sec <<< FAILURE!
test(com.tester.TestClassTest) Time elapsed: 0.279 sec <<< ERROR!
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.tester.TestClass] is defined: expected single bean but found 0:
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:280)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
at com.tester.TestClassTest.test(TestClassTest.java:16)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:146)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
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.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
at $Proxy0.invoke(Unknown Source)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:87)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
When i remove the line #profile("dev") from the DynamicConfig.java code is running fine. But i want that. I want to create similar classes for prod.
Please help
Thanks
Update your test class to activate the profile. Currently you are activating it by adding the property in the WebApplicationInitializer which is not run in the context of your test.
One way to activate it would be doing the following, however it is not the only way:
#RunWith(SpringJUnit4ClassRunner.class)
#ActiveProfiles({"dev"})
#ContextConfiguration(classes = {DynamicConfig.class})
public class TestClassTest {
#Autowired
TestClass testClass;
#Test
public void test(){
System.out.println(testClass.getEnvironment());
}

LifeCycle error - not implementing the correct interface javax.portlet.filter.PortletFilter

I started to update a wep application from Tomcat 6 to the current version of Tomcat (7-27). The problem arises when I start-up the server with the following error message:
ERROR LifeCycle - Cannot start object
org.gatein.pc.portlet.container.PortletInitializationException: Cannot create filter with class com.qnamic.railopt.web.security.portlet.PortletSecurityFilter because it does not implement the expected interface javax.portlet.filter.PortletFilter
at org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(ClassInstanceLifeCycle.java:85)
at org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl.start(PortletFilterImpl.java:144)
at org.gatein.pc.portlet.impl.container.PortletFilterLifeCycle.invokeStart(PortletFilterLifeCycle.java:66)
at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:93)
at org.gatein.pc.portlet.impl.container.PortletApplicationLifeCycle.startDependents(PortletApplicationLifeCycle.java:339)
at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:129)
at org.gatein.pc.mc.PortletApplicationDeployment.install(PortletApplicationDeployment.java:153)
at org.gatein.pc.mc.PortletApplicationDeployer.add(PortletApplicationDeployer.java:216)
at org.gatein.pc.mc.PortletApplicationDeployer.onEvent(PortletApplicationDeployer.java:185)
at org.gatein.wci.impl.DefaultServletContainer.safeFireEvent(DefaultServletContainer.java:200)
at org.gatein.wci.impl.DefaultServletContainer.fireEvent(DefaultServletContainer.java:219)
at org.gatein.wci.impl.DefaultServletContainer.access$400(DefaultServletContainer.java:60)
at org.gatein.wci.impl.DefaultServletContainer$RegistrationImpl.registerWebApp(DefaultServletContainer.java:338)
at org.gatein.wci.tomcat.TC7ServletContainerContext.start(TC7ServletContainerContext.java:380)
at org.gatein.wci.tomcat.TC7ServletContainerContext.lifecycleEvent(TC7ServletContainerContext.java:234)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:168)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
A: S: R: U: ERROR LifeCycle - Cannot start object
org.gatein.pc.portlet.container.PortletInitializationException: Cannot create filter with class com.qnamic.railopt.web.core.portal.ContextFilter because it does not implement the expected interface javax.portlet.filter.PortletFilter
at org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(ClassInstanceLifeCycle.java:85)
at org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl.start(PortletFilterImpl.java:144)
at org.gatein.pc.portlet.impl.container.PortletFilterLifeCycle.invokeStart(PortletFilterLifeCycle.java:66)
at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:93)
at org.gatein.pc.portlet.impl.container.PortletApplicationLifeCycle.startDependents(PortletApplicationLifeCycle.java:339)
at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:129)
at org.gatein.pc.mc.PortletApplicationDeployment.install(PortletApplicationDeployment.java:153)
at org.gatein.pc.mc.PortletApplicationDeployer.add(PortletApplicationDeployer.java:216)
at org.gatein.pc.mc.PortletApplicationDeployer.onEvent(PortletApplicationDeployer.java:185)
at org.gatein.wci.impl.DefaultServletContainer.safeFireEvent(DefaultServletContainer.java:200)
at org.gatein.wci.impl.DefaultServletContainer.fireEvent(DefaultServletContainer.java:219)
at org.gatein.wci.impl.DefaultServletContainer.access$400(DefaultServletContainer.java:60)
at org.gatein.wci.impl.DefaultServletContainer$RegistrationImpl.registerWebApp(DefaultServletContainer.java:338)
at org.gatein.wci.tomcat.TC7ServletContainerContext.start(TC7ServletContainerContext.java:380)
at org.gatein.wci.tomcat.TC7ServletContainerContext.lifecycleEvent(TC7ServletContainerContext.java:234)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:168)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
The class com.qnamic.railopt.web.security.portlet.PortletSecurityFilter does implement the interface javax.portlet.filter.PortletFilter:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Principal;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.portlet.filter.ActionFilter;
import javax.portlet.filter.EventFilter;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.portlet.filter.ResourceFilter;
import org.apache.log4j.Logger;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class PortletSecurityFilter implements ActionFilter, EventFilter, RenderFilter, ResourceFilter {
ActionFilter does implement javax.portlet.filter.PortletFilter
The dependent jars are:
primefaces-3.2.jar
spring-core-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-aop-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-webmvc-portlet-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
portlet-api-2.0.jar
Platform-3.8.0.jar
jdo-2.0.jar
kodo-runtime.jar
openjpa-1.0-fast.jar
PlanOpt-3.8.0.jar
RailOptBase-3.8.0.jar
portletfaces-bridge-api-2.0.0-RC1.jar
portletfaces-bridge-impl-2.0.0-RC1.jar
portletfaces-logging-1.1.0.jar
commons-collections-3.2.1.jar
spring-web-3.0.5.RELEASE.jar
aopalliance-1.0.jar
spring-beans-3.0.5.RELEASE.jar
spring-security-web-3.0.5.RELEASE.jar
spring-security-core-3.0.5.RELEASE.jar
spring-tx-3.0.3.RELEASE.jar
aspectjrt-1.6.8.jar
aspectjweaver-1.6.8.jar
spring-security-config-3.0.5.RELEASE.jar
log4j-1.2.15.jar
el-api-1.0.jar
slf4j-api-1.5.8.jar
servlet-api-2.5.jar
jstl-1.2.jar
commons-lang-2.5.jar
RailOptIntegration-3.8.0.jar
google-collections-1.0.jar
junit-4.8.2.jar
commons-io-2.0.1.jar
el-impl-2.2.jar
javax.faces-2.1.7.jar
Some dependencies have the scope "provided" and are not included in the war (as long tomcat doesn't use them)!
Part of my portlet.xml
<filter>
<filter-name>PortletSecurityFilter</filter-name>
<filter-class>com.qnamic.railopt.web.security.portlet.PortletSecurityFilter</filter- class>
<lifecycle>ACTION_PHASE</lifecycle>
<lifecycle>EVENT_PHASE</lifecycle>
<lifecycle>RENDER_PHASE</lifecycle>
<lifecycle>RESOURCE_PHASE</lifecycle>
<init-param>
<name>message</name>
<value>Security Filter</value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PortletSecurityFilter</filter-name>
<portlet-name>*</portlet-name>
</filter-mapping>
The other dependencies are found in a parent project:
pc-api-2.2.0-GA.jar
pc-controller-2.2.0-GA.jar
pc-portlet-2.2.0-GA.jar
pc-mc-2.2.0-GA.jar
wci-wci-2.1.1-GA.jar
wci-tomcat7-2.1.1-GA.jar
When I debug the code in
org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(...)
it stops on the second line
Class clazz = classLoader.loadClass(className);
if (expectedClass.isAssignableFrom(clazz)) {
Class<? extends T> castedClass = clazz.asSubclass(expectedClass);
Constructor<? extends T> ctor = castedClass.getConstructor();
instance = ctor.newInstance();
}
else {
String msg = "Cannot create " + type + " with class " + className + " because it does not implement the expected interface " + expectedClass.getName();
throw new PortletInitializationException(msg);
}
My suggestion was first that there is a problem with the class loader but it shouldn't be, because the first line correctly loads the class PortletSecurityFilter. The expected class is javax.portlet.filter.PortletFilter as expected. Why the class is not assignable from?
I thank for any help!
I must admit that I have no idea what is the exact version of GateIn you used to meet this issue but anyway I could reproduce this issue with GateIn-3.2.0.Final-tomcat7 by simply keeping (on purpose) portlet-api-2.0.jar in the WEB-INF/lib directory of my war file. I could then get something like:
28 janv. 2013 15:48:09 org.gatein.common.logging.Logger log
GRAVE: Cannot start object
org.gatein.pc.portlet.container.PortletInitializationException: Cannot create filter with class org.exoplatform.tutorial.portlet.MyPortletFilter because it does not implement the expected interface javax.portlet.filter.PortletFilter
at org.gatein.pc.portlet.impl.jsr168.ClassInstanceLifeCycle.create(ClassInstanceLifeCycle.java:85)
at org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl.start(PortletFilterImpl.java:144)
at org.gatein.pc.portlet.impl.container.PortletFilterLifeCycle.invokeStart(PortletFilterLifeCycle.java:66)
at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:93)
at org.gatein.pc.portlet.impl.container.PortletApplicationLifeCycle.startDependents(PortletApplicationLifeCycle.java:339)
at org.gatein.pc.portlet.impl.container.LifeCycle.managedStart(LifeCycle.java:129)
at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployment.install(PortletApplicationDeployment.java:153)
at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployer.add(PortletApplicationDeployer.java:199)
at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployer.onEvent(PortletApplicationDeployer.java:168)
at org.gatein.wci.impl.DefaultServletContainer.safeFireEvent(DefaultServletContainer.java:200)
at org.gatein.wci.impl.DefaultServletContainer.addWebAppListener(DefaultServletContainer.java:166)
at org.gatein.pc.portlet.impl.deployment.PortletApplicationDeployer.start(PortletApplicationDeployer.java:241)
at org.exoplatform.portal.pc.ExoKernelIntegration.start(ExoKernelIntegration.java:178)
at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.exoplatform.container.LifecycleVisitor.traverse(LifecycleVisitor.java:100)
at org.exoplatform.container.LifecycleVisitor.start(LifecycleVisitor.java:170)
at org.exoplatform.container.ConcurrentPicoContainer.start(ConcurrentPicoContainer.java:554)
at org.exoplatform.container.ExoContainer.start(ExoContainer.java:266)
at org.exoplatform.container.PortalContainer.start(PortalContainer.java:667)
at org.exoplatform.container.ExoContainer.start(ExoContainer.java:254)
at org.exoplatform.container.RootContainer.createPortalContainer(RootContainer.java:399)
at org.exoplatform.container.RootContainer.registerPortalContainer(RootContainer.java:266)
at org.exoplatform.portal.application.PortalController.afterInit(PortalController.java:114)
at org.exoplatform.container.web.AbstractHttpServlet.init(AbstractHttpServlet.java:79)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1201)
I could fix it by simply removing portlet-api-2.0.jar from WEB-INF/lib of my webapp (or defining this dependency in maven as provided). This happens simply because the jar file is already in tomcat/lib so the Portlet Container refers to the class javax.portlet.filter.PortletFilter that has been loaded from the common ClassLoader of Tomcat and your Filter implements the class javax.portlet.filter.PortletFilter that has been loaded from the ClassLoader of your webapp (from WEB-INF/lib), even if the FQN of these 2 classes are equal, they are not considered as the same classes that is the reason why expectedClass.isAssignableFrom(clazz) returns false.

Resources