Skip to content

Commit 836a321

Browse files
committed
JPA ClassFileTransformerAdapter defensively backs out when called from within a transform call
Issue: SPR-13886
1 parent 74608e6 commit 836a321

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/ClassFileTransformerAdapter.java

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,19 +27,23 @@
2727

2828
/**
2929
* Simple adapter that implements the {@code java.lang.instrument.ClassFileTransformer}
30-
* interface based on a JPA ClassTransformer which a JPA PersistenceProvider asks the
31-
* PersistenceUnitInfo to install in the current runtime.
30+
* interface based on a JPA {@code ClassTransformer} which a JPA PersistenceProvider
31+
* asks the {@code PersistenceUnitInfo} to install in the current runtime.
3232
*
3333
* @author Rod Johnson
34+
* @author Juergen Hoeller
3435
* @since 2.0
3536
* @see javax.persistence.spi.PersistenceUnitInfo#addTransformer(javax.persistence.spi.ClassTransformer)
3637
*/
3738
class ClassFileTransformerAdapter implements ClassFileTransformer {
3839

3940
private static final Log logger = LogFactory.getLog(ClassFileTransformerAdapter.class);
4041

42+
4143
private final ClassTransformer classTransformer;
4244

45+
private boolean currentlyTransforming = false;
46+
4347

4448
public ClassFileTransformerAdapter(ClassTransformer classTransformer) {
4549
Assert.notNull(classTransformer, "ClassTransformer must not be null");
@@ -52,28 +56,42 @@ public byte[] transform(
5256
ClassLoader loader, String className, Class<?> classBeingRedefined,
5357
ProtectionDomain protectionDomain, byte[] classfileBuffer) {
5458

55-
try {
56-
byte[] transformed = this.classTransformer.transform(
57-
loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
58-
if (transformed != null && logger.isDebugEnabled()) {
59-
logger.debug("Transformer of class [" + this.classTransformer.getClass().getName() +
60-
"] transformed class [" + className + "]; bytes in=" +
61-
classfileBuffer.length + "; bytes out=" + transformed.length);
59+
synchronized (this) {
60+
if (this.currentlyTransforming) {
61+
// Defensively back out when called from within the transform delegate below:
62+
// in particular, for the over-eager transformer implementation in Hibernate 5.
63+
return null;
6264
}
63-
return transformed;
64-
}
65-
catch (ClassCircularityError ex) {
66-
logger.error("Error weaving class [" + className + "] with " +
67-
"transformer of class [" + this.classTransformer.getClass().getName() + "]", ex);
68-
throw new IllegalStateException("Could not weave class [" + className + "]", ex);
69-
}
70-
catch (Throwable ex) {
71-
if (logger.isWarnEnabled()) {
72-
logger.warn("Error weaving class [" + className + "] with " +
73-
"transformer of class [" + this.classTransformer.getClass().getName() + "]", ex);
65+
66+
this.currentlyTransforming = true;
67+
try {
68+
byte[] transformed = this.classTransformer.transform(
69+
loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
70+
if (transformed != null && logger.isDebugEnabled()) {
71+
logger.debug("Transformer of class [" + this.classTransformer.getClass().getName() +
72+
"] transformed class [" + className + "]; bytes in=" +
73+
classfileBuffer.length + "; bytes out=" + transformed.length);
74+
}
75+
return transformed;
76+
}
77+
catch (ClassCircularityError ex) {
78+
if (logger.isErrorEnabled()) {
79+
logger.error("Circularity error while weaving class [" + className + "] with " +
80+
"transformer of class [" + this.classTransformer.getClass().getName() + "]", ex);
81+
}
82+
throw new IllegalStateException("Failed to weave class [" + className + "]", ex);
83+
}
84+
catch (Throwable ex) {
85+
if (logger.isWarnEnabled()) {
86+
logger.warn("Error weaving class [" + className + "] with transformer of class [" +
87+
this.classTransformer.getClass().getName() + "]", ex);
88+
}
89+
// The exception will be ignored by the class loader, anyway...
90+
throw new IllegalStateException("Could not weave class [" + className + "]", ex);
91+
}
92+
finally {
93+
this.currentlyTransforming = false;
7494
}
75-
// The exception will be ignored by the class loader, anyway...
76-
throw new IllegalStateException("Could not weave class [" + className + "]", ex);
7795
}
7896
}
7997

0 commit comments

Comments
 (0)