From 37f74e76f674e175813f36d3562a9333d7c6654e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 15 Jul 2015 00:02:55 +0200 Subject: [PATCH] TomcatInstrumentableClassLoader supports Tomcat 7.0.63+ as well Issue: SPR-13210 --- build.gradle | 4 ++ .../catalina/loader/WebappClassLoader.java | 44 +++++++++++++++++++ .../TomcatInstrumentableClassLoader.java | 18 +++++--- src/asciidoc/core-aop.adoc | 5 +-- 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 spring-instrument-tomcat/src/main/java/org/apache/catalina/loader/WebappClassLoader.java diff --git a/build.gradle b/build.gradle index 5e224a4c24..9ee303d2d2 100644 --- a/build.gradle +++ b/build.gradle @@ -448,6 +448,10 @@ project("spring-instrument-tomcat") { dependencies { provided("org.apache.tomcat:catalina:6.0.16") } + + jar { + exclude("org/apache/**") // exclude the mock used to bridge between pre-7.0.63 and 7.0.63+ + } } project("spring-context") { diff --git a/spring-instrument-tomcat/src/main/java/org/apache/catalina/loader/WebappClassLoader.java b/spring-instrument-tomcat/src/main/java/org/apache/catalina/loader/WebappClassLoader.java new file mode 100644 index 0000000000..ba54df867c --- /dev/null +++ b/spring-instrument-tomcat/src/main/java/org/apache/catalina/loader/WebappClassLoader.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.catalina.loader; + +/** + * A mock of Tomcat's {@code WebappClassLoader} just for Spring's compilation purposes. + * Exposes both pre-7.0.63 as well as 7.0.63+ variants of {@code findResourceInternal}. + * + * @author Juergen Hoeller + * @since 4.2 + */ +public class WebappClassLoader extends ClassLoader { + + public WebappClassLoader() { + } + + public WebappClassLoader(ClassLoader parent) { + super(parent); + } + + + protected ResourceEntry findResourceInternal(String name, String path) { + throw new UnsupportedOperationException(); + } + + protected ResourceEntry findResourceInternal(String name, String path, boolean manifestRequired) { + throw new UnsupportedOperationException(); + } + +} diff --git a/spring-instrument-tomcat/src/main/java/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.java b/spring-instrument-tomcat/src/main/java/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.java index b98706a304..554522171f 100644 --- a/spring-instrument-tomcat/src/main/java/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.java +++ b/spring-instrument-tomcat/src/main/java/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.java @@ -44,7 +44,7 @@ import org.springframework.instrument.classloading.WeavingTransformer; * in the LoadTimeWeaver interface, as expected by ReflectiveLoadTimeWeaver. * *

NOTE: Requires Apache Tomcat version 6.0 or higher, as of Spring 4.0. - * This class does not work on Tomcat 7.0.63 and higher; please rely on Tomcat's own + * This class is not intended to work on Tomcat 8.0+; please rely on Tomcat's own * {@code InstrumentableClassLoader} facility instead, as autodetected by Spring's * {@link org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver}. * @@ -109,7 +109,7 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader { } - @Override + @Override // overriding the pre-7.0.63 variant of findResourceInternal protected ResourceEntry findResourceInternal(String name, String path) { ResourceEntry entry = super.findResourceInternal(name, path); if (entry != null && entry.binaryContent != null && path.endsWith(CLASS_SUFFIX)) { @@ -119,11 +119,19 @@ public class TomcatInstrumentableClassLoader extends WebappClassLoader { return entry; } + @Override // overriding the 7.0.63+ variant of findResourceInternal + protected ResourceEntry findResourceInternal(String name, String path, boolean manifestRequired) { + ResourceEntry entry = super.findResourceInternal(name, path, manifestRequired); + if (entry != null && entry.binaryContent != null && path.endsWith(CLASS_SUFFIX)) { + String className = (name.endsWith(CLASS_SUFFIX) ? name.substring(0, name.length() - CLASS_SUFFIX.length()) : name); + entry.binaryContent = this.weavingTransformer.transformIfNecessary(className, entry.binaryContent); + } + return entry; + } + @Override public String toString() { - StringBuilder sb = new StringBuilder(getClass().getName()); - sb.append("\r\n").append(super.toString()); - return sb.toString(); + return getClass().getName() + "\r\n" + super.toString(); } diff --git a/src/asciidoc/core-aop.adoc b/src/asciidoc/core-aop.adoc index 539d82045a..5d9fccdd07 100644 --- a/src/asciidoc/core-aop.adoc +++ b/src/asciidoc/core-aop.adoc @@ -3451,10 +3451,9 @@ Tomcat 6.0 and above. [TIP] ==== -Do not define `TomcatInstrumentableClassLoader` anymore as of Tomcat 7.0.44+ / 8.0. +Do not define `TomcatInstrumentableClassLoader` anymore on Tomcat 8.0 and higher. Instead, let Spring automatically use Tomcat's new native `InstrumentableClassLoader` -facility through the `TomcatLoadTimeWeaver` strategy, in particular on Tomcat 7.0.63+ -where `TomcatInstrumentableClassLoader` does not work at all anymore. +facility through the `TomcatLoadTimeWeaver` strategy. ==== If you still need to use `TomcatInstrumentableClassLoader`, it can be registered