This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomee-jakarta.git
commit fc4ec2e5c667659c2e076c52a829c12849d5d352 Author: Richard Zowalla <richard.zowa...@hs-heilbronn.de> AuthorDate: Thu Jun 10 17:17:02 2021 +0200 TOMEE-3753: Unpatched OpenJPA 3.2.0 classes --- .../openjpa/enhance/PCClassFileTransformer.java | 254 --------------------- .../openjpa/lib/meta/ClassMetaDataIterator.java | 23 +- .../openjpa/lib/util/TemporaryClassLoader.java | 4 +- .../openjpa/meta/AbstractMetaDataDefaults.java | 10 +- .../persistence/PersistenceProviderImpl.java | 80 ++----- 5 files changed, 38 insertions(+), 333 deletions(-) diff --git a/transform/src/patch/java/org/apache/openjpa/enhance/PCClassFileTransformer.java b/transform/src/patch/java/org/apache/openjpa/enhance/PCClassFileTransformer.java deleted file mode 100644 index ee2cdac..0000000 --- a/transform/src/patch/java/org/apache/openjpa/enhance/PCClassFileTransformer.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.openjpa.enhance; - -import java.io.ByteArrayInputStream; -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.security.AccessController; -import java.security.ProtectionDomain; -import java.util.Set; - -import org.apache.openjpa.conf.OpenJPAConfiguration; -import org.apache.openjpa.lib.log.Log; -import org.apache.openjpa.lib.util.J2DoPrivHelper; -import org.apache.openjpa.lib.util.Localizer; -import org.apache.openjpa.lib.util.Options; -import org.apache.openjpa.meta.MetaDataRepository; -import org.apache.openjpa.util.GeneralException; - -import serp.bytecode.BCClass; -import serp.bytecode.Project; -import serp.bytecode.lowlevel.ConstantPoolTable; - - -/** - * Transformer that makes persistent classes implement the - * {@link PersistenceCapable} interface at runtime. - * - * @author Abe White - */ -public class PCClassFileTransformer - implements ClassFileTransformer { - - private static final Localizer _loc = Localizer.forPackage - (PCClassFileTransformer.class); - - private final MetaDataRepository _repos; - private final PCEnhancer.Flags _flags; - private final ClassLoader _tmpLoader; - private final Log _log; - private final Set _names; - private boolean _transforming = false; - - /** - * Constructor. - * - * @param repos metadata repository to use internally - * @param opts enhancer configuration options - * @param loader temporary class loader for loading intermediate classes - */ - public PCClassFileTransformer(MetaDataRepository repos, Options opts, - ClassLoader loader) { - this(repos, toFlags(opts), loader, opts.removeBooleanProperty - ("scanDevPath", "ScanDevPath", false)); - } - - /** - * Create enhancer flags from the given options. - */ - private static PCEnhancer.Flags toFlags(Options opts) { - PCEnhancer.Flags flags = new PCEnhancer.Flags(); - flags.addDefaultConstructor = opts.removeBooleanProperty - ("addDefaultConstructor", "AddDefaultConstructor", - flags.addDefaultConstructor); - flags.enforcePropertyRestrictions = opts.removeBooleanProperty - ("enforcePropertyRestrictions", "EnforcePropertyRestrictions", - flags.enforcePropertyRestrictions); - return flags; - } - - /** - * Constructor. - * - * @param repos metadata repository to use internally - * @param flags enhancer configuration - * @param tmpLoader temporary class loader for loading intermediate classes - * @param devscan whether to scan the dev classpath for persistent types - * if none are configured - */ - public PCClassFileTransformer(MetaDataRepository repos, - PCEnhancer.Flags flags, ClassLoader tmpLoader, boolean devscan) { - _repos = repos; - _tmpLoader = tmpLoader; - - _log = repos.getConfiguration(). - getLog(OpenJPAConfiguration.LOG_ENHANCE); - _flags = flags; - - _names = repos.getPersistentTypeNames(devscan, tmpLoader); - if (_names == null && _log.isInfoEnabled()) - _log.info(_loc.get("runtime-enhance-pcclasses")); - } - - @Override - public byte[] transform(ClassLoader loader, String className, - Class redef, ProtectionDomain domain, byte[] bytes) - throws IllegalClassFormatException { - if (loader == _tmpLoader) - return null; - - // JDK bug -- OPENJPA-1676 - if (className == null) { - return null; - } - // prevent re-entrant calls, which can occur if the enhancing - // loader is used to also load OpenJPA libraries; this is to prevent - // recursive enhancement attempts for internal openjpa libraries - if (_transforming) - return null; - - _transforming = true; - - return transform0(className, redef, bytes); - } - - /** - * We have to split the transform method into two methods to avoid - * ClassCircularityError when executing method using pure-JIT JVMs - * such as JRockit. - */ - private byte[] transform0(String className, Class redef, byte[] bytes) - throws IllegalClassFormatException { - - byte[] returnBytes = null; - try { - Boolean enhance = needsEnhance(className, redef, bytes); - if (enhance != null && _log.isTraceEnabled()) - _log.trace(_loc.get("needs-runtime-enhance", className, - enhance)); - if (enhance != Boolean.TRUE) - return null; - - ClassLoader oldLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()); - AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(_tmpLoader)); - try { - PCEnhancer enhancer = new PCEnhancer(_repos.getConfiguration(), - new Project().loadClass(new ByteArrayInputStream(bytes), - _tmpLoader), _repos); - enhancer.setAddDefaultConstructor(_flags.addDefaultConstructor); - enhancer.setEnforcePropertyRestrictions - (_flags.enforcePropertyRestrictions); - - if (enhancer.run() == PCEnhancer.ENHANCE_NONE) - return null; - BCClass pcb = enhancer.getPCBytecode(); - returnBytes = AsmAdaptor.toByteArray(pcb, pcb.toByteArray()); - return returnBytes; - } finally { - AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(oldLoader)); - } - } catch (Throwable t) { - _log.warn(_loc.get("cft-exception-thrown", className), t); - if (t instanceof RuntimeException) - throw (RuntimeException) t; - if (t instanceof IllegalClassFormatException) - throw (IllegalClassFormatException) t; - throw new GeneralException(t); - } finally { - _transforming = false; - if (returnBytes != null && _log.isTraceEnabled()) - _log.trace(_loc.get("runtime-enhance-complete", className, - bytes.length, returnBytes.length)); - } - } - - /** - * Return whether the given class needs enhancement. - */ - private Boolean needsEnhance(String clsName, Class redef, byte[] bytes) { - if (redef != null) { - Class[] intfs = redef.getInterfaces(); - for (int i = 0; i < intfs.length; i++) - if (PersistenceCapable.class.getName(). - equals(intfs[i].getName())) - return Boolean.valueOf(!isEnhanced(bytes)); - return null; - } - - if (_names != null) { - if (_names.contains(clsName.replace('/', '.'))) - return Boolean.valueOf(!isEnhanced(bytes)); - return null; - } - - if (clsName.startsWith("java/") || clsName.startsWith("javax/") || clsName.startsWith("jakarta/")) - return null; - if (isEnhanced(bytes)) - return Boolean.FALSE; - - try { - Class c = Class.forName(clsName.replace('/', '.'), false, - _tmpLoader); - if (_repos.getMetaData(c, null, false) != null) - return Boolean.TRUE; - return null; - } catch (ClassNotFoundException cnfe) { - // cannot load the class: this might mean that it is a proxy - // or otherwise inaccessible class which can't be an entity - return Boolean.FALSE; - } catch (LinkageError cce) { - // this can happen if we are loading classes that this - // class depends on; these will never be enhanced anyway - return Boolean.FALSE; - } catch (RuntimeException re) { - throw re; - } catch (Throwable t) { - throw new GeneralException(t); - } - } - - /** - * Analyze the bytecode to see if the given class definition implements - * {@link PersistenceCapable}. - */ - private static boolean isEnhanced(byte[] b) { - if (AsmAdaptor.use()) - { - return AsmAdaptor.isEnhanced(b); - } - - ConstantPoolTable table = new ConstantPoolTable(b); - int idx = table.getEndIndex(); - - idx += 6; // skip access, cls, super - int ifaces = table.readUnsignedShort(idx); - int clsEntry, utfEntry; - String name; - for (int i = 0; i < ifaces; i++) { - idx += 2; - clsEntry = table.readUnsignedShort(idx); - utfEntry = table.readUnsignedShort(table.get(clsEntry)); - name = table.readString(table.get(utfEntry)); - if ("org/apache/openjpa/enhance/PersistenceCapable".equals(name)) - return true; - } - return false; - } -} \ No newline at end of file diff --git a/transform/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java b/transform/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java index b972512..1d0bcb4 100644 --- a/transform/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java +++ b/transform/src/patch/java/org/apache/openjpa/lib/meta/ClassMetaDataIterator.java @@ -63,12 +63,11 @@ public class ClassMetaDataIterator implements MetaDataIterator { * of metadata files, and whether to parse top-down or bottom-up. */ public ClassMetaDataIterator(Class<?> cls, String suffix, - ClassLoader loader, boolean topDown) { + ClassLoader loader, boolean topDown) { // skip classes that can't have metadata if (cls != null && (cls.isPrimitive() - || cls.getName().startsWith("java.") - || cls.getName().startsWith("javax.") - || cls.getName().startsWith("jakarta."))) { + || cls.getName().startsWith("java.") + || cls.getName().startsWith("javax."))) { _loader = null; _locs = Collections.emptyList(); return; @@ -76,15 +75,15 @@ public class ClassMetaDataIterator implements MetaDataIterator { if (loader == null) { MultiClassLoader multi = AccessController - .doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction()); + .doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction()); multi.addClassLoader(MultiClassLoader.SYSTEM_LOADER); multi.addClassLoader(MultiClassLoader.THREAD_LOADER); multi.addClassLoader(getClass().getClassLoader()); if (cls != null) { ClassLoader clsLoader = (ClassLoader) - AccessController.doPrivileged( - J2DoPrivHelper.getClassLoaderAction(cls)); + AccessController.doPrivileged( + J2DoPrivHelper.getClassLoaderAction(cls)); if (clsLoader != null) multi.addClassLoader(clsLoader); } @@ -158,8 +157,8 @@ public class ClassMetaDataIterator implements MetaDataIterator { _urls.clear(); try { e = AccessController.doPrivileged( - J2DoPrivHelper.getResourcesAction( - _loader, _locs.get(_loc))); + J2DoPrivHelper.getResourcesAction( + _loader, _locs.get(_loc))); } catch (PrivilegedActionException pae) { throw (IOException) pae.getException(); } @@ -182,7 +181,7 @@ public class ClassMetaDataIterator implements MetaDataIterator { throw new IllegalStateException(); try { return AccessController.doPrivileged( - J2DoPrivHelper.openStreamAction(_urls.get(_url))); + J2DoPrivHelper.openStreamAction(_urls.get(_url))); } catch (PrivilegedActionException pae) { throw (IOException) pae.getException(); } @@ -193,8 +192,8 @@ public class ClassMetaDataIterator implements MetaDataIterator { if (_url == -1 || _url >= _urls.size()) throw new IllegalStateException(); File file = new File(URLDecoder.decode((_urls.get(_url)).getFile())); - return ((AccessController.doPrivileged( - J2DoPrivHelper.existsAction(file))).booleanValue()) ? file:null; + return (AccessController.doPrivileged( + J2DoPrivHelper.existsAction(file))) ? file:null; } @Override diff --git a/transform/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java b/transform/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java index dc5a93c..f56f2fc 100644 --- a/transform/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java +++ b/transform/src/patch/java/org/apache/openjpa/lib/util/TemporaryClassLoader.java @@ -54,7 +54,7 @@ public class TemporaryClassLoader extends ClassLoader { // bug #283. defer to system if the name is a protected name. // "sun." is required for JDK 1.4, which has an access check for // sun.reflect.GeneratedSerializationConstructorAccessor1 - if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("jakarta.") + if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("sun.") || name.startsWith("jdk.")) { return Class.forName(name, resolve, getClass().getClassLoader()); } @@ -120,4 +120,4 @@ public class TemporaryClassLoader extends ClassLoader { int access = ConstantPoolTable.readUnsignedShort(b, idx); return (access & 0x4000) != 0; // access constant for enum type } -} \ No newline at end of file +} diff --git a/transform/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java b/transform/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java index 03cd4fc..8c8f89c 100644 --- a/transform/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java +++ b/transform/src/patch/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java @@ -223,8 +223,7 @@ public abstract class AbstractMetaDataDefaults String name; boolean def; FieldMetaData fmd; - for (int i = 0; i < members.size(); i++) { - Member member = members.get(i); + for (Member member : members) { name = getFieldName(member); if (name == null || isReservedFieldName(name)) continue; @@ -288,7 +287,7 @@ public abstract class AbstractMetaDataDefaults public static String getFieldName(Member member) { if (member instanceof Field) return member.getName(); - if (member instanceof Method == false) + if (!(member instanceof Method)) return null; Method method = (Method) member; String name = method.getName(); @@ -352,8 +351,7 @@ public abstract class AbstractMetaDataDefaults */ protected static boolean isUserDefined(Class<?> cls) { return cls != null && !cls.getName().startsWith("java.") - && !cls.getName().startsWith ("javax.") - && !cls.getName().startsWith ("jakarta."); + && !cls.getName().startsWith ("javax."); } /** @@ -419,4 +417,4 @@ public abstract class AbstractMetaDataDefaults return result; } -} \ No newline at end of file +} diff --git a/transform/src/patch/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java b/transform/src/patch/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java index ff4be9d..bbe358d 100644 --- a/transform/src/patch/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java +++ b/transform/src/patch/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java @@ -26,12 +26,12 @@ import java.security.ProtectionDomain; import java.util.HashMap; import java.util.Map; -import jakarta.persistence.EntityManager; -import jakarta.persistence.spi.ClassTransformer; -import jakarta.persistence.spi.LoadState; -import jakarta.persistence.spi.PersistenceProvider; -import jakarta.persistence.spi.PersistenceUnitInfo; -import jakarta.persistence.spi.ProviderUtil; +import javax.persistence.EntityManager; +import javax.persistence.spi.ClassTransformer; +import javax.persistence.spi.LoadState; +import javax.persistence.spi.PersistenceProvider; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.ProviderUtil; import org.apache.openjpa.conf.BrokerValue; import org.apache.openjpa.conf.OpenJPAConfiguration; @@ -136,7 +136,7 @@ public class PersistenceProviderImpl } private BrokerFactory getBrokerFactory(ConfigurationProvider cp, - Object poolValue, ClassLoader loader) { + Object poolValue, ClassLoader loader) { // handle "true" and "false" if (poolValue instanceof String && ("true".equalsIgnoreCase((String) poolValue) @@ -173,7 +173,7 @@ public class PersistenceProviderImpl String ctOpts = (String) Configurations.getProperty(CLASS_TRANSFORMER_OPTIONS, pui.getProperties()); try { pui.addTransformer(new ClassTransformerImpl(cp, ctOpts, - pui.getNewTempClassLoader(), newConfigurationImpl())); + pui.getNewTempClassLoader(), newConfigurationImpl())); } catch (Exception e) { // fail gracefully transformerException = e; @@ -228,12 +228,7 @@ public class PersistenceProviderImpl @Override public void generateSchema(final PersistenceUnitInfo info, final Map map) { final Map runMap = map == null ? new HashMap<>() : new HashMap<>(map); - - if (!acceptProvider(runMap)) { - return; - } - - runMap.put("jakarta.persistence.schema-generation.database.action", "create"); + runMap.put("javax.persistence.schema-generation.database.action", "create"); final OpenJPAEntityManagerFactory factory = createContainerEntityManagerFactory(info, runMap); try { synchronizeMappings(factory); @@ -245,12 +240,7 @@ public class PersistenceProviderImpl @Override public boolean generateSchema(final String persistenceUnitName, final Map map) { final Map runMap = map == null ? new HashMap<>() : new HashMap<>(map); - - if (!acceptProvider(runMap)) { - return false; - } - - runMap.put("jakarta.persistence.schema-generation.database.action", "create"); + runMap.put("javax.persistence.schema-generation.database.action", "create"); final OpenJPAEntityManagerFactory factory = createEntityManagerFactory(persistenceUnitName, runMap); try { final Object obj = synchronizeMappings(factory); @@ -260,32 +250,6 @@ public class PersistenceProviderImpl } } - // if persistence provider is specific, don't do anything - // only allowed to process if persistence provider matches or if not provider is specified - public boolean acceptProvider(final Map properties){ - Object provider = properties.get("jakarta.persistence.provider"); - - // provider is specified, so it has to match - if (provider != null){ - if (provider instanceof Class){ - provider = ((Class)provider).getName(); - } - try{ - if (! ((String)provider).equals(org.apache.openjpa.persistence.PersistenceProviderImpl.class.getName())){ - return false; - } - - }catch(ClassCastException e){ - return false; - // not a recognized provider property value so must be another provider. - } - } - - // no provider specified - return true; - - } - private Object synchronizeMappings(final OpenJPAEntityManagerFactory factory) { if (EntityManagerFactoryImpl.class.isInstance(factory)) { final EntityManagerFactoryImpl entityManagerFactory = EntityManagerFactoryImpl.class.cast(factory); @@ -295,7 +259,7 @@ public class PersistenceProviderImpl } try { final Method synchronizeMappings = brokerFactory.getClass() - .getDeclaredMethod("synchronizeMappings", ClassLoader.class); + .getDeclaredMethod("synchronizeMappings", ClassLoader.class); if (!synchronizeMappings.isAccessible()) { synchronizeMappings.setAccessible(true); } @@ -365,7 +329,7 @@ public class PersistenceProviderImpl private final ClassFileTransformer _trans; private ClassTransformerImpl(ConfigurationProvider cp, String props, - final ClassLoader tmpLoader, OpenJPAConfiguration conf) { + final ClassLoader tmpLoader, OpenJPAConfiguration conf) { cp.setInto(conf); // use the temporary loader for everything conf.setClassResolver(new ClassResolver() { @@ -378,17 +342,17 @@ public class PersistenceProviderImpl MetaDataRepository repos = conf.getMetaDataRepositoryInstance(); repos.setResolve(MetaDataModes.MODE_MAPPING, false); - _trans = new PCClassFileTransformer(repos, - Configurations.parseProperties(props), tmpLoader); + _trans = PCClassFileTransformer.newInstance(repos, + Configurations.parseProperties(props), tmpLoader); } @Override public byte[] transform(ClassLoader cl, String name, - Class<?> previousVersion, ProtectionDomain pd, byte[] bytes) + Class<?> previousVersion, ProtectionDomain pd, byte[] bytes) throws IllegalClassFormatException { return _trans.transform(cl, name, previousVersion, pd, bytes); } - } + } /** * This private worker method will attempt load the PCEnhancerAgent. @@ -397,9 +361,9 @@ public class PersistenceProviderImpl OpenJPAConfiguration conf = factory.getConfiguration(); Log log = conf.getLog(OpenJPAConfiguration.LOG_RUNTIME); - if (conf.getDynamicEnhancementAgent() == true) { + if (conf.getDynamicEnhancementAgent()) { boolean res = PCEnhancerAgent.loadDynamicAgent(log); - if (log.isInfoEnabled() && res == true ){ + if (log.isInfoEnabled() && res){ log.info(_loc.get("dynamic-agent")); } } @@ -409,16 +373,14 @@ public class PersistenceProviderImpl * This private worker method will attempt to setup the proper * LifecycleEventManager type based on if the javax.validation APIs are * available and a ValidatorImpl is required by the configuration. - * @param log - * @param conf * @throws if validation setup failed and was required by the config */ private void loadValidator(BrokerFactory factory) { OpenJPAConfiguration conf = factory.getConfiguration(); Log log = conf.getLog(OpenJPAConfiguration.LOG_RUNTIME); - if ((ValidationUtils.setupValidation(conf) == true) && - log.isInfoEnabled()) { + if ((ValidationUtils.setupValidation(conf)) && + log.isInfoEnabled()) { log.info(_loc.get("vlem-creation-info")); } } @@ -481,4 +443,4 @@ public class PersistenceProviderImpl return OpenJPAPersistenceUtil.isLoaded(obj, attr); } -} \ No newline at end of file +}