1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
27
27
28
28
/**
29
29
* 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.
32
32
*
33
33
* @author Rod Johnson
34
+ * @author Juergen Hoeller
34
35
* @since 2.0
35
36
* @see javax.persistence.spi.PersistenceUnitInfo#addTransformer(javax.persistence.spi.ClassTransformer)
36
37
*/
37
38
class ClassFileTransformerAdapter implements ClassFileTransformer {
38
39
39
40
private static final Log logger = LogFactory .getLog (ClassFileTransformerAdapter .class );
40
41
42
+
41
43
private final ClassTransformer classTransformer ;
42
44
45
+ private boolean currentlyTransforming = false ;
46
+
43
47
44
48
public ClassFileTransformerAdapter (ClassTransformer classTransformer ) {
45
49
Assert .notNull (classTransformer , "ClassTransformer must not be null" );
@@ -52,28 +56,42 @@ public byte[] transform(
52
56
ClassLoader loader , String className , Class <?> classBeingRedefined ,
53
57
ProtectionDomain protectionDomain , byte [] classfileBuffer ) {
54
58
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 ;
62
64
}
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 ;
74
94
}
75
- // The exception will be ignored by the class loader, anyway...
76
- throw new IllegalStateException ("Could not weave class [" + className + "]" , ex );
77
95
}
78
96
}
79
97
0 commit comments