You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rz...@apache.org on 2021/06/10 15:22:17 UTC
[tomee-jakarta] 01/02: TOMEE-3753: Unpatched OpenJPA 3.2.0 classes
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 <ri...@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
+}