Skip to content

Commit 664df89

Browse files
committed
Initial work on reproducing trouble we've seen with RefletionOptimizer caused by a class on the classpath twice (EAR and WAR e.g.)
1 parent 55c5838 commit 664df89

File tree

5 files changed

+241
-0
lines changed

5 files changed

+241
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.bytecode.duplication;
6+
7+
import jakarta.persistence.EntityManagerFactory;
8+
import org.hibernate.engine.spi.SessionFactoryImplementor;
9+
10+
/**
11+
* To be loaded reflectively...
12+
*
13+
* @author Steve Ebersole
14+
*/
15+
public class Client {
16+
public static void execute(EntityManagerFactory emf) {
17+
emf.runInTransaction( (entityManager) -> {
18+
entityManager.persist( new SimpleEntity( 1, "tester" ) );
19+
entityManager.createQuery( "from SimpleEntity" ).getResultList();
20+
} );
21+
}
22+
23+
public static void cleanup(EntityManagerFactory emf) {
24+
emf.unwrap( SessionFactoryImplementor.class ).getSchemaManager().truncateMappedObjects();
25+
}
26+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.bytecode.duplication;
6+
7+
import jakarta.persistence.EntityManagerFactory;
8+
import jakarta.persistence.Persistence;
9+
import org.jboss.shrinkwrap.api.ArchivePath;
10+
import org.jboss.shrinkwrap.api.ArchivePaths;
11+
import org.jboss.shrinkwrap.api.ShrinkWrap;
12+
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
13+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
14+
import org.junit.jupiter.api.AfterEach;
15+
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Test;
17+
import org.junit.jupiter.api.io.TempDir;
18+
19+
import java.io.File;
20+
import java.lang.reflect.InvocationTargetException;
21+
import java.lang.reflect.Method;
22+
import java.net.MalformedURLException;
23+
import java.net.URL;
24+
import java.net.URLClassLoader;
25+
26+
27+
/**
28+
* @author Steve Ebersole
29+
*/
30+
public class DuplicateClassTests {
31+
private ClassLoader originalTccl;
32+
33+
@BeforeEach
34+
void storeOriginalTccl() {
35+
originalTccl = Thread.currentThread().getContextClassLoader();
36+
}
37+
38+
@AfterEach
39+
void restoreOriginalTccl() {
40+
Thread.currentThread().setContextClassLoader( originalTccl );
41+
}
42+
43+
@Test
44+
void testSimple(@TempDir File tempDir)
45+
throws MalformedURLException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
46+
ArchivePath path = ArchivePaths.create( "META-INF/persistence.xml" );
47+
48+
JavaArchive jar1 = ShrinkWrap.create( JavaArchive.class, "jar1.jar" );
49+
jar1.addClasses( SimpleEntity.class );
50+
jar1.addAsResource( "units/bytecode/duplication/pu1.xml", path );
51+
File jar1File = new File( tempDir, "jar1.jar" );
52+
jar1.as( ZipExporter.class ).exportTo( jar1File, true );
53+
54+
JavaArchive jar2 = ShrinkWrap.create( JavaArchive.class, "jar2.jar" );
55+
jar2.addClasses( SimpleEntity.class );
56+
jar2.addAsResource( "units/bytecode/duplication/pu2.xml", path );
57+
File jar2File = new File( tempDir, "jar2.jar" );
58+
jar2.as( ZipExporter.class ).exportTo( jar2File, true );
59+
60+
URL[] jarUrls = new URL[] {
61+
jar1File.toURI().toURL(),
62+
jar2File.toURI().toURL()
63+
};
64+
final URLClassLoader classLoader = new URLClassLoader( jarUrls, getClass().getClassLoader() );
65+
Thread.currentThread().setContextClassLoader( classLoader );
66+
67+
try (EntityManagerFactory emf1 = Persistence.createEntityManagerFactory( "unit-1" )) {
68+
executeUseCases( classLoader, emf1 );
69+
}
70+
try (EntityManagerFactory emf2 = Persistence.createEntityManagerFactory( "unit-2" )) {
71+
executeUseCases( classLoader, emf2 );
72+
}
73+
74+
{
75+
JavaArchive jar3 = ShrinkWrap.create( JavaArchive.class, "jar3.jar" );
76+
jar3.addClasses( SimpleEntity.class );
77+
jar3.addAsResource( "units/bytecode/duplication/pu1.xml", path );
78+
File jar3File = new File( tempDir, "jar3.jar" );
79+
jar3.as( ZipExporter.class ).exportTo( jar3File, true );
80+
81+
URL[] secondaryUrls = new URL[] { jar3File.toURI().toURL() };
82+
final URLClassLoader secondaryClassLoader = new URLClassLoader( secondaryUrls, getClass().getClassLoader() );
83+
Thread.currentThread().setContextClassLoader( secondaryClassLoader );
84+
85+
try (EntityManagerFactory emf3 = Persistence.createEntityManagerFactory( "unit-1" )) {
86+
executeUseCases( classLoader, emf3 );
87+
}
88+
}
89+
}
90+
91+
private void executeUseCases(URLClassLoader classLoader, EntityManagerFactory entityManagerFactory)
92+
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
93+
final Class<?> clientClass = classLoader.loadClass( "org.hibernate.orm.test.bytecode.duplication.Client" );
94+
final Method executeMethod = clientClass.getDeclaredMethod( "execute", EntityManagerFactory.class );
95+
final Method cleanupMethod = clientClass.getDeclaredMethod( "cleanup", EntityManagerFactory.class );
96+
97+
try {
98+
executeMethod.invoke( null, entityManagerFactory );
99+
}
100+
finally {
101+
cleanupMethod.invoke( null, entityManagerFactory );
102+
}
103+
104+
}
105+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.bytecode.duplication;
6+
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.Id;
9+
10+
/**
11+
* @author Steve Ebersole
12+
*/
13+
@Entity
14+
public class SimpleEntity {
15+
@Id
16+
private Integer id;
17+
private String name;
18+
19+
public SimpleEntity() {
20+
}
21+
22+
public SimpleEntity(Integer id, String name) {
23+
this.id = id;
24+
this.name = name;
25+
}
26+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!--
2+
~ SPDX-License-Identifier: Apache-2.0
3+
~ Copyright Red Hat Inc. and Hibernate Authors
4+
-->
5+
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
6+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7+
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
8+
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
9+
version="2.1">
10+
11+
<persistence-unit name="unit-1">
12+
<description>
13+
Persistence unit for Hibernate User Guide
14+
</description>
15+
16+
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
17+
18+
<class>org.hibernate.orm.test.bytecode.duplication.SimpleEntity</class>
19+
20+
<properties>
21+
<property name="jakarta.persistence.jdbc.driver"
22+
value="org.h2.Driver" />
23+
24+
<property name="jakarta.persistence.jdbc.url"
25+
value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1" />
26+
27+
<property name="jakarta.persistence.jdbc.user"
28+
value="sa" />
29+
30+
<property name="jakarta.persistence.jdbc.password"
31+
value="" />
32+
33+
<property name="hibernate.show_sql"
34+
value="true" />
35+
36+
<property name="hibernate.hbm2ddl.auto"
37+
value="update" />
38+
</properties>
39+
40+
</persistence-unit>
41+
42+
</persistence>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!--
2+
~ SPDX-License-Identifier: Apache-2.0
3+
~ Copyright Red Hat Inc. and Hibernate Authors
4+
-->
5+
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
6+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7+
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
8+
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
9+
version="2.1">
10+
11+
<persistence-unit name="unit-2">
12+
<description>
13+
Persistence unit for Hibernate User Guide
14+
</description>
15+
16+
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
17+
18+
<class>org.hibernate.orm.test.bytecode.duplication.SimpleEntity</class>
19+
20+
<properties>
21+
<property name="jakarta.persistence.jdbc.driver"
22+
value="org.h2.Driver" />
23+
24+
<property name="jakarta.persistence.jdbc.url"
25+
value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1" />
26+
27+
<property name="jakarta.persistence.jdbc.user"
28+
value="sa" />
29+
30+
<property name="jakarta.persistence.jdbc.password"
31+
value="" />
32+
33+
<property name="hibernate.show_sql"
34+
value="true" />
35+
36+
<property name="hibernate.hbm2ddl.auto"
37+
value="update" />
38+
</properties>
39+
40+
</persistence-unit>
41+
42+
</persistence>

0 commit comments

Comments
 (0)