Search code examples
javaspringaspectjaspect

Unable to apply aspects to String class


I was experimenting with AspectJ. I tried to apply aspect on String class. I created Spring configuration file as:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <!-- Enable @AspectJ annotation support -->
    <aop:aspectj-autoproxy />

    <!-- Employee manager -->
    <bean id="employeeManager" class="com.test.advice.EmployeeManager" />

    <!-- Logging Aspect -->
    <bean id="loggingAspect" class="com.test.advice.LoggingAspect" />

    <bean id="bean1" class="java.lang.String">
        <constructor-arg value="abx" />
    </bean>

</beans>

Then an Aspect class like,

package com.test.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LoggingAspect
{

    @Around("execution(* java.lang.String.*(..))")
    public void logAroundGetEmployee(ProceedingJoinPoint joinPoint) throws Throwable
    {
        System.out.println("works");
    }
}

After that created a class with a main method like:

package com.test.advice;

package com.test.advice;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AspectJAutoProxyTest
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Customer.xml");

        String pqr = (String) context.getBean("bean1");

        pqr.trim();

    }
}

On running it should output "works" to console. But it fails saying,

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy5 cannot be cast to java.lang.String
    at com.test.advice.AspectJAutoProxyTest.main(AspectJAutoProxyTest.java:13)

What is the issue? Can't we apply proxy to java.lang objects? Please help.


Solution

  • To use a proxy object as a replacement for the real object, the proxy object must be of a subclass of the real object. String being final, the JVM does not permit creating such a subclass.

    (Note that spring has two proxy modes; one creates an actual subclass and the other just implements all public interfaces. You're probably using the latter, but if you changed to the former, you'd see an exception at proxy creation time)