From 0e055fb013c5713be573c5088c18320dc16764d4 Mon Sep 17 00:00:00 2001 From: Michael Dick Date: Mon, 22 Jun 2009 19:16:19 +0000 Subject: [PATCH] OPENJPA-1119 committing patch from Rick Curtis. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@787359 13f79535-47bb-0310-9956-ffa450edef68 --- .../enhance/InstrumentationFactory.java | 85 ++++++++++++++----- openjpa-persistence-jdbc/pom.xml | 8 ++ 2 files changed, 74 insertions(+), 19 deletions(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/InstrumentationFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/InstrumentationFactory.java index 633070622..37b9983f8 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/InstrumentationFactory.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/InstrumentationFactory.java @@ -29,7 +29,11 @@ import java.lang.management.RuntimeMXBean; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessController; +import java.security.CodeSource; import java.security.PrivilegedAction; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -193,30 +197,37 @@ public class InstrumentationFactory { * point to the OpenJPA jar. If running in a development environment a * temporary jar file will be created. * - * @return absolute path to the agent jar. - * @throws Exception - * if this method is unable to detect where this class was - * loaded from. It is unknown if this is actually possible. + * @return absolute path to the agent jar or null if anything unexpected + * happens. */ private static String getAgentJar(Log log) { - // Find the name of the jar that this class was loaded from. That + File agentJarFile = null; + // Find the name of the File that this class was loaded from. That // jar *should* be the same location as our agent. - File agentJarFile = - new File(InstrumentationFactory.class.getProtectionDomain() - .getCodeSource().getLocation().getFile()); - // We're deadmeat if we can't find a file that this class - // was loaded from. Just return if this file doesn't exist. - // Note: I'm not sure if this can really happen. - if (agentJarFile.exists() == false) { - if (log.isTraceEnabled() == true) { - log.trace(_name + ".getAgentJar() -- Couldn't find where this " - + "class was loaded from!"); + CodeSource cs = + InstrumentationFactory.class.getProtectionDomain().getCodeSource(); + if (cs != null) { + URL loc = cs.getLocation(); + if(loc!=null){ + agentJarFile = new File(loc.getFile()); } } + + // Determine whether the File that this class was loaded from has this + // class defined as the Agent-Class. + boolean createJar = false; + if (cs == null || agentJarFile == null + || agentJarFile.isDirectory() == true) { + createJar = true; + }else if(validateAgentJarManifest(agentJarFile, log, _name) == false){ + // We have an agentJarFile, but this class isn't the Agent-Class. + createJar=true; + } + String agentJar; - if (agentJarFile.isDirectory() == true) { - // This will happen when running in eclipse as an OpenJPA - // developer. No one else should ever go down this path. We + if (createJar == true) { + // This can happen when running in eclipse as an OpenJPA + // developer or for some reason the CodeSource is null. We // should log a warning here because this will create a jar // in your temp directory that doesn't always get cleaned up. try { @@ -236,7 +247,7 @@ public class InstrumentationFactory { } return agentJar; - } + }//end getAgentJar /** * Attach and load an agent class. @@ -304,4 +315,40 @@ public class InstrumentationFactory { } return null; } + + /** + * This private worker method will validate that the provided agentClassName + * is defined as the Agent-Class in the manifest file from the provided jar. + * + * @param agentJarFile + * non-null agent jar file. + * @param log + * non-null logger. + * @param agentClassName + * the non-null agent class name. + * @return True if the provided agentClassName is defined as the Agent-Class + * in the manifest from the provided agentJarFile. False otherwise. + */ + private static boolean validateAgentJarManifest(File agentJarFile, Log log, + String agentClassName) { + try { + JarFile jar = new JarFile(agentJarFile); + Manifest manifest = jar.getManifest(); + if (manifest == null) { + return false; + } + Attributes attributes = manifest.getMainAttributes(); + String ac = attributes.getValue("Agent-Class"); + if (ac != null && ac.equals(agentClassName)) { + return true; + } + } catch (Exception e) { + if (log.isTraceEnabled() == true) { + log.trace(_name + + ".validateAgentJarManifest() caught unexpected " + + "exception " + e.getMessage()); + } + } + return false; + }// end validateAgentJarManifest } diff --git a/openjpa-persistence-jdbc/pom.xml b/openjpa-persistence-jdbc/pom.xml index a06834f9e..e2ecde3ec 100644 --- a/openjpa-persistence-jdbc/pom.xml +++ b/openjpa-persistence-jdbc/pom.xml @@ -817,6 +817,14 @@ --> org/apache/openjpa/persistence/criteria/*.java + + + org/apache/openjpa/**/TestUnenhanced*.java + + + org/apache/openjpa/enhance/TestEnhancementConfiguration.java + org/apache/openjpa/enhance/TestRelationToUnlistedClass.java + org/apache/openjpa/kernel/TestDynamicClassRegistration.java