Spring - can't get simple aspect working - spring

ERROR
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/callcentre] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class
HandlerMethod details:
Controller [$Proxy109]
Method [public final java.lang.String au.com.mycompany.web.controllers.DummyControllerImpl.dummy()]
Resolved arguments:
] with root cause
java.lang.IllegalArgumentException: object is not an instance of declaring class
...
MAVEN DEPENDENCY
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.framework.version}</version>
</dependency>
SERVLET-CONTEXT.XML
<aop:aspectj-autoproxy />
ASPECT
#Aspect
#Component
public class JsonAspect {
#Before("execution(public * au.com.mycompany.web.controllers.DummyController.dummy(..))")
public final void beforeMethod1(final JoinPoint joinPoint) {
System.out.println("Intercepted.............");
System.out.println(joinPoint.getSignature().getName());
}
}
CONTROLLER INTERFACE
#Controller
public interface DummyController {
#RequestMapping(value = "/dummy", method = RequestMethod.GET)
#ResponseBody
String dummy();
}
CONTROLLER IMPL
#Controller
public class DummyControllerImpl implements DummyController {
#Override
public final String dummy() {
System.out.println("IT WORKED..........");
return "it returned";
}
}

I assume this is no longer relevant, but I had the exact same issue and the solution was to set this in the application context:
<aop:aspectj-autoproxy proxy-target-class="true"/>
Root cause, is that the AOP Auto Proxy generated for this class is a JdkAutoProxy instead of a CGLIB generated proxy - which causes a failure in the spring MVC invocation of the API since the proxy is not of the same type as the controller.
The reason for this JdkAutoProxy is since this specific controller implements an interface, which causes spring to automatically use the JDK auto proxy.

Related

Start Springboot without any Undertow Configuration

I have a project which mixes 2 dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-installed-adapter</artifactId>
<version>11.0.2</version>
</dependency>
I'm getting a transitiv dependency for Undertow, which comes from
keycloak-installed-adapter
As far as I understood, Undertow is used internally within the KeyCloak libraries.
I don't want my Springboot Application to start with Undertow, nor I want that anything related with Undertow gets configured at Springboot level.
I can't find to completely exclude any Undertow configuration for Springboot. Does anyone have an idea?
Update
I now have the following:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {EmbeddedUndertow.class})
public class SpringbootTest {
public static void main(String[] args) {
SpringApplication.run(SpringbootTest.class, args);
}
}
But i'm getting following exception when starting my service:
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'undertowEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedUndertow.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory]: Factory method 'undertowEmbeddedServletContainerFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: io/undertow/servlet/api/SessionPersistenceManager
Knowing that the EmbeddedUndertow Class lokks like:
#Configuration
#ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
#ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedUndertow {
#Bean
public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
return new UndertowEmbeddedServletContainerFactory();
}
}
How would you ignore this calss from the scanning?

why jdk proxy could not be injected

I use Aspect like this:
#Aspect
#Component
public class DataSourceAspect {
#Pointcut("#target(com.chen.dynamicsource.aspect.DataSource)")
public void pointCut() {
}
#Before("pointCut()")
public void doBefore(JoinPoint joinPoint) {}
}
And I add it to application.yml:
spring
aop:
proxy-target-class: false
When I run the application. I get the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'dispatcherServlet' could not be injected because it is a JDK dynamic proxy
The bean is of type 'com.sun.proxy.$Proxy67' and implements:
org.springframework.context.ApplicationContextAware
org.springframework.core.env.EnvironmentCapable
org.springframework.context.EnvironmentAware
javax.servlet.Servlet
javax.servlet.ServletConfig
java.io.Serializable
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
org.springframework.core.DecoratingProxy
Expected a bean of type 'org.springframework.web.servlet.DispatcherServlet' which implements:
I know I can use statically evaluated pointcut designators like within () and change the value of proxy-target-class to true to avoid the problem.
But I just want to know why jdk proxy could not be injected.

Spring Lookup Method Injection failing with AbstractMethodError

I have a singleton service class like the below.
#Service
public class SingletonClass{
#Autowired
private ContextProvider provider;
public Context run(){
context = provider.createContext();
updateContext(context)
}
ContextProvider class:
public abstract class ContextProvider implements MyInterface{
public abstract Context createContext();
}
configuration:
<bean name="provider"
class="xyz.s.s.ContextProvider" >
<lookup-method name="createContext"
bean="someBean" />
</bean>
<bean id="somebean" class="com.x.y.someclass" />
<bean id="singletonService" class="com.x.y.SingletonClass" />
When i try to run the above using Junit ->instead of creating the lookup bean on demand, I am getting the below error
org.springframework.beans.factory.BeanCreationException:
aused by: java.lang.AbstractMethodError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1585)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
It seems, the lookup method injection is not working in my case
I found the issue and fixed it.
I was having the abstract class implemented an interface. So at run time,
CGLIB unable to create a proxy class since there are unimplemented methods.
Compiler also did not complain, because this is abstract class and it did not expect us to add all implementations of the interface.
I removed the 'implements ' and it just works fine.
So the contextprovider will become,
public abstract class ContextProvider {
public abstract Context createContext();
}
Posting this message, since people might face same situation.

Spring constructor dependency Injection Issues

I have 2 classes
public class Abcd{
private String username;
private String password;
public Abcd(#Value("${username}") String userName, #Value("${password}") String password) {
...
}
public String retrieveValues(){
......
return "someString";
}
}
public class SomeClass{
#Autowired
private Abcd obj;
public String method1(){
obj.retrieveValues();
}
I have a Xml as below.
<context:annotation-config />
<context:property-placeholder location="classpath:applNew.properties" />
<bean id="abcd" class="com.somecompany.Abcd">
<constructor-arg type="java.lang.String" value="${prop.user}" />
<constructor-arg type="java.lang.String" value="${prop.password}" />
</bean>
<bean id="someclass"
class="com.differentcompany.SomeClass">
</bean>
When I build the project and start the server, i see the below exceptions.
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'abcd' defined in URL []: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class []: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
I dont understand what could be the issue to do a constructor injecting this way. Is there any solution for this?
Classes to be proxied by CGLIB (for AOP support) must have no-args constructors.
These no-args constructors don't have to be public and it doesn't affect anything else - you can use other constructors as usually:
public class Abcd{
// Dummy constructor for AOP
Abcd() {}
public Abcd(#Value("${username}") String userName, #Value("${password}") String password) { ... }
...
}
See also:
7.6 Proxying mechanisms

Proxy Exception while injecting spring bean into JSF bean

I'm trying to inject spring bean into JSF bean, I'm using Spring 3.1 and JSF 2 (Mojarra 2.1.7)
Without a lot of talking my configuration and code and exception listed in the following:
StudentService.java:
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)
public class StudentsService extends AbstractMaqraaService {
#Override
public Set<Class<?>> getTypes() {
// TODO Auto-generated method stub
return null;
}
public Student registerStudent(Student student) {
return this.store(student);
}
}
StudentRegistrationMBean.java:
#ManagedBean(name="studentRegistrationMBean")
#SessionScoped
public class StudentRegistrationMBean extends AbstractMBean {
private Student student;
#ManagedProperty (value="#{studentsService}")
private StudentsService studentsService;
public StudentRegistrationMBean() {
this.student = new Student();
}
/*Setters and getters omitted here only*/
public String register() {
studentsService.registerStudent(student);
return "manageStudents";
}
}
Spring bean in module context xml file:
<bean id="abstractMaqraaService" class="org.tts.maqraa.service.AbstractMaqraaService" abstract="true"/>
<bean id="studentsService" class="org.tts.maqraa.service.StudentsService" lazy-init="default" parent="abstractMaqraaService"/>
faces-config.xml:
...
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
...
Eception:
TRACE [http-bio-8080-exec-3] (SpringBeanELResolver.java:53) - Successfully resolved variable 'studentsService' in Spring BeanFactory
DEBUG [http-bio-8080-exec-3] (AbstractBeanFactory.java:245) - Returning cached instance of singleton bean 'studentsService'
نوار 13, 2012 11:10:45 ص com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/teacher/registerNewStudent.xhtml]
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to set property studentsService for managed bean studentRegistrationMBean
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
at com.sun.faces.mgbean.ManagedBeanBuilder.buildBean(ManagedBeanBuilder.java:133)
...
at java.lang.Thread.run(Unknown Source)
Caused by: javax.el.ELException: Cannot convert org.tts.maqraa.service.StudentsService#8f65bc0 of type class $Proxy10 to class org.tts.maqraa.service.StudentsService
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:420)
at org.apache.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:47)
at com.sun.faces.el.ELUtils.coerce(ELUtils.java:536)
at com.sun.faces.mgbean.BeanBuilder$Expression.evaluate(BeanBuilder.java:592)
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:606)
... 47 more
ERROR [http-bio-8080-exec-3] (MaqraaExceptionHandler.java:83) - Exception
javax.el.ELException: Cannot convert org.tts.maqraa.service.StudentsService#8f65bc0 of type class $Proxy10 to class org.tts.maqraa.service.StudentsService
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:420)
...
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I made a lot of search in Google and found a lot of questions here had issues like mine but nothing helped me, I hope I'll find my solution for my special case !!
use <aop:aspectj-autoproxy proxy-target-class="true"/> to enforce use of JDK proxy rather than CGLIB
if you inject your Spring service like this don't forget to create the setter for your Service:
#ManagedProperty (value="#{studentsService}")
private StudentsService studentsService;
public void setStudentsService (StudentsService studentsService)
{
this.studentsService = studentsService;
}
With the #Autowired annotation there was no need to do this.
Take a look at this answer It's about not using an interface for using your proxy.

Resources