01: /*
02: * Copyright 2002-2006 the original author or authors.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.springframework.instrument.classloading.glassfish;
18:
19: import java.lang.instrument.ClassFileTransformer;
20:
21: import com.sun.enterprise.loader.InstrumentableClassLoader;
22:
23: import org.springframework.instrument.classloading.LoadTimeWeaver;
24: import org.springframework.util.Assert;
25: import org.springframework.util.ClassUtils;
26:
27: /**
28: * {@link LoadTimeWeaver} implementation for GlassFish's instrumentable ClassLoader.
29: *
30: * @author Costin Leau
31: * @author Juergen Hoeller
32: * @since 2.0.1
33: * @see com.sun.enterprise.loader.InstrumentableClassLoader
34: */
35: public class GlassFishLoadTimeWeaver implements LoadTimeWeaver {
36:
37: private final InstrumentableClassLoader classLoader;
38:
39: public GlassFishLoadTimeWeaver() {
40: this (ClassUtils.getDefaultClassLoader());
41: }
42:
43: public GlassFishLoadTimeWeaver(ClassLoader classLoader) {
44: Assert.notNull(classLoader, "ClassLoader must not be null");
45: InstrumentableClassLoader icl = determineClassLoader(classLoader);
46: if (icl == null) {
47: throw new IllegalArgumentException(
48: classLoader
49: + " and its parents are not suitable ClassLoaders: "
50: + "An ["
51: + InstrumentableClassLoader.class.getName()
52: + "] implementation is required.");
53: }
54: this .classLoader = icl;
55: }
56:
57: /**
58: * Determine the GlassFish InstrumentableClassLoader for the given ClassLoader.
59: * @param classLoader the ClassLoader to check
60: * @return the InstrumentableClassLoader, or <code>null</code> if none found
61: */
62: protected InstrumentableClassLoader determineClassLoader(
63: ClassLoader classLoader) {
64: // Detect transformation-aware ClassLoader by traversing the hierarchy
65: // (as in GlassFish, Spring can be loaded by the WebappClassLoader).
66: for (ClassLoader cl = classLoader; cl != null; cl = cl
67: .getParent()) {
68: if (cl instanceof InstrumentableClassLoader) {
69: return (InstrumentableClassLoader) cl;
70: }
71: }
72: return null;
73: }
74:
75: public void addTransformer(ClassFileTransformer transformer) {
76: this .classLoader.addTransformer(new ClassTransformerAdapter(
77: transformer));
78: }
79:
80: public ClassLoader getInstrumentableClassLoader() {
81: return (ClassLoader) this .classLoader;
82: }
83:
84: public ClassLoader getThrowawayClassLoader() {
85: return this.classLoader.copy();
86: }
87:
88: }
|