diff --git a/hibernate-core/src/main/java/org/hibernate/service/classloading/internal/ClassLoaderServiceImpl.java b/hibernate-core/src/main/java/org/hibernate/service/classloading/internal/ClassLoaderServiceImpl.java index 51154e88fe..0c0a360f32 100644 --- a/hibernate-core/src/main/java/org/hibernate/service/classloading/internal/ClassLoaderServiceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/service/classloading/internal/ClassLoaderServiceImpl.java @@ -86,7 +86,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { classLoadingClassLoaders.add( hibernateClassLoader ); classLoadingClassLoaders.add( environmentClassLoader ); - this.classClassLoader = new ClassLoader() { + this.classClassLoader = new ClassLoader(null) { @Override protected Class findClass(String name) throws ClassNotFoundException { for ( ClassLoader loader : classLoadingClassLoaders ) { @@ -197,7 +197,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService { @Override public LinkedHashSet loadJavaServices(Class serviceContract) { - final ClassLoader serviceLoaderClassLoader = new ClassLoader() { + final ClassLoader serviceLoaderClassLoader = new ClassLoader(null) { final ClassLoader[] classLoaderArray = new ClassLoader[] { // first look on the hibernate class loader getClass().getClassLoader(), diff --git a/hibernate-core/src/test/java/org/hibernate/test/service/ClassLoaderServiceImplTest.java b/hibernate-core/src/test/java/org/hibernate/test/service/ClassLoaderServiceImplTest.java new file mode 100644 index 0000000000..1ada3caec3 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/service/ClassLoaderServiceImplTest.java @@ -0,0 +1,70 @@ +package org.hibernate.test.service; + +import org.hibernate.service.classloading.internal.ClassLoaderServiceImpl; +import org.junit.Assert; +import org.junit.Test; + +import javax.persistence.Entity; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * @author Artem V. Navrotskiy + * @author Emmanuel Bernard + */ +public class ClassLoaderServiceImplTest { + /** + * Test for bug: HHH-7084 + */ + @Test + public void testSystemClassLoaderNotOverriding() throws IOException, ClassNotFoundException { + Class testClass = Entity.class; + + // Check that class is accessible by SystemClassLoader. + ClassLoader.getSystemClassLoader().loadClass(testClass.getName()); + + // Create ClassLoader with overridden class. + TestClassLoader anotherLoader = new TestClassLoader(); + anotherLoader.overrideClass(testClass); + Class anotherClass = anotherLoader.loadClass(testClass.getName()); + Assert.assertNotSame( testClass, anotherClass ); + + // Check ClassLoaderServiceImpl().classForName() returns correct class (not from current ClassLoader). + ClassLoaderServiceImpl loaderService = new ClassLoaderServiceImpl(anotherLoader); + Class objectClass = loaderService.classForName(testClass.getName()); + Assert.assertSame("Should not return class loaded from the parent classloader of ClassLoaderServiceImpl", + objectClass, anotherClass); + } + + private static class TestClassLoader extends ClassLoader { + /** + * Reloading class from binary file. + * + * @param originalClass Original class. + * @throws IOException . + */ + public void overrideClass(final Class originalClass) throws IOException { + String originalPath = "/" + originalClass.getName().replaceAll("\\.", "/") + ".class"; + InputStream inputStream = originalClass.getResourceAsStream(originalPath); + Assert.assertNotNull(inputStream); + try { + byte[] data = toByteArray( inputStream ); + defineClass(originalClass.getName(), data, 0, data.length); + } finally { + inputStream.close(); + } + } + + private byte[] toByteArray(InputStream inputStream) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + int read; + byte[] slice = new byte[2000]; + while ( (read = inputStream.read(slice, 0, slice.length) ) != -1) { + out.write( slice, 0, read ); + } + out.flush(); + return out.toByteArray(); + } + } +}