Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TomcatInstrumentableClassLoader should support Tomcat 7.0.63+ as well [SPR-13210] #17802

Closed
spring-issuemaster opened this issue Jul 7, 2015 · 17 comments
Assignees
Milestone

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Jul 7, 2015

Emil Lundström opened SPR-13210 and commented

TomcatInstrumentableClassLoader in spring-instrument-tomcat contains a method override:

@Override
protected ResourceEntry findResourceInternal(String name, String path) {
    ...
}

which in Tomcat 7.0.63 no longer exists. Another parameter has been added, and the method signature is now:

protected ResourceEntry findResourceInternal(String name, String path, boolean manifestRequired)

(see http://svn.apache.org/repos/asf/tomcat/tc7.0.x/tags/TOMCAT_7_0_63/java/org/apache/catalina/loader/WebappClassLoader.java)

The "overridden" method is never called, so the weaving process fails silently. Issue does not reproduce on Tomcat 7.0.62.


Affects: 4.1.7

Issue Links:

  • #18073 Require Undertow 1.3.5+, Tyrus 1.11+, Jetty 9.3+, Tomcat 8.5+ ("is depended on by")
  • #15414 Use Tomcat 8's new instrumentable WebappClassLoader

Referenced from: commits 08fb625, 37f74e7

0 votes, 5 watchers

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 7, 2015

Juergen Hoeller commented

This is not easy to fix since we can't properly call superclass methods reflectively... and we need to remain compatible with Tomcat 6.0+ still.

That said, Tomcat 7.0.44+ has a new InstrumentableClassLoader facility which we support as of Spring 4.0 already. All that it takes is <context:load-time-weaver> / @EnableLoadTimeWeaving which automatically registers a TomcatLoadTimeWeaver in case of Tomcat.

That native facility should work fine on Tomcat 7.0.63+ as well. So I recommend to simply drop your custom TomcatInstrumentableClassLoader definition and let Spring figure out how to use Tomcat's native InstrumentableClassLoader. If that doesn't work for you for some reason, let me know.

In any case, we should a note on this to the reference documentation, so I'm turning this into a documentation task.

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 7, 2015

Juergen Hoeller commented

I've added explicit notes for load-time weaving on Tomcat 7.0.63+ and WildFly 9 to the reference documentation.

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 7, 2015

Emil Lundström commented

I think you are referring to #15414, and the corresponding issue in Tomcat's issue tracker: https://bz.apache.org/bugzilla/show_bug.cgi?id=55317

Unfortunately, as far as I can tell, that patch was never backported into Tomcat 7.0.44 despite what the title says. InstrumentableClassLoader only exists in Tomcat 8.0+.

I ended up going back to Tomcat 7.0.62 for now. Using -javaagent with spring-instrument is of course also a workaround.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 7, 2015

Juergen Hoeller commented

Ouch, even Tomcat's javadoc is wrong then, since it explicitly declares 7.0.44 there. I only ever tried this against Tomcat 8 and just assumed it would be there in 7.0.44+ as well :-(

Here's the Tomcat change that led to the change in findResourceInternal's signature:
https://bz.apache.org/bugzilla/show_bug.cgi?id=58023

Let's see what we can do about this, also involving Mark Thomas from the Tomcat team who was certainly not aware of the implications of this change...

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 13, 2015

Juergen Hoeller commented

We're compiling our TomcatInstrumentableClassLoader against a mock of Tomcat's WebappClassLoader now, allowing us to declare and override both versions of findResourceInternal... so that when bound to a real Tomcat WebappClassLoader at runtime, we'll override both the pre-7.0.63 and the 7.0.63+ variant of that method.

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 14, 2015

Andrei Ivanov commented

I've just noticed that LTW doesn't work properly when switching from 8.0.22 to 8.0.24 :(
Any chance this issue could apply in my case too?
I don't see any errors, just that the aspect doesn't get woven somehow.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 14, 2015

Juergen Hoeller commented

This might indeed be related, since I suppose that the same change has been made in the Tomcat 8 line. The same fix, coming in 4.2 RC3, should also work on Tomcat 8 then.

However, are you still using Spring's TomcatInstrumentableClassLoader with Tomcat 8 to begin with? With TomcatLoadTimeWeaver, auto-selected by Spring when running on Tomcat, you should be able to rely on Tomcat 8's native instrumentation capabilities...

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Andrei Ivanov commented

I've started to investigate the issue since it was failing with TomcatLoadTimeWeaver on 8.0.22.
As far as I see, the only combination that worked was with TomcatInstrumentableClassLoader on 8.0.22.
On 8.0.24 both options fail.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Juergen Hoeller commented

The latest 4.2.0.BUILD-SNAPSHOT already comes with a spring-instrument-tomcat variant that should work on Tomcat 7.0.63 / 8.0.24 as well... Would be great if you could give it an early try, just grabbing it from http://repo.spring.io/snapshot. We'll release it tonight in 4.2 RC3 then.

I'm surprised that TomcatLoadTimeWeaver doesn't work for you though? In which way does it fail?

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Andrei Ivanov commented

@Aspect
public class ExporterEnhancingAspect {
	@Around("execution(* org.primefaces.component.export.Exporter.exportValue(..)) && args(context, component)")
	public Object exportValue(ProceedingJoinPoint call, FacesContext context, UIComponent component) throws Throwable {
	}
}
// classes provided by primefaces-5.2.jar
public abstract class Exporter {
	protected String exportValue(FacesContext context, UIComponent component) {
	}
}
public class ExcelExporter extends Exporter {
}

Using TomcatLoadTimeWeaver, the Exporter class is not being passed through WeavingTransformer.transformIfNecessary, only the children.

Using TomcatInstrumentableClassLoader, the parent class gets transformed:

typeToWeave = org.primefaces.component.export.ExcelExporter

Daemon Thread [http-apr-8443-exec-10] (Suspended (entry into method weaveParentsFor in BcelWeaver))	
	owns: TomcatInstrumentableClassLoader  (id=11131)	
	owns: AprEndpoint$AprSocketWrapper  (id=11132)	
	BcelWeaver.weaveParentsFor(List<String>, String, ResolvedType) line: 1296	
	BcelWeaver.weave(IClassFileProvider) line: 1119	
	ClassLoaderWeavingAdaptor(WeavingAdaptor).getWovenBytes(String, byte[]) line: 527	
	ClassLoaderWeavingAdaptor(WeavingAdaptor).weaveClass(String, byte[], boolean) line: 363	
	Aj.preProcess(String, byte[], ClassLoader, ProtectionDomain) line: 121	
	ClassPreProcessorAgentAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 54	
	AspectJWeavingEnabler$AspectJClassBypassingClassFileTransformer.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 108	
	WeavingTransformer.transformIfNecessary(String, String, byte[], ProtectionDomain) line: 95	
	WeavingTransformer.transformIfNecessary(String, byte[]) line: 78	
	TomcatInstrumentableClassLoader.findResourceInternal(String, String) line: 113	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2405	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 854	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1274	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1157	
	DataExporter.processAction(ActionEvent) line: 88	
	ActionEvent.processListener(FacesListener) line: 88	
	CommandButton(UIComponentBase).broadcast(FacesEvent) line: 813	
	CommandButton(UICommand).broadcast(FacesEvent) line: 300	
	UIViewRoot.broadcastEvents(FacesContext, PhaseId) line: 790	
	UIViewRoot.processApplication(FacesContext) line: 1282	
	InvokeApplicationPhase.execute(FacesContext) line: 81	
	InvokeApplicationPhase(Phase).doPhase(FacesContext, Lifecycle, ListIterator<PhaseListener>) line: 101	
	LifecycleImpl.execute(FacesContext) line: 198	
	FacesServlet.service(ServletRequest, ServletResponse) line: 654	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 291	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	WsFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 52	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	OpenEntityManagerInViewFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 178	
	OpenEntityManagerInViewFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	SecurityMdcFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 60	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330	
	FilterSecurityInterceptor.invoke(FilterInvocation) line: 118	
	FilterSecurityInterceptor.doFilter(ServletRequest, ServletResponse, FilterChain) line: 84	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	ExceptionTranslationFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 113	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	SessionManagementFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 103	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	AnonymousAuthenticationFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 113	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	SecurityContextHolderAwareRequestFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 154	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	RequestCacheAwareFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 45	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	UsernamePasswordAuthenticationFilter(AbstractAuthenticationProcessingFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 199	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	LogoutFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 110	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	HeaderWriterFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 57	
	HeaderWriterFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	WebAsyncManagerIntegrationFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 50	
	WebAsyncManagerIntegrationFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	SecurityContextPersistenceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 87	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	ChannelProcessingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 144	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	FilterChainProxy.doFilterInternal(ServletRequest, ServletResponse, FilterChain) line: 192	
	FilterChainProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 160	
	DelegatingFilterProxy.invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain) line: 344	
	DelegatingFilterProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 261	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	StandardWrapperValve.invoke(Request, Response) line: 219	
	StandardContextValve.invoke(Request, Response) line: 106	
	NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 614	
	StandardHostValve.invoke(Request, Response) line: 142	
	ErrorReportValve.invoke(Request, Response) line: 79	
	AccessLogValve(AbstractAccessLogValve).invoke(Request, Response) line: 617	
	StandardEngineValve.invoke(Request, Response) line: 88	
	CoyoteAdapter.service(Request, Response) line: 518	
	Http11AprProcessor(AbstractHttp11Processor<S>).process(SocketWrapper<S>) line: 1091	
	Http11AprProtocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler<S,P>).process(SocketWrapper<S>, SocketStatus) line: 668	
	AprEndpoint$SocketProcessor.doRun() line: 2463	
	AprEndpoint$SocketProcessor.run() line: 2452	
	ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1142	
	ThreadPoolExecutor$Worker.run() line: 617	
	TaskThread$WrappingRunnable.run() line: 61	
	TaskThread(Thread).run() line: 745	

typeToWeave = org.primefaces.component.export.Exporter

Daemon Thread [http-apr-8443-exec-6] (Suspended (entry into method weaveParentsFor in BcelWeaver))	
	owns: TomcatInstrumentableClassLoader  (id=11167)	
	owns: AprEndpoint$AprSocketWrapper  (id=11168)	
	BcelWeaver.weaveParentsFor(List<String>, String, ResolvedType) line: 1296	
	BcelWeaver.weave(IClassFileProvider) line: 1119	
	ClassLoaderWeavingAdaptor(WeavingAdaptor).getWovenBytes(String, byte[]) line: 527	
	ClassLoaderWeavingAdaptor(WeavingAdaptor).weaveClass(String, byte[], boolean) line: 363	
	Aj.preProcess(String, byte[], ClassLoader, ProtectionDomain) line: 121	
	ClassPreProcessorAgentAdapter.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 54	
	AspectJWeavingEnabler$AspectJClassBypassingClassFileTransformer.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 108	
	WeavingTransformer.transformIfNecessary(String, String, byte[], ProtectionDomain) line: 95	
	WeavingTransformer.transformIfNecessary(String, byte[]) line: 78	
	TomcatInstrumentableClassLoader.findResourceInternal(String, String) line: 113	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2405	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 854	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1274	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1157	
	ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String) line: not available [native method]	
	TomcatInstrumentableClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 760	
	TomcatInstrumentableClassLoader(SecureClassLoader).defineClass(String, byte[], int, int, CodeSource) line: 142	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClassInternal(String) line: 2472	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).findClass(String) line: 854	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String, boolean) line: 1274	
	TomcatInstrumentableClassLoader(WebappClassLoaderBase).loadClass(String) line: 1157	
	DataExporter.processAction(ActionEvent) line: 88	
	ActionEvent.processListener(FacesListener) line: 88	
	CommandButton(UIComponentBase).broadcast(FacesEvent) line: 813	
	CommandButton(UICommand).broadcast(FacesEvent) line: 300	
	UIViewRoot.broadcastEvents(FacesContext, PhaseId) line: 790	
	UIViewRoot.processApplication(FacesContext) line: 1282	
	InvokeApplicationPhase.execute(FacesContext) line: 81	
	InvokeApplicationPhase(Phase).doPhase(FacesContext, Lifecycle, ListIterator<PhaseListener>) line: 101	
	LifecycleImpl.execute(FacesContext) line: 198	
	FacesServlet.service(ServletRequest, ServletResponse) line: 654	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 291	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	WsFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 52	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	OpenEntityManagerInViewFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 178	
	OpenEntityManagerInViewFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	SecurityMdcFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 60	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330	
	FilterSecurityInterceptor.invoke(FilterInvocation) line: 118	
	FilterSecurityInterceptor.doFilter(ServletRequest, ServletResponse, FilterChain) line: 84	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	ExceptionTranslationFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 113	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	SessionManagementFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 103	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	AnonymousAuthenticationFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 113	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	SecurityContextHolderAwareRequestFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 154	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	RequestCacheAwareFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 45	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	UsernamePasswordAuthenticationFilter(AbstractAuthenticationProcessingFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 199	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	LogoutFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 110	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	HeaderWriterFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 57	
	HeaderWriterFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	WebAsyncManagerIntegrationFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 50	
	WebAsyncManagerIntegrationFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	SecurityContextPersistenceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 87	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	ChannelProcessingFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 144	
	FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 342	
	FilterChainProxy.doFilterInternal(ServletRequest, ServletResponse, FilterChain) line: 192	
	FilterChainProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 160	
	DelegatingFilterProxy.invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain) line: 344	
	DelegatingFilterProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 261	
	ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 239	
	ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 206	
	StandardWrapperValve.invoke(Request, Response) line: 219	
	StandardContextValve.invoke(Request, Response) line: 106	
	NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 614	
	StandardHostValve.invoke(Request, Response) line: 142	
	ErrorReportValve.invoke(Request, Response) line: 79	
	AccessLogValve(AbstractAccessLogValve).invoke(Request, Response) line: 617	
	StandardEngineValve.invoke(Request, Response) line: 88	
	CoyoteAdapter.service(Request, Response) line: 518	
	Http11AprProcessor(AbstractHttp11Processor<S>).process(SocketWrapper<S>) line: 1091	
	Http11AprProtocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler<S,P>).process(SocketWrapper<S>, SocketStatus) line: 668	
	AprEndpoint$SocketProcessor.doRun() line: 2463	
	AprEndpoint$SocketProcessor.run() line: 2452	
	ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1142	
	ThreadPoolExecutor$Worker.run() line: 617	
	TaskThread$WrappingRunnable.run() line: 61	
	TaskThread(Thread).run() line: 745	
@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Juergen Hoeller commented

Hmm, it looks like Tomcat's own instrumentable class loader selectively applies the weaving to application classes only there. I'm afraid we cannot do much about this from Spring's side; you'd really have to report that part to Tomcat itself. Our TomcatLoadTimeWeaver does nothing more than pass transformer handles to Tomcat's class loader, after all.

As for our own TomcatInstrumentableClassLoader, any chance that the latest 4.2 snapshot works for you there?

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Andrei Ivanov commented

Yes, it works with the TomcatInstrumentableClassLoader from 4.2.0 SNAPSHOT.
Would have been nice to have it work with TomcatLoadTimeWeaver as the virtual host setup we want doesn't seem to load the context.xml from the web app :(

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Juergen Hoeller commented

Great to hear, thanks for the timely feedback!

As for TomcatLoadTimeWeaver, that's definitely preferrred on Tomcat 8. No idea why you're seeing that limitation; please do raise it with the Tomcat team.

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2015

Andrei Ivanov commented

I've created https://bz.apache.org/bugzilla/show_bug.cgi?id=58143
As far as I see, when the application gets deployed, Tomcat tries to discover various classes to process servlet annotations.
The resources for these classes get cached in WebappClassLoaderBase.resourceEntries before the Spring Framework is started, so any calls to WebappClassLoaderBase.findResourceInternal will return the cached resources and the transformers will not be run.
A workaround could be for TomcatLoadTimeWeaver.addTransformer to clear the resourceEntries map.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 20, 2015

Andrei Ivanov commented

Jurgen,
Can I direct your attention to the Tomcat ticket I've created?
They've added a comment and I think it might be best if you could chime in.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 24, 2015

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Sep 4, 2015

Bryn Cooke commented

I have reopened the Tomcat ticket regarding registration of transformers suggesting an alternative mechanism for discovering transformers via something like ServiceLoader.

https://bz.apache.org/bugzilla/show_bug.cgi?id=58143

It would be great if the spring could share their views on if it is a good idea or otherwise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.