diff --git a/openjpa-persistence/pom.xml b/openjpa-persistence/pom.xml index 2c707e74b..12a7b7163 100644 --- a/openjpa-persistence/pom.xml +++ b/openjpa-persistence/pom.xml @@ -54,6 +54,32 @@ jdk5-compiler + + org.apache.maven.plugins + maven-surefire-plugin + + + ${basedir}/target/test-classes/second-persistence.jar + + + + + maven-antrun-plugin + + + test-compile + + + + + + + run + + + + org.apache.maven.plugins maven-compiler-plugin @@ -78,6 +104,32 @@ jdk6-compiler + + org.apache.maven.plugins + maven-surefire-plugin + + + ${basedir}/target/test-classes/second-persistence.jar + + + + + maven-antrun-plugin + + + test-compile + + + + + + + run + + + + org.apache.maven.plugins maven-antrun-plugin diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java index 3232f2f6a..c0d25d199 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java @@ -27,9 +27,12 @@ import java.security.PrivilegedActionException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.MissingResourceException; +import java.util.Set; import javax.persistence.spi.PersistenceUnitInfo; import javax.persistence.spi.PersistenceUnitTransactionType; @@ -82,6 +85,8 @@ public class PersistenceProductDerivation private static final Localizer _loc = Localizer.forPackage (PersistenceProductDerivation.class); + private HashMap _puNameCollisions + = new HashMap(); public void putBrokerFactoryAliases(Map m) { } @@ -266,15 +271,17 @@ public class PersistenceProductDerivation public List getAnchorsInResource(String resource) throws Exception { ConfigurationParser parser = new ConfigurationParser(null); try { + List results = new ArrayList(); ClassLoader loader = AccessController.doPrivileged( J2DoPrivHelper.getContextClassLoaderAction()); List urls = getResourceURLs(resource, loader); if (urls != null) { for (URL url : urls) { parser.parse(url); + results.addAll(getUnitNames(parser)); } } - return getUnitNames(parser); + return results; } catch (IOException e) { // not all configuration files are XML; return null if unparsable return null; @@ -318,6 +325,21 @@ public class PersistenceProductDerivation return null; } + /** + * This method checks to see if the provided puName was + * detected in multiple resources. If a collision is detected, a warning + * will be logged and this method will return true. + *

+ */ + public boolean checkPuNameCollisions(Log logger,String puName){ + PUNameCollision p = _puNameCollisions.get(puName); + if(p!=null){ + p.logCollision(logger); + return true; + } + return false; + } + private static List getResourceURLs(String rsrc, ClassLoader loader) throws IOException { Enumeration urls = null; @@ -407,11 +429,24 @@ public class PersistenceProductDerivation private PersistenceUnitInfoImpl findUnit(List pinfos, String name, ClassLoader loader) { PersistenceUnitInfoImpl ojpa = null; + PersistenceUnitInfoImpl result = null; for (PersistenceUnitInfoImpl pinfo : pinfos) { // found named unit? if (name != null) { - if (name.equals(pinfo.getPersistenceUnitName())) - return pinfo; + if (name.equals(pinfo.getPersistenceUnitName())){ + + if(result!=null){ + this.addPuNameCollision(name, + result.getPersistenceXmlFileUrl().toString(), + pinfo.getPersistenceXmlFileUrl().toString()); + + }else{ + // Grab a ref to the pinfo that matches the name we're + // looking for. Keep going to look for duplicate pu + // names. + result = pinfo; + } + } continue; } @@ -425,6 +460,9 @@ public class PersistenceProductDerivation ojpa = pinfo; } } + if(result!=null){ + return result; + } return ojpa; } @@ -469,6 +507,16 @@ public class PersistenceProductDerivation System.err.println(msg); } + private void addPuNameCollision(String puName, String file1, String file2){ + PUNameCollision pun = _puNameCollisions.get(puName); + if(pun!=null){ + pun.addCollision(file1, file2); + }else{ + _puNameCollisions.put(puName, + new PUNameCollision(puName, file1, file2)); + } + + } /** * Custom configuration provider. */ @@ -691,4 +739,32 @@ public class PersistenceProductDerivation _info.setPersistenceXmlFileUrl(_source); } } + /** + * This private class is used to hold onto information regarding + * PersistentUnit name collisions. + */ + private static class PUNameCollision{ + private String _puName; + private Set _resources; + + PUNameCollision(String puName, String file1, String file2) { + _resources = new LinkedHashSet(); + _resources.add(file1); + _resources.add(file2); + + _puName=puName; + } + void logCollision(Log logger){ + if(logger.isWarnEnabled()){ + logger.warn(_loc.getFatal("dup-pu", + new Object[]{_puName,_resources.toString(), + _resources.iterator().next()})); + } + } + void addCollision(String file1, String file2){ + _resources.add(file1); + _resources.add(file2); + } + + } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java index 0ecbaf01c..f8779914d 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java @@ -37,6 +37,7 @@ import org.apache.openjpa.kernel.BrokerFactory; import org.apache.openjpa.lib.conf.Configuration; import org.apache.openjpa.lib.conf.ConfigurationProvider; import org.apache.openjpa.lib.conf.Configurations; +import org.apache.openjpa.lib.conf.ProductDerivations; import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.meta.MetaDataModes; @@ -60,6 +61,7 @@ public class PersistenceProviderImpl private static final Localizer _loc = Localizer.forPackage( PersistenceProviderImpl.class); + private Log _log; /** * Loads the entity manager specified by name, applying * the properties in m as overrides to the properties defined @@ -80,6 +82,11 @@ public class PersistenceProviderImpl return null; BrokerFactory factory = getBrokerFactory(cp, poolValue, null); + _log = factory.getConfiguration() + .getLog(OpenJPAConfiguration.LOG_RUNTIME); + if(pd.checkPuNameCollisions(_log,name)==true){ + ;//return null; + } return JPAFacadeHelper.toEntityManagerFactory(factory); } catch (Exception e) { throw PersistenceExceptions.toPersistenceException(e); diff --git a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties index 41b43e9b8..19e34634f 100644 --- a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties +++ b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties @@ -179,6 +179,9 @@ unwrap-em-invalid: EntityManager can not be unwrapped to an instance of "{0}". unwrap-query-invalid: Query can not be unwrapped to an instance of "{0}". invalid_entity_argument: Object being locked must be an valid and not detached \ entity. +dup-pu: The persistence unit "{0}" was found multiple times in the following \ + resources "{1}", but persistence unit names should be unique. The first \ + persistence unit matching the provided name in "{2}" is being used. bad-lock-level: Invalid lock mode/level. Valid values are \ "none"(0), "read"(10), "optimistic"(15), "write"(20), \ "optimistic-force-increment"(25), \ diff --git a/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestPersistenceProductDerivation.java b/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestPersistenceProductDerivation.java new file mode 100644 index 000000000..42573a20d --- /dev/null +++ b/openjpa-persistence/src/test/java/org/apache/openjpa/persistence/TestPersistenceProductDerivation.java @@ -0,0 +1,43 @@ +/* + * 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.persistence; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.TestCase; + +public class TestPersistenceProductDerivation extends TestCase { + + /** + * Added for OPENJPA-932. Verifies a ppd properly loads pu's from multiple archives. + * + * @throws Exception + */ + public void testGetAnchorsInResource()throws Exception{ + + List expectedPUs = Arrays.asList( + new String[]{"pu_1","pu_2","pu_3"}); + + PersistenceProductDerivation ppd = new PersistenceProductDerivation(); + List actual = ppd.getAnchorsInResource("META-INF/persistence.xml"); + + assertEquals(expectedPUs, actual); + } +} diff --git a/openjpa-persistence/src/test/resources/META-INF/persistence.xml b/openjpa-persistence/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..334dd3f3e --- /dev/null +++ b/openjpa-persistence/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/openjpa-persistence/src/test/resources/second-persistence/META-INF/persistence.xml b/openjpa-persistence/src/test/resources/second-persistence/META-INF/persistence.xml new file mode 100644 index 000000000..a4623fe93 --- /dev/null +++ b/openjpa-persistence/src/test/resources/second-persistence/META-INF/persistence.xml @@ -0,0 +1,26 @@ + + + + + + +