From 05c995cfb33bc42ab536be76d2ecff383ec195fe Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Oct 2014 14:33:13 +0200 Subject: [PATCH] DecoratingClassLoader and its subclasses register themselves as parallel capable on Java 7+ Issue: SPR-12285 --- .../support/ContextTypeMatchClassLoader.java | 17 ++++++++++---- .../SimpleInstrumentableClassLoader.java | 22 ++++++++++++------- .../SimpleThrowawayClassLoader.java | 13 +++++++++-- .../core/DecoratingClassLoader.java | 19 +++++++++++++++- .../core/OverridingClassLoader.java | 15 +++++++++---- 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/support/ContextTypeMatchClassLoader.java b/spring-context/src/main/java/org/springframework/context/support/ContextTypeMatchClassLoader.java index b433137f39..a54ccab47d 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ContextTypeMatchClassLoader.java +++ b/spring-context/src/main/java/org/springframework/context/support/ContextTypeMatchClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -17,12 +17,13 @@ package org.springframework.context.support; import java.lang.reflect.Method; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.DecoratingClassLoader; import org.springframework.core.OverridingClassLoader; import org.springframework.core.SmartClassLoader; +import org.springframework.lang.UsesJava7; import org.springframework.util.ReflectionUtils; /** @@ -36,13 +37,21 @@ import org.springframework.util.ReflectionUtils; * @see AbstractApplicationContext * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#setTempClassLoader */ +@UsesJava7 class ContextTypeMatchClassLoader extends DecoratingClassLoader implements SmartClassLoader { + static { + if (parallelCapableClassLoaderAvailable) { + ClassLoader.registerAsParallelCapable(); + } + } + + private static Method findLoadedClassMethod; static { try { - findLoadedClassMethod = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[] {String.class}); + findLoadedClassMethod = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); } catch (NoSuchMethodException ex) { throw new IllegalStateException("Invalid [java.lang.ClassLoader] class: no 'findLoadedClass' method defined!"); @@ -51,7 +60,7 @@ class ContextTypeMatchClassLoader extends DecoratingClassLoader implements Smart /** Cache for byte array per class name */ - private final Map bytesCache = new HashMap(); + private final Map bytesCache = new ConcurrentHashMap(256); public ContextTypeMatchClassLoader(ClassLoader parent) { diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleInstrumentableClassLoader.java b/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleInstrumentableClassLoader.java index 4405dc3fdc..b2c00f9c3d 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleInstrumentableClassLoader.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleInstrumentableClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -19,6 +19,7 @@ package org.springframework.instrument.classloading; import java.lang.instrument.ClassFileTransformer; import org.springframework.core.OverridingClassLoader; +import org.springframework.lang.UsesJava7; /** * Simplistic implementation of an instrumentable {@code ClassLoader}. @@ -29,16 +30,22 @@ import org.springframework.core.OverridingClassLoader; * @author Costin Leau * @since 2.0 */ +@UsesJava7 public class SimpleInstrumentableClassLoader extends OverridingClassLoader { + static { + if (parallelCapableClassLoaderAvailable) { + ClassLoader.registerAsParallelCapable(); + } + } + + private final WeavingTransformer weavingTransformer; /** - * Create a new {@code SimpleLoadTimeWeaver} for the given - * {@code ClassLoader}. - * @param parent the {@code ClassLoader} to build a simple - * instrumentable {@code ClassLoader} for + * Create a new SimpleInstrumentableClassLoader for the given ClassLoader. + * @param parent the ClassLoader to build an instrumentable ClassLoader for */ public SimpleInstrumentableClassLoader(ClassLoader parent) { super(parent); @@ -47,9 +54,8 @@ public class SimpleInstrumentableClassLoader extends OverridingClassLoader { /** - * Add a {@code ClassFileTransformer} to be applied by this - * {@code ClassLoader}. - * @param transformer the {@code ClassFileTransformer} to register + * Add a {@link ClassFileTransformer} to be applied by this ClassLoader. + * @param transformer the {@link ClassFileTransformer} to register */ public void addTransformer(ClassFileTransformer transformer) { this.weavingTransformer.addTransformer(transformer); diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleThrowawayClassLoader.java b/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleThrowawayClassLoader.java index 227a7d2556..011ea17d7c 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleThrowawayClassLoader.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/SimpleThrowawayClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 the original author or authors. + * Copyright 2002-2014 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. @@ -17,6 +17,7 @@ package org.springframework.instrument.classloading; import org.springframework.core.OverridingClassLoader; +import org.springframework.lang.UsesJava7; /** * ClassLoader that can be used to load classes without bringing them @@ -26,10 +27,18 @@ import org.springframework.core.OverridingClassLoader; * @author Rod Johnson * @since 2.0 */ +@UsesJava7 public class SimpleThrowawayClassLoader extends OverridingClassLoader { + static { + if (parallelCapableClassLoaderAvailable) { + ClassLoader.registerAsParallelCapable(); + } + } + + /** - * Create a new SimpleThrowawayClassLoader for the given class loader. + * Create a new SimpleThrowawayClassLoader for the given ClassLoader. * @param parent the ClassLoader to build a throwaway ClassLoader for */ public SimpleThrowawayClassLoader(ClassLoader parent) { diff --git a/spring-core/src/main/java/org/springframework/core/DecoratingClassLoader.java b/spring-core/src/main/java/org/springframework/core/DecoratingClassLoader.java index 0e67714101..350df5cfa1 100644 --- a/spring-core/src/main/java/org/springframework/core/DecoratingClassLoader.java +++ b/spring-core/src/main/java/org/springframework/core/DecoratingClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2014 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. @@ -19,7 +19,9 @@ package org.springframework.core; import java.util.HashSet; import java.util.Set; +import org.springframework.lang.UsesJava7; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * Base class for decorating ClassLoaders such as {@link OverridingClassLoader} @@ -30,8 +32,23 @@ import org.springframework.util.Assert; * @author Rod Johnson * @since 2.5.2 */ +@UsesJava7 public abstract class DecoratingClassLoader extends ClassLoader { + /** + * Java 7+ {@code ClassLoader.registerAsParallelCapable()} available? + * @since 4.1.2 + */ + protected static final boolean parallelCapableClassLoaderAvailable = + ClassUtils.hasMethod(ClassLoader.class, "registerAsParallelCapable"); + + static { + if (parallelCapableClassLoaderAvailable) { + ClassLoader.registerAsParallelCapable(); + } + } + + private final Set excludedPackages = new HashSet(); private final Set excludedClasses = new HashSet(); diff --git a/spring-core/src/main/java/org/springframework/core/OverridingClassLoader.java b/spring-core/src/main/java/org/springframework/core/OverridingClassLoader.java index 9fbf0eed1a..c60a4c8b4b 100644 --- a/spring-core/src/main/java/org/springframework/core/OverridingClassLoader.java +++ b/spring-core/src/main/java/org/springframework/core/OverridingClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -19,6 +19,7 @@ package org.springframework.core; import java.io.IOException; import java.io.InputStream; +import org.springframework.lang.UsesJava7; import org.springframework.util.FileCopyUtils; /** @@ -33,17 +34,23 @@ import org.springframework.util.FileCopyUtils; * @author Juergen Hoeller * @since 2.0.1 */ +@UsesJava7 public class OverridingClassLoader extends DecoratingClassLoader { /** Packages that are excluded by default */ - public static final String[] DEFAULT_EXCLUDED_PACKAGES = - new String[] {"java.", "javax.", "sun.", "oracle."}; + public static final String[] DEFAULT_EXCLUDED_PACKAGES = new String[] {"java.", "javax.", "sun.", "oracle."}; private static final String CLASS_FILE_SUFFIX = ".class"; + static { + if (parallelCapableClassLoaderAvailable) { + ClassLoader.registerAsParallelCapable(); + } + } + /** - * Create a new OverridingClassLoader for the given class loader. + * Create a new OverridingClassLoader for the given ClassLoader. * @param parent the ClassLoader to build an overriding ClassLoader for */ public OverridingClassLoader(ClassLoader parent) { -- GitLab