Using CGLIB proxy with Ehcache CacheManager - spring

I want to use Spring AOP in my spring application. While creating AOP proxy for net.sf.ehcache.CacheManager, spring context initialization fails with the below exception:
nested exception is org.springframework.aop.framework.AopConfigException: Could not
generate CGLIB subclass of class [class net.sf.ehcache.CacheManager]: Common causes of
this problem include using a final class or a non-visible class; nested exception is
net.sf.cglib.core.CodeGenerationException: net.sf.ehcache.CacheException-->Another
unnamed CacheManager 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=java.io.ByteArrayInputStream#955b34]
Here's my understanding about this problem - Spring is trying to create AOP proxy for net.sf.ehcache.CacheManager, and it succeeds the first time and gives a default name to the CacheManager __DEFAULT__ (found this by adding debug statements to ehcache code, building it by source and using that in my application). Now if I've multiple cache managers like 'abcCacheManager' and 'xyzCacheManager' (of type EhCacheManagerFactoryBean), Spring encounters multiple net.sf.ehcache.CacheManagers and tries to create proxy objects (something like net.sf.ehcache.CacheManager$$EnhancerByCGLIB$$b18c5958) for all of them, but with EhCache >=2.5 version, we can't have more than one caches with same name under the same VM.
I'm using EhCache 2.5.1 and would like to avoid going back to 2.4 just for this purpose. I'm not sure if this is really the problem how I can overcome this problem.
Note: Note sure if this will help, but I also noticed from the debug statements that CacheManager no-arg constructor is invoked only by the spring/CGLIB proxy generator and xyzCacheManager invokes it by passing configuration as argument.

Note : I'm answering this myself as it may help others who face the same problem.
jeha's comment on my question makes sense as I shouldn't have needed that proxy at the first place, but since I'm new to Spring AOP and proxies, I didn't know how auto-proxy mechanism works. As I modified the pointcut expressions in my advice, I didn't face the above problem after that. Prior to this, almost all the beans in the container were getting proxied and hence the problem.

Related

Does ComponentScan order matter?

I'm setting up a very small Spring/REST/JPA project with Boot, using annotations.
I'm getting some Bean not found errors in my REST controller class that has an Autowired repository variable, when I move my JPA repository class out to a different package, and calling componentscan on its package. However, everything was working fine when all my files(5 total) were in the same package.
So I was wondering, however unlikely, if the component scan order matters? For example, if a class is AutoWiring some beans from a package that has not been 'component scanned' yet, will that cause a Bean not found error?
No, Spring loads all configuration information, from files and annotations and the environment when appropriate. It then creates beans (instances of classes) according to a dependency tree that it calculates in memory. In order to do this it has to have a good idea of the entire configuration at startup. The whole model derived from all the aggregated configuration information is called the Application Context.
In modern versions of spring the application context is flexible at runtime and so it's not quite the case that all the configuration is necessarily known up front, but the configuration that is flexible is limited in scope and must be planned for carefully.
Maybe you need to share some code. When you move that stuff, you also need to tell Spring where they went. My guess would be you haven't defined #EntityScan and #EnableJpaRepositories (which default to the location of #EnableAutoConfiguration).
There could be several problems:
You moved your class out of the some package where you have #ComponentScan without arguments. That basically means that components are scan only in this package and its children. Thus, moved class are not scanned and there is no bean to wire.
Wrong package name in #ComponentScan args.
The order isn't matter at all. There is an #Order annotation, but it's purpose is more about loading multiple implementations of sth in a different order.
At first Bean Definitions are created and they have nothing to do with wiring. Then via bean post processors, autowired beans are injected. Since there were no bean definition. There is nothing to inject.
In a well structured program it doesn't, because first each bean gets instantiated, then autowired and then you can actually use them.
However there could be situations where the order does matter and I had an issue figuring out what was going on. So this is an example where it would matter:
You have some Repository that you want to fill with data initially, call it SetupData component.
Then you use #PostConstruct to save the default objects.
You have some component that this Repository depends on but isn't managed by Spring, for example a #Converter.
And that #Converter depends on some other component which you would statically inject.
In this case #PostConstruct methods will be executed before the components into your #Converter get autowired which will result in an exception.
Relying on ComponentScan order is a bad habit, because it's not intuitive especially when you are working with multiple people who may not know about. Or there might be such dependencies that you can't fix the code by changing the scan order.
The best solution in this case was using a task executor service that takes care of running initialization functions.

Spring application has Cglib2AopProxy warnings

Upon starting my application, I get numerous warnings along the lines of o.s.aop.framework.Cglib2AopProxy 'Unable to proxy method [public final void org.springframework.jdbc.core.support.JdbcDaoSupport.setDataSource(javax.sql.DataSource)] because it is final: All calls to this method via a proxy will be routed directly to the proxy.' for about a dozen or so functions.
Now I perfectly understand that proxy-based aspects cannot be applied to final methods. However, I did not (on purpose, at least) try to weave any aspects into JdbcDaoSupport. I suspect it comes from <tx:annotation-driven />. Is there anything I can do to silence these warnings or, better yet, exclude those classes from the aspect weaving?
This is most likely caused by the #Transactional annotation, Spring wraps your DAO in a proxy to add the transactional behavior.
I would recommend to make your DAO implement an Interface (create and use an interface for your DAO), this will allow Spring to use a JDK dynamic proxy instead of having to use CGLib.
Using CGLIB has a limitation that methods marked as final in target class can’t be advised as final methods can’t be overridden (CGLIB creates a subclass of target class at runtime) but this limitation disappears in case of using JDK dynamic proxies.
Reference
Maybe you have extended JdbcDaoSupport and added #Transactional annotations.
You can set the Cglib2AopProxy logger to log level ERROR to avoid the warn messages. For example if using log4j and log4j.properties:
log.logger.org.springframework.aop.framework.Cglib2AopProxy = ERROR
You should use interfaces for dependency injection, the most reasons for this are described here and here.
You can read documentation about proxying mechanic for details why you see this warning.
And please vote for feature request of inspection for IntelliJ that may helps us to avoid this warnings. BTW It also contains a good explanation.
Spring Boot now uses CGLIB proxying by default, including for the AOP support. If you need interface-based proxy, you’ll need to set the spring.aop.proxy-target-class to false.
spring.aop.proxy-target-class=false

spring using CGLIB proxy even when class implements interface

I'm trying to use Spring AOP to intercept methods of my GWT-RPC application (using GWT-Server library, so RPC service doesn't extend RemoteServiceServlet). When I deploy my war to tomcat and start the application, CGLIB fails for some reason. But I don't understand why CGLIB is being used for proxying at the first place. Since my RPC class implements the interface, shouldn't it be using JDK dynamic proxies?
Is there anything I need to do to debug this issue? Kindly advise.
Note: FYI, Spring encounters this exception, but I believe that's a different problem, I'm unable to understand why CGLIB proxy is in the picture.
Caused by: net.sf.cglib.core.CodeGenerationException: net.sf.ehcache.CacheException-->Another unnamed CacheManager 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.
Answering for the sake of other (rare) folks who might do the same mistake.
The aspect setup for spring AOP wasn't correct and was in fact trying to target almost all the classes in the context, which is why EhCache started causing problems as there were more than one CacheManager instances (because of CGLIB proxies as CacheManager doesn't implement an interface)

hibernate validator without using autowire

I'am currently working on a Jersey project and decided to use Hibernate validator for the parameter validations. All dependencies injected on the Endpoint classes are properly initialized. However for those dependencies in the ConstraintValidator classes, it always throw a NPE. So i followed the guide on Spring+hibernate guide and registered
bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
and used the #Autowired annotation for the services in the ConstraintValidator class which needs to be injected.
are there side effects of using it? Is there a way to avoid the autowiring annotation in ConstraintValidator class and still injecting the values? I tried manually registering the constraintValidator class in the context as bean, adding a property reference to the service that i need, however it throws a null pointer exception.
"Hibernate Validator - JSR 303 Reference Implementation - Reference Guide" says something about portality:
Warning
Any constraint implementation relying on ConstraintValidatorFactory
behaviors specific to an implementation (dependency injection, no no-arg
constructor and so on) are not considered portable.
So, is it a bad thing? In my opinion it's not. Of course you are now coupled to the DI container (Spring) and can't easily reuse validators (e.g. when not using Spring). On the other hand, with your validators build by a Spring factory you can take full advantage of the framework and do very heavy lifting (read revision data for entities and comparison of previous states, call arbitrary services, enhance or localize validation messages, ...).
One thing you must be very careful about is that a validator's semantics is normally read-only and should not cause side-effects by calling it. For example don't accidentally flush data to the database because of some auto-flushing by invoking a (transactional) service or reading data inside your validator.

Spring Instantiation and 'unused beans'

I'm working on a project which means customising an existing application (JasperServer 3.7.1) which is implemented in Spring 2.5.6 (plus a host of other Spring frameworks).
The application consists of a host of applicationContext*.xml containing the bean definitions which when wired together by Spring bring the app to life - I think it's a typical Spring app configuration as although it my first experience using Spring, it seems all quite well put together and follows a lot of the examples I have seen on the web and in books..
Because I'm actually modifying an existing application, changing beans like filterChainProxy (because we have our own security model ,for example) I'm wary of changing the actual config files that come with the product - instead, where possible, I'd prefer to add extra appContext config files to the existing ones which override existing beans (ie leave the original config in tact, as much as possible).
This I've managed to do by creating beans implementing BeanFactoryPostProcessor which on pre-bean initialisation allow me to change the existing property values/bean references to custom ones. This all seems to be working fine.
My query is, say I had a bean with a property that referred to another bean, and my overrider bean changed that reference to my own version of bean, will Spring still instantiate the bean that is no longer referred to ? The reason for asking obviously is that some of these unused beans may be taking up resources, which may be an unwanted overhead.
Thanks in advance
I'm not sure I follow your example, but it might help to clarify a few things.
Generally, Spring will instantiate a bean for every non-abstract bean definition in the context (this is ignoring things like non-singleton bean scopes, but I'll ignore that for the purposes of this explanation). If multiple bean definition files are used, and some bean names are duplicated, then some definitions will be overridden by others. so far, so good, this seems to be what you wanted.
Once the bean definitions have been established, and any duplicated dealt with, then Spring will then instantiate a bean for each of those definitions. If you have changed the definition of BeanA so that it no longer refers to BeanB, but instead refers to BeanC, but the definition of BeanB still exists, then BeanB will still be instantiated, even if it's not being used.
If that example is not representative of your question, then please elaborate.

Resources