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:
Patrick Linskey 2007-08-22 18:21:03 +00:00
parent 3ae441064b
commit 4b9b0fc4a3
8 changed files with 137 additions and 42 deletions

View File

@ -34,6 +34,7 @@ import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.BytecodeWriter;
import org.apache.openjpa.lib.util.JavaVersions;
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.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
@ -81,18 +82,26 @@ public class ManagedClassSubclasser {
return null;
if (classes.size() == 0)
return Collections.EMPTY_LIST;
if (!conf.getRuntimeClassOptimization()) {
Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
if (conf.getRuntimeUnenhancedClassesConstant()
!= RuntimeUnenhancedClasssesModes.SUPPORTED) {
Collection unenhanced = new ArrayList();
for (Class cls : classes)
if (!PersistenceCapable.class.isAssignableFrom(cls))
unenhanced.add(cls);
if (unenhanced.size() > 0)
throw new UserException(_loc.get(
"runtime-optimization-disabled", unenhanced));
if (unenhanced.size() > 0) {
Message msg = _loc.get("runtime-optimization-disabled",
unenhanced);
if (conf.getRuntimeUnenhancedClassesConstant()
== RuntimeUnenhancedClasssesModes.WARN)
log.warn(msg);
else
throw new UserException(msg);
}
return null;
}
Log log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
boolean redefine = ClassRedefiner.canRedefineClasses();
if (redefine)
log.info(_loc.get("enhance-and-subclass-no-redef-start",

View File

@ -26,7 +26,6 @@ import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.lib.util.TemporaryClassLoader;
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
* all classes listed in the first persistence unit as they are loaded,
* and redefines all other persistent classes when they are encountered.
* To disable enhancement and rely solely on the redefinition logic, set
* the RuntimeEnhancement flag to false. To disable redefinition and rely
* solely on pre-deployment or runtime enhancement, set the
* RuntimeRedefinition flag to false.
* To disable enhancement at class-load time and rely solely on the
* redefinition logic, set the ClassLoadEnhancement flag to false. To
* disable redefinition and rely solely on pre-deployment or class-load
* enhancement, set the RuntimeRedefinition flag to false.
* </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 Patrick Linskey
@ -62,18 +61,23 @@ public class PCEnhancerAgent {
Options opts = Configurations.parseProperties(args);
if (opts.getBooleanProperty(
"RuntimeEnhancement", "runtimeEnhancement", true))
registerRuntimeEnhancer(inst, opts);
"ClassLoadEnhancement", "classLoadEnhancement", true))
registerClassLoadEnhancer(inst, opts);
if (opts.getBooleanProperty("RuntimeRedefinition",
"runtimeRedefinition", true)) {
// Deprecated property setting
if (opts.getBooleanProperty(
"RuntimeEnhancement", "runtimeEnhancement", true))
registerClassLoadEnhancer(inst, opts);
if (opts.getBooleanProperty(
"RuntimeRedefinition", "runtimeRedefinition", true)) {
InstrumentationFactory.setInstrumentation(inst);
} else {
InstrumentationFactory.setDynamicallyInstallAgent(false);
}
}
private static void registerRuntimeEnhancer(Instrumentation inst,
private static void registerClassLoadEnhancer(Instrumentation inst,
Options opts) {
OpenJPAConfiguration conf = new OpenJPAConfigurationImpl();
Configurations.populateConfiguration(conf, opts);

View File

@ -1389,31 +1389,63 @@ public interface OpenJPAConfiguration
public StoreFacadeTypeRegistry getStoreFacadeTypeRegistry();
/**
* Return the {@link org.apache.openjpa.event.BrokerFactoryEventManager} associated with this
* configuration.
* Return the {@link org.apache.openjpa.event.BrokerFactoryEventManager}
* associated with this configuration.
*
* @since 1.0.0
*/
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
*/
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
*/
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
*/
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);
}

View File

@ -53,6 +53,7 @@ import org.apache.openjpa.util.ClassResolver;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.ProxyManager;
import org.apache.openjpa.util.StoreFacadeTypeRegistry;
import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
/**
* Implementation of the {@link OpenJPAConfiguration} interface.
@ -131,7 +132,7 @@ public class OpenJPAConfigurationImpl
public ObjectValue orphanedKeyPlugin;
public ObjectValue compatibilityPlugin;
public QueryCompilationCacheValue queryCompilationCachePlugin;
public BooleanValue runtimeClassOptimization;
public IntValue runtimeUnenhancedClasses;
// custom values
public BrokerFactoryValue brokerFactoryPlugin;
@ -480,9 +481,18 @@ public class OpenJPAConfigurationImpl
"getQueryCompilationCacheInstance");
addValue(queryCompilationCachePlugin);
runtimeClassOptimization = addBoolean("RuntimeClassOptimization");
runtimeClassOptimization.setDefault("true");
runtimeClassOptimization.set(true);
runtimeUnenhancedClasses = addInt("RuntimeUnenhancedClasses");
runtimeUnenhancedClasses.setAliases(new String[] {
"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
supportedOptions.add(OPTION_NONTRANS_READ);
@ -1427,17 +1437,22 @@ public class OpenJPAConfigurationImpl
return _brokerFactoryEventManager;
}
public boolean getRuntimeClassOptimization() {
return runtimeClassOptimization.get();
public String getRuntimeUnenhancedClasses() {
return runtimeUnenhancedClasses.getString();
}
public void setRuntimeClassOptimization(Boolean enabled) {
setRuntimeClassOptimization(enabled.booleanValue());
public int getRuntimeUnenhancedClassesConstant() {
return runtimeUnenhancedClasses.get();
}
public void setRuntimeClassOptimization(boolean enabled) {
public void setRuntimeUnenhancedClasses(int mode) {
assertNotReadOnly();
runtimeClassOptimization.set(enabled);
runtimeUnenhancedClasses.set(mode);
}
public void setRuntimeUnenhancedClasses(String mode) {
assertNotReadOnly();
runtimeUnenhancedClasses.setString(mode);
}
public void instantiateAll() {

View File

@ -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;
}

View File

@ -30,6 +30,7 @@ import org.apache.openjpa.enhance.PCRegistry;
import org.apache.openjpa.enhance.StateManager;
import org.apache.openjpa.enhance.ManagedInstanceProvider;
import org.apache.openjpa.enhance.ReflectingPersistenceCapable;
import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.LockManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
@ -216,7 +217,8 @@ public class ImplHelper {
public static boolean isManagedType(OpenJPAConfiguration conf, Class type) {
return (PersistenceCapable.class.isAssignableFrom(type)
|| (type != null
&& (conf == null || conf.getRuntimeClassOptimization())
&& (conf == null || conf.getRuntimeUnenhancedClassesConstant()
== RuntimeUnenhancedClasssesModes.SUPPORTED)
&& PCRegistry.isRegistered(type)));
}

View File

@ -541,11 +541,12 @@ Compatibility-displayorder: 50
Compatibility-expert: true
Compatibility-interface: org.apache.openjpa.conf.Compatibility
RuntimeClassOptimization-name: Runtime class optimization
RuntimeClassOptimization-desc: Either "true" or "false".
RuntimeClassOptimization-type: General
RuntimeClassOptimization-cat: Optimization
RuntimeClassOptimization-displayorder: 50
RuntimeUnenhancedClasses-name: Runtime unenhanced classes
RuntimeUnenhancedClasses-desc: Either "supported", "unsupported", or "warn". \
Defaults to "supported".
RuntimeUnenhancedClasses-type: General
RuntimeUnenhancedClasses-cat: Optimization
RuntimeUnenhancedClasses-displayorder: 50
no-named-cf: use a DataSource bound to JNDI
diff-specs: Attempt to configure for multiple specifications. Was configured \

View File

@ -29,7 +29,7 @@ public class TestEnhancementConfiguration
public void testEnhancementConfiguration() {
try {
emf = createEMF(
"openjpa.RuntimeClassOptimization", "false",
"openjpa.RuntimeUnenhancedClasses", "unsupported",
UnenhancedFieldAccess.class, CLEAR_TABLES);
assertFalse(ImplHelper.isManagedType(emf.getConfiguration(),
UnenhancedFieldAccess.class));
@ -38,7 +38,8 @@ public class TestEnhancementConfiguration
"that depends on unenhanced types but disables runtime" +
"redefinition.");
} catch (Exception e) {
// expected
assertTrue(e.getMessage().contains(
"This configuration disallows runtime optimization"));
}
}
}