mirror of https://github.com/apache/openjpa.git
OPENJPA-293. Allow user configuration of error vs. warning if managed classes are not enhanced.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.0.0@568721 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3ae441064b
commit
4b9b0fc4a3
|
@ -34,6 +34,7 @@ import org.apache.openjpa.lib.log.Log;
|
||||||
import org.apache.openjpa.lib.util.BytecodeWriter;
|
import org.apache.openjpa.lib.util.BytecodeWriter;
|
||||||
import org.apache.openjpa.lib.util.JavaVersions;
|
import org.apache.openjpa.lib.util.JavaVersions;
|
||||||
import org.apache.openjpa.lib.util.Localizer;
|
import org.apache.openjpa.lib.util.Localizer;
|
||||||
|
import org.apache.openjpa.lib.util.Localizer.Message;
|
||||||
import org.apache.openjpa.meta.ClassMetaData;
|
import org.apache.openjpa.meta.ClassMetaData;
|
||||||
import org.apache.openjpa.meta.FieldMetaData;
|
import org.apache.openjpa.meta.FieldMetaData;
|
||||||
import org.apache.openjpa.meta.JavaTypes;
|
import org.apache.openjpa.meta.JavaTypes;
|
||||||
|
@ -81,18 +82,26 @@ public class ManagedClassSubclasser {
|
||||||
return null;
|
return null;
|
||||||
if (classes.size() == 0)
|
if (classes.size() == 0)
|
||||||
return Collections.EMPTY_LIST;
|
return Collections.EMPTY_LIST;
|
||||||
if (!conf.getRuntimeClassOptimization()) {
|
|
||||||
|
Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
|
||||||
|
if (conf.getRuntimeUnenhancedClassesConstant()
|
||||||
|
!= RuntimeUnenhancedClasssesModes.SUPPORTED) {
|
||||||
Collection unenhanced = new ArrayList();
|
Collection unenhanced = new ArrayList();
|
||||||
for (Class cls : classes)
|
for (Class cls : classes)
|
||||||
if (!PersistenceCapable.class.isAssignableFrom(cls))
|
if (!PersistenceCapable.class.isAssignableFrom(cls))
|
||||||
unenhanced.add(cls);
|
unenhanced.add(cls);
|
||||||
if (unenhanced.size() > 0)
|
if (unenhanced.size() > 0) {
|
||||||
throw new UserException(_loc.get(
|
Message msg = _loc.get("runtime-optimization-disabled",
|
||||||
"runtime-optimization-disabled", unenhanced));
|
unenhanced);
|
||||||
|
if (conf.getRuntimeUnenhancedClassesConstant()
|
||||||
|
== RuntimeUnenhancedClasssesModes.WARN)
|
||||||
|
log.warn(msg);
|
||||||
|
else
|
||||||
|
throw new UserException(msg);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
|
|
||||||
boolean redefine = ClassRedefiner.canRedefineClasses();
|
boolean redefine = ClassRedefiner.canRedefineClasses();
|
||||||
if (redefine)
|
if (redefine)
|
||||||
log.info(_loc.get("enhance-and-subclass-no-redef-start",
|
log.info(_loc.get("enhance-and-subclass-no-redef-start",
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
|
||||||
import org.apache.openjpa.lib.conf.Configurations;
|
import org.apache.openjpa.lib.conf.Configurations;
|
||||||
import org.apache.openjpa.lib.util.J2DoPrivHelper;
|
import org.apache.openjpa.lib.util.J2DoPrivHelper;
|
||||||
import org.apache.openjpa.lib.util.Options;
|
import org.apache.openjpa.lib.util.Options;
|
||||||
import org.apache.openjpa.lib.util.TemporaryClassLoader;
|
|
||||||
import org.apache.openjpa.util.ClassResolver;
|
import org.apache.openjpa.util.ClassResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,13 +44,13 @@ import org.apache.openjpa.util.ClassResolver;
|
||||||
* <p>By default, if specified, the agent runs the OpenJPA enhancer on
|
* <p>By default, if specified, the agent runs the OpenJPA enhancer on
|
||||||
* all classes listed in the first persistence unit as they are loaded,
|
* all classes listed in the first persistence unit as they are loaded,
|
||||||
* and redefines all other persistent classes when they are encountered.
|
* and redefines all other persistent classes when they are encountered.
|
||||||
* To disable enhancement and rely solely on the redefinition logic, set
|
* To disable enhancement at class-load time and rely solely on the
|
||||||
* the RuntimeEnhancement flag to false. To disable redefinition and rely
|
* redefinition logic, set the ClassLoadEnhancement flag to false. To
|
||||||
* solely on pre-deployment or runtime enhancement, set the
|
* disable redefinition and rely solely on pre-deployment or class-load
|
||||||
* RuntimeRedefinition flag to false.
|
* enhancement, set the RuntimeRedefinition flag to false.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p><code>java -javaagent:openjpa.jar=RuntimeEnhancement=false</code></p>
|
* <p><code>java -javaagent:openjpa.jar=ClassLoadEnhancement=false</code></p>
|
||||||
*
|
*
|
||||||
* @author Abe White
|
* @author Abe White
|
||||||
* @author Patrick Linskey
|
* @author Patrick Linskey
|
||||||
|
@ -62,18 +61,23 @@ public class PCEnhancerAgent {
|
||||||
Options opts = Configurations.parseProperties(args);
|
Options opts = Configurations.parseProperties(args);
|
||||||
|
|
||||||
if (opts.getBooleanProperty(
|
if (opts.getBooleanProperty(
|
||||||
"RuntimeEnhancement", "runtimeEnhancement", true))
|
"ClassLoadEnhancement", "classLoadEnhancement", true))
|
||||||
registerRuntimeEnhancer(inst, opts);
|
registerClassLoadEnhancer(inst, opts);
|
||||||
|
|
||||||
if (opts.getBooleanProperty("RuntimeRedefinition",
|
// Deprecated property setting
|
||||||
"runtimeRedefinition", true)) {
|
if (opts.getBooleanProperty(
|
||||||
|
"RuntimeEnhancement", "runtimeEnhancement", true))
|
||||||
|
registerClassLoadEnhancer(inst, opts);
|
||||||
|
|
||||||
|
if (opts.getBooleanProperty(
|
||||||
|
"RuntimeRedefinition", "runtimeRedefinition", true)) {
|
||||||
InstrumentationFactory.setInstrumentation(inst);
|
InstrumentationFactory.setInstrumentation(inst);
|
||||||
} else {
|
} else {
|
||||||
InstrumentationFactory.setDynamicallyInstallAgent(false);
|
InstrumentationFactory.setDynamicallyInstallAgent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerRuntimeEnhancer(Instrumentation inst,
|
private static void registerClassLoadEnhancer(Instrumentation inst,
|
||||||
Options opts) {
|
Options opts) {
|
||||||
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
|
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
|
||||||
Configurations.populateConfiguration(conf, opts);
|
Configurations.populateConfiguration(conf, opts);
|
||||||
|
|
|
@ -1389,31 +1389,63 @@ public interface OpenJPAConfiguration
|
||||||
public StoreFacadeTypeRegistry getStoreFacadeTypeRegistry();
|
public StoreFacadeTypeRegistry getStoreFacadeTypeRegistry();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@link org.apache.openjpa.event.BrokerFactoryEventManager} associated with this
|
* Return the {@link org.apache.openjpa.event.BrokerFactoryEventManager}
|
||||||
* configuration.
|
* associated with this configuration.
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public BrokerFactoryEventManager getBrokerFactoryEventManager();
|
public BrokerFactoryEventManager getBrokerFactoryEventManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not runtime class optimization is enabled.
|
* Specifies how OpenJPA handles unenhanced types. Possible values are:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>enabled</code>: Runtime optimization of persistent types
|
||||||
|
* is available. This is the default</li>
|
||||||
|
* <li><code>disabled</code>: Runtime optimization of persistent types
|
||||||
|
* is not available. An exception will be thrown if the system loads with
|
||||||
|
* persistent types that are not enhanced.</li>
|
||||||
|
* <li><code>warn</code>: Runtime optimization of persistent types is
|
||||||
|
* not available, but no exception will be thrown initially. A warning will
|
||||||
|
* be logged instead. It is likely that the system will fail at a later
|
||||||
|
* point. This might be suitable for environments with complex classloader
|
||||||
|
* configurations.</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public boolean getRuntimeClassOptimization();
|
public String getRuntimeUnenhancedClasses();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not runtime class optimization is enabled.
|
* Specifies how OpenJPA handles unenhanced types.
|
||||||
*
|
*
|
||||||
|
* @see {@link #getRuntimeUnenhancedClasses()}
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public void setRuntimeClassOptimization(Boolean enabled);
|
public void setRuntimeUnenhancedClasses(String mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for JCA usage of {@link #setRetryClassRegistration(boolean)}.
|
* Return the runtime class optimization setting as one of the
|
||||||
|
* following symbolic constants:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link RuntimeClassOptimizationModes#RUNTIME_OPT_ENABLED}</li>
|
||||||
|
* <li>{@link RuntimeClassOptimizationModes#RUNTIME_OPT_DISABLED}</li>
|
||||||
|
* <li>{@link RuntimeClassOptimizationModes#RUNTIME_OPT_WARN}</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public void setRuntimeClassOptimization(boolean enabled);
|
public int getRuntimeUnenhancedClassesConstant();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the runtime class optimization setting as one of the
|
||||||
|
* following symbolic constants:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link RuntimeClassOptimizationModes#RUNTIME_OPT_ENABLED}</li>
|
||||||
|
* <li>{@link RuntimeClassOptimizationModes#RUNTIME_OPT_DISABLED}</li>
|
||||||
|
* <li>{@link RuntimeClassOptimizationModes#RUNTIME_OPT_WARN}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public void setRuntimeUnenhancedClasses(int mode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import org.apache.openjpa.util.ClassResolver;
|
||||||
import org.apache.openjpa.util.ImplHelper;
|
import org.apache.openjpa.util.ImplHelper;
|
||||||
import org.apache.openjpa.util.ProxyManager;
|
import org.apache.openjpa.util.ProxyManager;
|
||||||
import org.apache.openjpa.util.StoreFacadeTypeRegistry;
|
import org.apache.openjpa.util.StoreFacadeTypeRegistry;
|
||||||
|
import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the {@link OpenJPAConfiguration} interface.
|
* Implementation of the {@link OpenJPAConfiguration} interface.
|
||||||
|
@ -131,7 +132,7 @@ public class OpenJPAConfigurationImpl
|
||||||
public ObjectValue orphanedKeyPlugin;
|
public ObjectValue orphanedKeyPlugin;
|
||||||
public ObjectValue compatibilityPlugin;
|
public ObjectValue compatibilityPlugin;
|
||||||
public QueryCompilationCacheValue queryCompilationCachePlugin;
|
public QueryCompilationCacheValue queryCompilationCachePlugin;
|
||||||
public BooleanValue runtimeClassOptimization;
|
public IntValue runtimeUnenhancedClasses;
|
||||||
|
|
||||||
// custom values
|
// custom values
|
||||||
public BrokerFactoryValue brokerFactoryPlugin;
|
public BrokerFactoryValue brokerFactoryPlugin;
|
||||||
|
@ -480,9 +481,18 @@ public class OpenJPAConfigurationImpl
|
||||||
"getQueryCompilationCacheInstance");
|
"getQueryCompilationCacheInstance");
|
||||||
addValue(queryCompilationCachePlugin);
|
addValue(queryCompilationCachePlugin);
|
||||||
|
|
||||||
runtimeClassOptimization = addBoolean("RuntimeClassOptimization");
|
runtimeUnenhancedClasses = addInt("RuntimeUnenhancedClasses");
|
||||||
runtimeClassOptimization.setDefault("true");
|
runtimeUnenhancedClasses.setAliases(new String[] {
|
||||||
runtimeClassOptimization.set(true);
|
"supported", String.valueOf(
|
||||||
|
RuntimeUnenhancedClasssesModes.SUPPORTED),
|
||||||
|
"unsupported", String.valueOf(
|
||||||
|
RuntimeUnenhancedClasssesModes.UNSUPPORTED),
|
||||||
|
"warn", String.valueOf(
|
||||||
|
RuntimeUnenhancedClasssesModes.WARN),
|
||||||
|
});
|
||||||
|
runtimeUnenhancedClasses.setDefault("supported");
|
||||||
|
runtimeUnenhancedClasses.setString("supported");
|
||||||
|
runtimeUnenhancedClasses.setAliasListComprehensive(true);
|
||||||
|
|
||||||
// initialize supported options that some runtimes may not support
|
// initialize supported options that some runtimes may not support
|
||||||
supportedOptions.add(OPTION_NONTRANS_READ);
|
supportedOptions.add(OPTION_NONTRANS_READ);
|
||||||
|
@ -1427,17 +1437,22 @@ public class OpenJPAConfigurationImpl
|
||||||
return _brokerFactoryEventManager;
|
return _brokerFactoryEventManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getRuntimeClassOptimization() {
|
public String getRuntimeUnenhancedClasses() {
|
||||||
return runtimeClassOptimization.get();
|
return runtimeUnenhancedClasses.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRuntimeClassOptimization(Boolean enabled) {
|
public int getRuntimeUnenhancedClassesConstant() {
|
||||||
setRuntimeClassOptimization(enabled.booleanValue());
|
return runtimeUnenhancedClasses.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRuntimeClassOptimization(boolean enabled) {
|
public void setRuntimeUnenhancedClasses(int mode) {
|
||||||
assertNotReadOnly();
|
assertNotReadOnly();
|
||||||
runtimeClassOptimization.set(enabled);
|
runtimeUnenhancedClasses.set(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRuntimeUnenhancedClasses(String mode) {
|
||||||
|
assertNotReadOnly();
|
||||||
|
runtimeUnenhancedClasses.setString(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void instantiateAll() {
|
public void instantiateAll() {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible values for the <code>openjpa.RuntimeUnenhancedClasses</code>
|
||||||
|
* configuration setting.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public interface RuntimeUnenhancedClasssesModes {
|
||||||
|
public final static int SUPPORTED = 0;
|
||||||
|
public final static int UNSUPPORTED = 1;
|
||||||
|
public final static int WARN = 2;
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import org.apache.openjpa.enhance.PCRegistry;
|
||||||
import org.apache.openjpa.enhance.StateManager;
|
import org.apache.openjpa.enhance.StateManager;
|
||||||
import org.apache.openjpa.enhance.ManagedInstanceProvider;
|
import org.apache.openjpa.enhance.ManagedInstanceProvider;
|
||||||
import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
|
import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
|
||||||
|
import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
|
||||||
import org.apache.openjpa.kernel.FetchConfiguration;
|
import org.apache.openjpa.kernel.FetchConfiguration;
|
||||||
import org.apache.openjpa.kernel.LockManager;
|
import org.apache.openjpa.kernel.LockManager;
|
||||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
|
@ -216,7 +217,8 @@ public class ImplHelper {
|
||||||
public static boolean isManagedType(OpenJPAConfiguration conf, Class type) {
|
public static boolean isManagedType(OpenJPAConfiguration conf, Class type) {
|
||||||
return (PersistenceCapable.class.isAssignableFrom(type)
|
return (PersistenceCapable.class.isAssignableFrom(type)
|
||||||
|| (type != null
|
|| (type != null
|
||||||
&& (conf == null || conf.getRuntimeClassOptimization())
|
&& (conf == null || conf.getRuntimeUnenhancedClassesConstant()
|
||||||
|
== RuntimeUnenhancedClasssesModes.SUPPORTED)
|
||||||
&& PCRegistry.isRegistered(type)));
|
&& PCRegistry.isRegistered(type)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -541,11 +541,12 @@ Compatibility-displayorder: 50
|
||||||
Compatibility-expert: true
|
Compatibility-expert: true
|
||||||
Compatibility-interface: org.apache.openjpa.conf.Compatibility
|
Compatibility-interface: org.apache.openjpa.conf.Compatibility
|
||||||
|
|
||||||
RuntimeClassOptimization-name: Runtime class optimization
|
RuntimeUnenhancedClasses-name: Runtime unenhanced classes
|
||||||
RuntimeClassOptimization-desc: Either "true" or "false".
|
RuntimeUnenhancedClasses-desc: Either "supported", "unsupported", or "warn". \
|
||||||
RuntimeClassOptimization-type: General
|
Defaults to "supported".
|
||||||
RuntimeClassOptimization-cat: Optimization
|
RuntimeUnenhancedClasses-type: General
|
||||||
RuntimeClassOptimization-displayorder: 50
|
RuntimeUnenhancedClasses-cat: Optimization
|
||||||
|
RuntimeUnenhancedClasses-displayorder: 50
|
||||||
|
|
||||||
no-named-cf: use a DataSource bound to JNDI
|
no-named-cf: use a DataSource bound to JNDI
|
||||||
diff-specs: Attempt to configure for multiple specifications. Was configured \
|
diff-specs: Attempt to configure for multiple specifications. Was configured \
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class TestEnhancementConfiguration
|
||||||
public void testEnhancementConfiguration() {
|
public void testEnhancementConfiguration() {
|
||||||
try {
|
try {
|
||||||
emf = createEMF(
|
emf = createEMF(
|
||||||
"openjpa.RuntimeClassOptimization", "false",
|
"openjpa.RuntimeUnenhancedClasses", "unsupported",
|
||||||
UnenhancedFieldAccess.class, CLEAR_TABLES);
|
UnenhancedFieldAccess.class, CLEAR_TABLES);
|
||||||
assertFalse(ImplHelper.isManagedType(emf.getConfiguration(),
|
assertFalse(ImplHelper.isManagedType(emf.getConfiguration(),
|
||||||
UnenhancedFieldAccess.class));
|
UnenhancedFieldAccess.class));
|
||||||
|
@ -38,7 +38,8 @@ public class TestEnhancementConfiguration
|
||||||
"that depends on unenhanced types but disables runtime" +
|
"that depends on unenhanced types but disables runtime" +
|
||||||
"redefinition.");
|
"redefinition.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// expected
|
assertTrue(e.getMessage().contains(
|
||||||
|
"This configuration disallows runtime optimization"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue