Issue Details (XML | Word | Printable)

Key: BATCH-740
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Mark St.Godard
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Spring Batch

Cannot create CGLib Proxy for SimpleJobRepository

Created: 21/Jul/08 11:48 AM   Updated: 21/Jul/08 03:57 PM
Component/s: Core
Affects Version/s: 1.0.1, 1.1.0
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments: 1. Text File stackTrace.txt (10 kB)



 Description  « Hide
I am using CGLib proxies (i.e. proxy-target-class -> true).... and (according to Spring batch documentation & examples)...
when I tried to apply transaction management around the JobRepository... I get an error when creating the proxy...


Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.springframework.batch.core.repository.support.SimpleJobRepository]: Common causes of this problem include using a final class or a non-visible class; nested exception is net.sf.cglib.core.CodeGenerationException: java.lang.IllegalAccessError-->tried to access method org.springframework.batch.core.repository.support.SimpleJobRepository.<init>()V from class org.springframework.batch.core.repository.support.SimpleJobRepository$$EnhancerByCGLIB$$1b091047

(see full trace in comment below)


For example:


<aop:config proxy-target-class="true">

<!-- Transaction Management -->
<aop:advisor pointcut="SystemArchitecture.businessService() || execution(* org.springframework.batch.core..*Repository+.*(..))"
advice-ref="txAdvice" />

</aop:config>

<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="createJobExecution" propagation="REQUIRES_NEW" isolation="SERIALIZABLE" /> <!-- Added for Spring Batch -->
                          . . .
<tx:method name="*" propagation="REQUIRED" />

</tx:attributes>
</tx:advice>


<!-- this is our class... hack to fix constructor scope, -->
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.SimpleJobRepository">
                . . .
        </bean>



Side Note: I would like to use regular Java dynamic proxies, however I do need CGLib proxies for a small set of my objects in my application ...
and I believe the way that autoproxying works is that if you use the proxy-target-class="true" in one <aop:config> snippet... and false in all others...
the CGLIb proxy target class will override the other behavior.... i.e. even if you say false... it will create CGLib proxies... anyway... a moot point... just wanted
to let you know that I DO NOT have a choice to not use CGLib proxies :)


Cheers
Mark


 All   Comments   Work Log   Change History   FishEye   Related Builds      Sort Order: Ascending order - Click to sort in descending order
Mark St.Godard added a comment - 21/Jul/08 11:49 AM
Attached full stack trace

Mark St.Godard added a comment - 21/Jul/08 11:54 AM
Note: The reason CBLib is failing to create the proxy is due to the fact that the SimpleJobRepository does not have a public default constructor
although the comment in the code seems to have that intention...

/**
* Provide default constructor with low visibility in case user wants to use
* use aop:proxy-target-class="true" for transaction interceptor.
*/
SimpleJobRepository() {
}



More information on the original forum posts:
http://forum.springframework.org/showthread.php?p=189081

Dave Syer added a comment - 21/Jul/08 12:33 PM
What version of Spring are you using? It should work with 2.5.x. Not sure where (in 2.0.x?) this would have been fixed in Spring Core.

Mark St.Godard added a comment - 21/Jul/08 12:55 PM
Hi Dave,


Re: "It should work with 2.5.x. Not sure where (in 2.0.x?) this would have been fixed in Spring Core."

I am using Spring 2.5.5... You think the auto proxying and mix and matching proxy-target-class works in the latest.. ?
I will check the source, do you know if its something you need to enable? (i.e. not the default behavior)

That would be good, because that would solve 2 of my problems... :)

However, I believe the problem would still remain if you wanted to use CGLib.....

Is there a reason why the constructor is "default" visibility?

Cheers
Mark

Dave Syer added a comment - 21/Jul/08 01:12 PM
The constructor is default visibility because it doesn't make sense as part of the public API (as signalled by the real constructor with all the mandatory properties). I tried a quick experiment with proxy-target-class="true" and a simple non-batch test case and that worked with 2.5.5, so I'm not sure why your experience should be any different. I didn't do anything fancy (using cglib:cglib-nodep:2.1_3).

Mark St.Godard added a comment - 21/Jul/08 03:57 PM
Hi Dave,

Very weird, yeah I have the same Spring and CGlib version.... I also dumbed down my example and I still get one aop:config overriding the others.

I apologize in advance, for veering off into the Spring Core....


But I do see these issues related to your comment that this is fixed

http://jira.springframework.org/browse/SPR-2593
http://jira.springframework.org/browse/SPR-1980

I looks like Juergen said he checked some stuff in ... however I didnt see anything obvious in FishEye...

I know when I debug my example... it gets into AopNamespaceUtils... twice.. and one of the invocations,
then calls AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);

private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(
sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)).booleanValue();
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
}
}


Did you have your non-batch test case?

I would be curious to run it as well... in my example, I did a simple case with 2 applicationContext files, 1 bean in each, and 2 aop-config snippets... one with proxy-target-class set to true....


I am probably missing something

Cheers