You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2014/10/06 09:26:04 UTC
svn commit: r1629582 - in
/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb:
assembler/classic/ bval/
Author: rmannibucau
Date: Mon Oct 6 07:26:04 2014
New Revision: 1629582
URL: http://svn.apache.org/r1629582
Log:
TOMEE-1381 passing good ValidatorFactory property to JPA
Added:
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidatorFactory.java
Modified:
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidator.java
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java
tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java
Modified: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1629582&r1=1629581&r2=1629582&view=diff
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Mon Oct 6 07:26:04 2014
@@ -36,16 +36,13 @@ import org.apache.openejb.Injection;
import org.apache.openejb.JndiConstants;
import org.apache.openejb.MethodContext;
import org.apache.openejb.NoSuchApplicationException;
-import org.apache.openejb.OpenEJB;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.OpenEJBRuntimeException;
import org.apache.openejb.UndeployException;
-import org.apache.openejb.api.DestroyableResource;
import org.apache.openejb.assembler.classic.event.AssemblerAfterApplicationCreated;
import org.apache.openejb.assembler.classic.event.AssemblerBeforeApplicationDestroyed;
import org.apache.openejb.assembler.classic.event.AssemblerCreated;
import org.apache.openejb.assembler.classic.event.AssemblerDestroyed;
-import org.apache.openejb.assembler.classic.event.BeanContextsInitializedEvent;
import org.apache.openejb.assembler.classic.event.ContainerSystemPostCreate;
import org.apache.openejb.assembler.classic.event.ContainerSystemPreDestroy;
import org.apache.openejb.assembler.monitoring.JMXContainer;
@@ -95,7 +92,6 @@ import org.apache.openejb.jpa.integratio
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.JarLocation;
import org.apache.openejb.loader.Options;
-import org.apache.openejb.loader.ProvisioningUtil;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.monitoring.DynamicMBeanWrapper;
import org.apache.openejb.monitoring.LocalMBeanServer;
@@ -227,7 +223,8 @@ public class Assembler extends Assembler
public static final String TIMER_STORE_CLASS = "timerStore.class";
private static final ReentrantLock lock = new ReentrantLock(true);
public static final String OPENEJB_TIMERS_ON = "openejb.timers.on";
-
+ public static final Class<?>[] VALIDATOR_FACTORY_INTERFACES = new Class<?>[]{ValidatorFactory.class};
+ public static final Class<?>[] VALIDATOR_INTERFACES = new Class<?>[]{Validator.class};
private final boolean skipLoaderIfPossible;
Messages messages = new Messages(Assembler.class.getPackage().getName());
@@ -325,8 +322,6 @@ public class Assembler extends Assembler
final Collection<URL> urls = NewLoaderLogic.applyBuiltinExcludes(new UrlSet(Assembler.class.getClassLoader()).excludeJvm()).getUrls();
Extensions.installExtensions(new ResourceFinder("META-INF", urls.toArray(new URL[urls.size()])));
return;
- } catch (final MalformedURLException e) {
- // no-op
} catch (final IOException e) {
// no-op
}
@@ -475,8 +470,9 @@ public class Assembler extends Assembler
*/
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public void buildContainerSystem(final OpenEjbConfiguration configInfo) throws Exception {
- if (SystemInstance.get().getOptions().get(OPENEJB_JPA_DEPLOY_TIME_ENHANCEMENT_PROP, false)) {
- SystemInstance.get().addObserver(new DeployTimeEnhancer());
+ final SystemInstance systemInstance = SystemInstance.get();
+ if (systemInstance.getOptions().get(OPENEJB_JPA_DEPLOY_TIME_ENHANCEMENT_PROP, false)) {
+ systemInstance.addObserver(new DeployTimeEnhancer());
}
for (final ServiceInfo serviceInfo : configInfo.facilities.services) {
@@ -517,14 +513,14 @@ public class Assembler extends Assembler
} catch (final Throwable e) {
logger.error("appNotDeployed", e, appInfo.path);
- final DeploymentExceptionManager exceptionManager = SystemInstance.get().getComponent(DeploymentExceptionManager.class);
+ final DeploymentExceptionManager exceptionManager = systemInstance.getComponent(DeploymentExceptionManager.class);
if (exceptionManager != null && e instanceof Exception) {
exceptionManager.saveDeploymentException(appInfo, (Exception) e);
}
}
}
- SystemInstance.get().fireEvent(new ContainerSystemPostCreate());
+ systemInstance.fireEvent(new ContainerSystemPostCreate());
}
private void createJavaGlobal() {
@@ -535,10 +531,6 @@ public class Assembler extends Assembler
}
}
- public boolean isDeployed(final String path) {
- return deployedApplications.containsKey(ProvisioningUtil.realLocation(path));
- }
-
public Collection<AppInfo> getDeployedApplications() {
return new ArrayList<AppInfo>(deployedApplications.values());
}
@@ -623,7 +615,7 @@ public class Assembler extends Assembler
return createApplication(appInfo, classLoader, true);
}
- public AppContext createApplication(final AppInfo appInfo, ClassLoader classLoader, final boolean start) throws OpenEJBException, IOException, NamingException {
+ private AppContext createApplication(final AppInfo appInfo, ClassLoader classLoader, final boolean start) throws OpenEJBException, IOException, NamingException {
// The path is used in the UrlCache, command line deployer, JNDI name templates, tomcat integration and a few other places
if (appInfo.appId == null) {
throw new IllegalArgumentException("AppInfo.appId cannot be null");
@@ -636,13 +628,6 @@ public class Assembler extends Assembler
logger.info("createApplication.start", appInfo.path);
- // try {
- // Thread.sleep(5000);
- // } catch (InterruptedException e) {
- // e.printStackTrace();
- // Thread.interrupted();
- // }
-
// To start out, ensure we don't already have any beans deployed with duplicate IDs. This
// is a conflict we can't handle.
final List<String> used = new ArrayList<String>();
@@ -698,23 +683,41 @@ public class Assembler extends Assembler
final Context containerSystemContext = containerSystem.getJNDIContext();
- if (!SystemInstance.get().hasProperty("openejb.geronimo")) {
+ final Map<String, LazyValidatorFactory> lazyValidatorFactories = new HashMap<String, LazyValidatorFactory>();
+ final Map<String, LazyValidator> lazyValidators = new HashMap<String, LazyValidator>();
+ final boolean isGeronimo = SystemInstance.get().hasProperty("openejb.geronimo");
+
+ // try to not create N times the same validator for a single app
+ final Map<ComparableValidationConfig, ValidatorFactory> validatorFactoriesByConfig = new HashMap<ComparableValidationConfig, ValidatorFactory>();
+ if (!isGeronimo) {
// Bean Validation
// ValidatorFactory needs to be put in the map sent to the entity manager factory
// so it has to be constructed before
final List<CommonInfoObject> vfs = listCommonInfoObjectsForAppInfo(appInfo);
-
final Map<String, ValidatorFactory> validatorFactories = new HashMap<String, ValidatorFactory>();
+
for (final CommonInfoObject info : vfs) {
- ValidatorFactory factory = null;
- try {
- factory = ValidatorBuilder.buildFactory(classLoader, info.validationInfo);
- } catch (final ValidationException ve) {
- logger.warning("can't build the validation factory for module " + info.uniqueId, ve);
- }
- if (factory != null) {
- validatorFactories.put(info.uniqueId, factory);
+ final ComparableValidationConfig conf = new ComparableValidationConfig(
+ info.validationInfo.providerClassName, info.validationInfo.messageInterpolatorClass,
+ info.validationInfo.traversableResolverClass, info.validationInfo.constraintFactoryClass,
+ info.validationInfo.propertyTypes, info.validationInfo.constraintMappings
+ );
+ ValidatorFactory factory = validatorFactoriesByConfig.get(conf);
+ if (factory == null) {
+ try { // lazy cause of CDI :(
+ final LazyValidatorFactory handler = new LazyValidatorFactory(classLoader, info.validationInfo);
+ factory = (ValidatorFactory) Proxy.newProxyInstance(
+ appContext.getClassLoader(), VALIDATOR_FACTORY_INTERFACES, handler);
+ lazyValidatorFactories.put(info.uniqueId, handler);
+ } catch (final ValidationException ve) {
+ logger.warning("can't build the validation factory for module " + info.uniqueId, ve);
+ continue;
+ }
+ validatorFactoriesByConfig.put(conf, factory);
+ } else {
+ lazyValidatorFactories.put(info.uniqueId, LazyValidatorFactory.class.cast(Proxy.getInvocationHandler(factory)));
}
+ validatorFactories.put(info.uniqueId, factory);
}
// validators bindings
@@ -726,9 +729,12 @@ public class Assembler extends Assembler
Validator validator;
try {
- validator = factory.usingContext().getValidator();
+ final LazyValidator lazyValidator = new LazyValidator(factory);
+ validator = (Validator) Proxy.newProxyInstance(appContext.getClassLoader(), VALIDATOR_INTERFACES, lazyValidator);
+ lazyValidators.put(id, lazyValidator);
} catch (final Exception e) {
- validator = (Validator) Proxy.newProxyInstance(appContext.getClassLoader(), new Class<?>[]{Validator.class}, new LazyValidator(factory));
+ logger.error(e.getMessage(), e);
+ continue;
}
containerSystemContext.bind(VALIDATOR_NAMING_CONTEXT + id, validator);
@@ -738,6 +744,8 @@ public class Assembler extends Assembler
throw new OpenEJBException(e);
}
}
+
+ validatorFactories.clear();
}
// JPA - Persistence Units MUST be processed first since they will add ClassFileTransformers
@@ -747,7 +755,7 @@ public class Assembler extends Assembler
for (final PersistenceUnitInfo info : appInfo.persistenceUnits) {
final ReloadableEntityManagerFactory factory;
try {
- factory = persistenceBuilder.createEntityManagerFactory(info, classLoader);
+ factory = persistenceBuilder.createEntityManagerFactory(info, classLoader, validatorFactoriesByConfig);
containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT + info.id, factory);
units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT + info.id);
} catch (final NameAlreadyBoundException e) {
@@ -800,9 +808,31 @@ public class Assembler extends Assembler
appContext.getBindings().put("app/BeanManager", appContext.getBeanManager());
}
- // before starting everything, give the user the opportunity to hack on the AppContext/BeanContext
- final SystemInstance systemInstance = SystemInstance.get();
- systemInstance.fireEvent(new BeanContextsInitializedEvent(appInfo, appContext, allDeployments));
+ // now cdi is started we can try to bind real validator factory and validator
+ if (!isGeronimo) {
+ for (final Entry<String, LazyValidator> lazyValidator : lazyValidators.entrySet()) {
+ final String id = lazyValidator.getKey();
+ final ValidatorFactory factory = lazyValidatorFactories.get(lazyValidator.getKey()).getFactory();
+ try {
+ final String factoryName = VALIDATOR_FACTORY_NAMING_CONTEXT + id;
+ containerSystemContext.unbind(factoryName);
+ containerSystemContext.bind(factoryName, factory);
+
+ final String validatoryName = VALIDATOR_NAMING_CONTEXT + id;
+ try { // do it after factory cause of TCKs which expects validator to be created later
+ final Validator val = lazyValidator.getValue().getValidator();
+ containerSystemContext.unbind(validatoryName);
+ containerSystemContext.bind(validatoryName, val);
+ } catch (final Exception e) {
+ logger.error(e.getMessage(), e);
+ }
+ } catch (final NameAlreadyBoundException e) {
+ throw new OpenEJBException("ValidatorFactory already exists for module " + id, e);
+ } catch (final Exception e) {
+ throw new OpenEJBException(e);
+ }
+ }
+ }
startEjbs(start, allDeployments);
@@ -849,6 +879,7 @@ public class Assembler extends Assembler
}
// WebApp
+ final SystemInstance systemInstance = SystemInstance.get();
final WebAppBuilder webAppBuilder = systemInstance.getComponent(WebAppBuilder.class);
if (webAppBuilder != null) {
@@ -1245,7 +1276,7 @@ public class Assembler extends Assembler
}else{
if(null == appContext.getWebBeansContext()){
appContext.setWebBeansContext(webBeansContext);
- }
+ }
return;
}
@@ -1272,9 +1303,9 @@ public class Assembler extends Assembler
appContext.setCdiEnabled(false);
OpenEJBTransactionService.class.cast(services.get(TransactionService.class)).setWebBeansContext(webBeansContext);
- appContext.set(WebBeansContext.class, webBeansContext);
- appContext.setWebBeansContext(webBeansContext);
- }
+ appContext.set(WebBeansContext.class, webBeansContext);
+ appContext.setWebBeansContext(webBeansContext);
+ }
}
private TransactionPolicyFactory createTransactionPolicyFactory(final EjbJarInfo ejbJar, final ClassLoader classLoader) {
@@ -1494,12 +1525,6 @@ public class Assembler extends Assembler
} catch (final Exception e) {
logger.debug("Not processing resource on destroy: " + className, e);
}
- } else if (DestroyableResource.class.isInstance(object)) {
- try {
- DestroyableResource.class.cast(object).destroyResource();
- } catch (final RuntimeException e) {
- logger.error(e.getMessage(), e);
- }
} else if (logger.isDebugEnabled() && !DataSource.class.isInstance(object)) {
logger.debug("Not processing resource on destroy: " + className);
}
@@ -1917,11 +1942,7 @@ public class Assembler extends Assembler
jars.addAll(Arrays.asList(SystemInstance.get().getComponent(ClassLoaderEnricher.class).applicationEnrichment()));
// Create the class loader
- final ParentClassLoaderFinder parentFinder = SystemInstance.get().getComponent(ParentClassLoaderFinder.class);
- ClassLoader parent = OpenEJB.class.getClassLoader();
- if (parentFinder != null) {
- parent = parentFinder.getParentClassLoader(parent);
- }
+ final ClassLoader parent = ParentClassLoaderFinder.Helper.get();
final String prefix;
if (appInfo.webAppAlone) {
@@ -1943,7 +1964,11 @@ public class Assembler extends Assembler
// try to get the app BM from the AppClassLoader having stored it in a map).
// since we don't really need to create a classloader here when starting from classpath just let skip this step
if (skipLoaderIfPossible) { // TODO: maybe use a boolean to know if all urls comes from the classpath to avoid this validation
- final Collection<File> urls = new ArrayList<File>();
+ if ("classpath.ear".equals(appInfo.appId)) {
+ return parent;
+ }
+
+ final Collection<File> urls = new HashSet<File>();
for (final URL url : ClassLoaders.findUrls(parent)) { // need to convert it to file since urls can be file:/xxx or jar:file:///xxx
try {
urls.add(URLs.toFile(url).getCanonicalFile());
@@ -1959,24 +1984,38 @@ public class Assembler extends Assembler
try {
if (!urls.contains(URLs.toFile(url).getCanonicalFile())) {
allIsIntheClasspath = false;
+ if (logger.isDebugEnabled()) {
+ logger.debug(url.toExternalForm() + " (" + URLs.toFile(url)
+ + ") is not in the classloader so we'll create a dedicated classloader for this app");
+ }
break;
}
} catch (final Exception ignored) {
allIsIntheClasspath = false;
+ if (logger.isDebugEnabled()) {
+ logger.debug(url.toExternalForm() + " (" + URLs.toFile(url) + ") is not in the classloader", ignored);
+ }
break;
}
}
if (allIsIntheClasspath) {
+ logger.info("Not creating another application classloader for " + appInfo.appId);
return parent;
} else if (logger.isDebugEnabled()) {
logger.debug("Logging all urls from the app since we don't skip the app classloader creation:");
for (final URL url : filtered) {
logger.debug(" -> " + url.toExternalForm());
}
+ logger.debug("Logging all urls from the classloader since we don't skip the app classloader creation:");
+ for (final File url : urls) {
+ logger.debug(" -> " + url.getAbsolutePath());
+ }
}
}
+ logger.info("Creating dedicated application classloader for " + appInfo.appId);
+
if (!appInfo.delegateFirst) {
return ClassLoaderUtil.createClassLoader(appInfo.path, filtered, parent);
}
@@ -2048,7 +2087,7 @@ public class Assembler extends Assembler
containerObjectNames.add(objectName);
} catch (final Exception e) {
// no-op
- } catch (final NoClassDefFoundError ncdfe) { // OSGi
+ } catch (final NoClassDefFoundError ncdfe) {
// no-op
}
}
Added: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java?rev=1629582&view=auto
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java (added)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java Mon Oct 6 07:26:04 2014
@@ -0,0 +1,81 @@
+/*
+ * 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.openejb.assembler.classic;
+
+import java.util.List;
+import java.util.Properties;
+
+public class ComparableValidationConfig {
+ private final String providerClassName;
+ private final String messageInterpolatorClass;
+ private final String traversableResolverClass;
+ private final String constraintFactoryClass;
+ private final Properties propertyTypes;
+ private final List<String> constraintMappings;
+
+ private final int hash;
+
+ public ComparableValidationConfig(final String providerClassName, final String messageInterpolatorClass,
+ final String traversableResolverClass, final String constraintFactoryClass,
+ final Properties propertyTypes, final List<String> constraintMappings) {
+ this.providerClassName = providerClassName;
+ this.messageInterpolatorClass = messageInterpolatorClass;
+ this.traversableResolverClass = traversableResolverClass;
+ this.constraintFactoryClass = constraintFactoryClass;
+ this.propertyTypes = propertyTypes;
+ this.constraintMappings = constraintMappings;
+
+ int result = providerClassName != null ? providerClassName.hashCode() : 0;
+ result = 31 * result + (messageInterpolatorClass != null ? messageInterpolatorClass.hashCode() : 0);
+ result = 31 * result + (traversableResolverClass != null ? traversableResolverClass.hashCode() : 0);
+ result = 31 * result + (constraintFactoryClass != null ? constraintFactoryClass.hashCode() : 0);
+ result = 31 * result + (propertyTypes != null ? propertyTypes.hashCode() : 0);
+ result = 31 * result + (constraintMappings != null ? constraintMappings.hashCode() : 0);
+ hash = result;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final ComparableValidationConfig that = (ComparableValidationConfig) o;
+
+ if (constraintFactoryClass != null ? !constraintFactoryClass.equals(that.constraintFactoryClass) : that.constraintFactoryClass != null)
+ return false;
+ if (constraintMappings != null ? !constraintMappings.equals(that.constraintMappings) : that.constraintMappings != null)
+ return false;
+ if (messageInterpolatorClass != null ? !messageInterpolatorClass.equals(that.messageInterpolatorClass) : that.messageInterpolatorClass != null)
+ return false;
+ if (propertyTypes != null ? !propertyTypes.equals(that.propertyTypes) : that.propertyTypes != null)
+ return false;
+ if (providerClassName != null ? !providerClassName.equals(that.providerClassName) : that.providerClassName != null)
+ return false;
+ if (traversableResolverClass != null ? !traversableResolverClass.equals(that.traversableResolverClass) : that.traversableResolverClass != null)
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+}
Modified: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java?rev=1629582&r1=1629581&r2=1629582&view=diff
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java (original)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java Mon Oct 6 07:26:04 2014
@@ -23,6 +23,7 @@ import org.apache.openejb.persistence.Pe
import javax.persistence.EntityManagerFactory;
import javax.persistence.ValidationMode;
import javax.persistence.spi.PersistenceProvider;
+import javax.validation.ValidatorFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
@@ -33,12 +34,15 @@ public class EntityManagerFactoryCallabl
private final String persistenceProviderClassName;
private final PersistenceUnitInfoImpl unitInfo;
+ private final Map<ComparableValidationConfig, ValidatorFactory> potentialValidators;
private ClassLoader appClassLoader;
- public EntityManagerFactoryCallable(final String persistenceProviderClassName, final PersistenceUnitInfoImpl unitInfo, final ClassLoader cl) {
+ public EntityManagerFactoryCallable(final String persistenceProviderClassName, final PersistenceUnitInfoImpl unitInfo,
+ final ClassLoader cl, final Map<ComparableValidationConfig, ValidatorFactory> validators) {
this.persistenceProviderClassName = persistenceProviderClassName;
this.unitInfo = unitInfo;
this.appClassLoader = cl;
+ this.potentialValidators = validators;
}
@Override
@@ -52,7 +56,7 @@ public class EntityManagerFactoryCallabl
// Create entity manager factories with the validator factory
final Map<String, Object> properties = new HashMap<String, Object>();
if (!ValidationMode.NONE.equals(unitInfo.getValidationMode())) {
- properties.put("javax.persistence.validator.ValidatorFactory", new ValidatorFactoryWrapper());
+ properties.put("javax.persistence.validation.factory", new ValidatorFactoryWrapper(potentialValidators));
}
customizeProperties(properties);
@@ -60,8 +64,8 @@ public class EntityManagerFactoryCallabl
final EntityManagerFactory emf = persistenceProvider.createContainerEntityManagerFactory(unitInfo, properties);
if (unitInfo.getProperties() != null
- && "true".equalsIgnoreCase(unitInfo.getProperties().getProperty(OPENEJB_JPA_INIT_ENTITYMANAGER))
- || SystemInstance.get().getOptions().get(OPENEJB_JPA_INIT_ENTITYMANAGER, false)) {
+ && "true".equalsIgnoreCase(unitInfo.getProperties().getProperty(OPENEJB_JPA_INIT_ENTITYMANAGER))
+ || SystemInstance.get().getOptions().get(OPENEJB_JPA_INIT_ENTITYMANAGER, false)) {
emf.createEntityManager().close();
}
@@ -79,6 +83,7 @@ public class EntityManagerFactoryCallabl
}
}
+ // properties that have to be passed to properties parameters and not unit properties
private void customizeProperties(final Map<String, Object> properties) {
final String pool = SystemInstance.get().getProperty(OPENJPA_ENTITY_MANAGER_FACTORY_POOL);
if (pool != null) {
Modified: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidator.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidator.java?rev=1629582&r1=1629581&r2=1629582&view=diff
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidator.java (original)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidator.java Mon Oct 6 07:26:04 2014
@@ -20,6 +20,7 @@ package org.apache.openejb.assembler.cla
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.locks.ReentrantLock;
@@ -35,7 +36,15 @@ public class LazyValidator implements In
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ ensureDelegate();
+ try {
+ return method.invoke(validator, args);
+ } catch (final InvocationTargetException ite) {
+ throw ite.getCause();
+ }
+ }
+ private void ensureDelegate() {
if (validator == null) {
final ReentrantLock l = lock;
@@ -49,7 +58,10 @@ public class LazyValidator implements In
l.unlock();
}
}
+ }
- return method.invoke(validator, args);
+ public Validator getValidator() {
+ ensureDelegate();
+ return validator;
}
}
Added: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidatorFactory.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidatorFactory.java?rev=1629582&view=auto
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidatorFactory.java (added)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/LazyValidatorFactory.java Mon Oct 6 07:26:04 2014
@@ -0,0 +1,65 @@
+/*
+ * 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.openejb.assembler.classic;
+
+import javax.validation.ValidatorFactory;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantLock;
+
+// TODO: make it generic (LazyDelegate + Factory + refactor LazyValidator)
+public class LazyValidatorFactory implements InvocationHandler {
+ private final ReentrantLock lock = new ReentrantLock();
+ private final ClassLoader loader;
+ private final ValidationInfo info;
+ private volatile ValidatorFactory factory;
+
+ public LazyValidatorFactory(final ClassLoader classLoader, final ValidationInfo validationInfo) {
+ this.loader = classLoader;
+ this.info = validationInfo;
+ }
+
+ @Override
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ ensureDelegate();
+ try {
+ return method.invoke(factory, args);
+ } catch (final InvocationTargetException ite) {
+ throw ite.getCause();
+ }
+ }
+
+ private void ensureDelegate() {
+ if (factory == null) {
+ final ReentrantLock l = lock;
+ l.lock();
+ try {
+ if (factory == null) {
+ factory = ValidatorBuilder.buildFactory(loader, info);
+ }
+ } finally {
+ l.unlock();
+ }
+ }
+ }
+
+ public ValidatorFactory getFactory() {
+ ensureDelegate();
+ return factory;
+ }
+}
Modified: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java?rev=1629582&r1=1629581&r2=1629582&view=diff
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java (original)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java Mon Oct 6 07:26:04 2014
@@ -32,6 +32,8 @@ import javax.persistence.SharedCacheMode
import javax.persistence.ValidationMode;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
+import javax.validation.ValidatorFactory;
+import java.util.Map;
public class PersistenceBuilder {
@@ -46,7 +48,8 @@ public class PersistenceBuilder {
this.persistenceClassLoaderHandler = persistenceClassLoaderHandler;
}
- public ReloadableEntityManagerFactory createEntityManagerFactory(final PersistenceUnitInfo info, final ClassLoader classLoader) throws Exception {
+ public ReloadableEntityManagerFactory createEntityManagerFactory(final PersistenceUnitInfo info, final ClassLoader classLoader,
+ final Map<ComparableValidationConfig, ValidatorFactory> validators) throws Exception {
final PersistenceUnitInfoImpl unitInfo = new PersistenceUnitInfoImpl(persistenceClassLoaderHandler);
// Persistence Unit Id
@@ -147,7 +150,7 @@ public class PersistenceBuilder {
final String persistenceProviderClassName = unitInfo.getPersistenceProviderClassName();
unitInfo.setPersistenceProviderClassName(persistenceProviderClassName);
- final EntityManagerFactoryCallable callable = new EntityManagerFactoryCallable(persistenceProviderClassName, unitInfo, classLoader);
+ final EntityManagerFactoryCallable callable = new EntityManagerFactoryCallable(persistenceProviderClassName, unitInfo, classLoader, validators);
return new ReloadableEntityManagerFactory(classLoader, callable, unitInfo);
}
Modified: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java?rev=1629582&r1=1629581&r2=1629582&view=diff
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java (original)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java Mon Oct 6 07:26:04 2014
@@ -21,6 +21,7 @@ import org.apache.openejb.bval.Validator
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
+import javax.naming.NamingException;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
@@ -28,12 +29,26 @@ import javax.validation.Validator;
import javax.validation.ValidatorContext;
import javax.validation.ValidatorFactory;
import java.io.Serializable;
+import java.util.Map;
public class ValidatorFactoryWrapper implements ValidatorFactory, Serializable {
public static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, ValidatorFactoryWrapper.class);
- private static ValidatorFactory factory() {
- return ValidatorUtil.validatorFactory();
+ private final Map<ComparableValidationConfig, ValidatorFactory> fallbackValidators;
+
+ private ValidatorFactory factory() {
+ try {
+ return ValidatorUtil.lookupFactory();
+ } catch (final NamingException e) { // in absolute we should sort them to get the closest one of the persistence-unit?
+ if (!fallbackValidators.isEmpty()) {
+ return fallbackValidators.values().iterator().next();
+ }
+ return ValidatorUtil.tryJndiLaterFactory();
+ }
+ }
+
+ public ValidatorFactoryWrapper(final Map<ComparableValidationConfig, ValidatorFactory> validators) {
+ fallbackValidators = validators;
}
@Override
Modified: tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java
URL: http://svn.apache.org/viewvc/tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java?rev=1629582&r1=1629581&r2=1629582&view=diff
==============================================================================
--- tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java (original)
+++ tomee/tomee/branches/tomee-1.7.x/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java Mon Oct 6 07:26:04 2014
@@ -43,12 +43,20 @@ public final class ValidatorUtil {
public static ValidatorFactory validatorFactory() {
try {
- return (ValidatorFactory) new InitialContext().lookup("java:comp/ValidatorFactory");
+ return lookupFactory();
} catch (final NamingException e) {
- return proxy(ValidatorFactory.class, "java:comp/ValidatorFactory");
+ return tryJndiLaterFactory();
}
}
+ public static ValidatorFactory lookupFactory() throws NamingException {
+ return (ValidatorFactory) new InitialContext().lookup("java:comp/ValidatorFactory");
+ }
+
+ public static ValidatorFactory tryJndiLaterFactory() {
+ return proxy(ValidatorFactory.class, "java:comp/ValidatorFactory");
+ }
+
public static Validator validator() {
try {
return (Validator) new InitialContext().lookup("java:comp/Validator");
@@ -113,7 +121,9 @@ public final class ValidatorUtil {
}
}
}
- break;
+ if (ClassLoader.getSystemClassLoader() != appContextClassLoader) {
+ break;
+ } // else we surely have a single AppContext so let's try WebContext
}
for (final WebContext web : appContext.getWebContexts()) {
final ClassLoader webClassLoader = web.getClassLoader();