HHH-16911 Integration test for empty SessionFactory to not leak the CL
This commit is contained in:
parent
187e637b68
commit
6ff15ff3fb
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.bootstrap.registry.classloading;
|
||||||
|
|
||||||
|
import java.sql.Driver;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that Hibernate ORM won't leak the classloader.
|
||||||
|
* We only test in H2 to save some time; we also need to avoid
|
||||||
|
* leaks by JDBC drivers, and since these aren't our responsibility
|
||||||
|
* it's best to focus on a single DB.
|
||||||
|
*/
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class HibernateClassLoaderLeaksTest {
|
||||||
|
|
||||||
|
private static Set<Driver> knownDrivers;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void prepareForClassLoaderLeakTest() {
|
||||||
|
final String property = System.getProperty( "log4j2.disableJmx" );
|
||||||
|
Assert.assertEquals( "To be able to test against leaks, the system property 'log4j2.disableJmx' must be set to true",
|
||||||
|
"true", property );
|
||||||
|
|
||||||
|
//Attempt to workaround the mess of DriverManager leaks by clearing it before the test;
|
||||||
|
//it will most certainly re-register all drivers again within the test running context,
|
||||||
|
//but that will imply that the isolated classloader will also have permission to de-register them.
|
||||||
|
knownDrivers = DriverManager.drivers().collect( Collectors.toUnmodifiableSet() );
|
||||||
|
knownDrivers.forEach( HibernateClassLoaderLeaksTest::cleanup );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void restoreRegisteredDrivers() throws SQLException {
|
||||||
|
if ( knownDrivers != null ) {
|
||||||
|
for ( Driver driver : knownDrivers ) {
|
||||||
|
DriverManager.registerDriver( driver );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hibernateDoesNotLeakClassloader() {
|
||||||
|
ClassLoaderLeakDetector.assertNotLeakingAction( HibernateLoadingTestAction.class.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void cleanup(Driver driver) {
|
||||||
|
System.out.println( "Attempting de-registration of driver: " + driver );
|
||||||
|
try {
|
||||||
|
DriverManager.deregisterDriver( driver );
|
||||||
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.bootstrap.registry.classloading;
|
||||||
|
|
||||||
|
import java.sql.Driver;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||||
|
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Runnable which initializes an EntityManagerFactory;
|
||||||
|
* this is meant to test against classloader leaks, so needs
|
||||||
|
* to be packaged as a Runnable rather than using our usual
|
||||||
|
* testing facilities.
|
||||||
|
*/
|
||||||
|
public class HibernateLoadingTestAction extends NotLeakingTestAction implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
super.run(); //for basic sanity self-check
|
||||||
|
final Map config = new HashMap();
|
||||||
|
EntityManagerFactory emf = Bootstrap.getEntityManagerFactoryBuilder(
|
||||||
|
new BaseEntityManagerFunctionalTestCase.TestingPersistenceUnitDescriptorImpl( getClass().getSimpleName() ),
|
||||||
|
config
|
||||||
|
).build();
|
||||||
|
try {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
cleanupJDBCDrivers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanupJDBCDrivers() {
|
||||||
|
DriverManager.drivers().forEach( this::deregister );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deregister(final Driver driver) {
|
||||||
|
System.out.println( "Unregistering driver: " +driver);
|
||||||
|
try {
|
||||||
|
DriverManager.deregisterDriver( driver );
|
||||||
|
}
|
||||||
|
catch ( SQLException e ) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue