public void enhance(@Observes final BeforeDeploymentEvent event) { if (enhancerMethod == null) { LOGGER.debug("OpenJPA is not available so no deploy-time enhancement will be done"); return; } // find persistence.xml final Map<String, List<String>> classesByPXml = new HashMap<String, List<String>>(); final List<URL> usedUrls = new ArrayList<URL>(); // for fake classloader for (URL url : event.getUrls()) { final File file = URLs.toFile(url); if (file.isDirectory()) { final String pXmls = getWarPersistenceXml(url); if (pXmls != null) { feed(classesByPXml, pXmls); } usedUrls.add(url); } else if (file.getName().endsWith(".jar")) { try { final JarFile jar = new JarFile(file); ZipEntry entry = jar.getEntry(META_INF_PERSISTENCE_XML); if (entry != null) { final String path = file.getAbsolutePath(); final File unpacked = new File(path.substring(0, path.length() - 4) + TMP_ENHANCEMENT_SUFFIX); JarExtractor.extract(file, unpacked); // replace jar by folder url since otherwise enhancement doesn't work usedUrls.add(unpacked.toURI().toURL()); feed(classesByPXml, new File(unpacked, META_INF_PERSISTENCE_XML).getAbsolutePath()); } } catch (IOException e) { // ignored } } else { usedUrls.add(url); } } // enhancement final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); final ClassLoader fakeClassLoader = new URLClassLoaderFirst( usedUrls.toArray(new URL[usedUrls.size()]), event.getParentClassLoader()); Thread.currentThread().setContextClassLoader(fakeClassLoader); try { for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) { final Properties opts = new Properties(); opts.setProperty(PROPERTIES_FILE_PROP, entry.getKey()); final Object optsArg; try { optsArg = optionsConstructor.newInstance(opts); } catch (Exception e) { LOGGER.debug("can't create options for enhancing"); return; } LOGGER.info("enhancing url(s): " + Arrays.asList(event.getUrls())); try { enhancerMethod.invoke(null, toFilePaths(entry.getValue()), optsArg); } catch (Exception e) { LOGGER.warning("can't enhanced at deploy-time entities", e); } } } finally { Thread.currentThread().setContextClassLoader(tccl); usedUrls.clear(); } // clean up extracted jars and replace jar to keep consistent classloading for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) { final List<String> values = entry.getValue(); for (String rawPath : values) { if (rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX + "/") || rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX)) { final File dir = new File(rawPath); final File file = new File( rawPath.substring(0, rawPath.length() - TMP_ENHANCEMENT_SUFFIX.length() - 1) + ".jar"); if (file.exists()) { String name = dir.getName(); name = name.substring(0, name.length() - TMP_ENHANCEMENT_SUFFIX.length()) + ".jar"; final File target = new File(dir.getParentFile(), name); try { // override existing jar otherwise classloading is broken in tomee Files.delete(file); JarCreator.jarDir(dir, target); } catch (final IOException e) { LOGGER.error("can't repackage enhanced jar file " + file.getName()); } Files.delete(dir); } } } values.clear(); } classesByPXml.clear(); }