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.
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 */
3738class 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