diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..29fcbb0
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..335c27d
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ tomee-maven-demo
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.maven.ide.eclipse.maven2Nature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..fef2bd7
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+#Fri Jan 27 15:43:49 CET 2012
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000..6434337
--- /dev/null
+++ b/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,9 @@
+#Tue Jan 31 10:56:54 CET 2012
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=true
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/MessageService-soapui-project.xml b/MessageService-soapui-project.xml
new file mode 100644
index 0000000..24dfb5e
--- /dev/null
+++ b/MessageService-soapui-project.xml
@@ -0,0 +1,94 @@
+
+http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageService?wsdl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>http://schemas.xmlsoap.org/wsdl/http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageServiceUTF-8http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageService
+
+
+
+
+
+ ?
+ ?
+ ?
+
+
+
+]]>UTF-8http://localhost:8081/tomee-maven-demo-war-2.0.0/services/MessageService
+
+
+
+
+
+ Hello David
+
+
+
+]]>falseSEQUENCEResponse 1
\ No newline at end of file
diff --git a/ear/pom.xml b/ear/pom.xml
new file mode 100644
index 0000000..7437480
--- /dev/null
+++ b/ear/pom.xml
@@ -0,0 +1,105 @@
+
+
+
+ 4.0.0
+
+
+ be.dabla
+ tomee-maven-demo
+ 2.0.0
+
+
+ tomee-maven-demo-ear
+ ear
+ tomee-maven-demo-ear
+
+
+
+ be.dabla
+ tomee-maven-demo-war
+ ${project.version}
+ war
+
+
+ be.dabla
+ tomee-maven-demo-ejb
+ ${project.version}
+ ejb
+
+
+ be.dabla
+ tomee-maven-demo-jar
+ ${project.version}
+
+
+
+ javax.validation
+ validation-api
+ 1.0.0.GA
+
+
+ org.hibernate
+ hibernate-validator
+ 4.0.2.GA
+
+
+ org.slf4j
+ slf4j-api
+ 1.6.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-ear-plugin
+ 2.6
+
+ true
+ APP-INF/lib
+ tomee-maven-demo-ear
+ TomEE Maven Demo
+ 5
+
+
+ ${project.version}
+
+
+
+
+ be.dabla
+ tomee-maven-demo-war
+ tomee-maven-demo-context-root
+ web.xml
+
+
+ be.dabla
+ tomee-maven-demo-ejb
+
+
+ javax.activation
+ activation
+ true
+
+
+ javax.xml.bind
+ jaxb-api
+ true
+
+
+ com.sun.xml.bind
+ jaxb-impl
+ true
+
+
+ javax.xml.stream
+ stax-api
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ear/src/main/application/META-INF/weblogic-application.xml b/ear/src/main/application/META-INF/weblogic-application.xml
new file mode 100644
index 0000000..c3d876f
--- /dev/null
+++ b/ear/src/main/application/META-INF/weblogic-application.xml
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/ejb/pom.xml b/ejb/pom.xml
new file mode 100644
index 0000000..4266ced
--- /dev/null
+++ b/ejb/pom.xml
@@ -0,0 +1,235 @@
+
+
+
+ 4.0.0
+
+
+ be.dabla
+ tomee-maven-demo
+ 2.0.0
+
+
+ tomee-maven-demo-ejb
+ ejb
+ tomee-maven-demo-ejb
+
+
+
+ be.dabla
+ tomee-maven-demo-jar
+ ${project.version}
+ provided
+
+
+ org.eclipse.persistence
+ eclipselink
+ 1.1.0
+ provided
+
+
+ junit
+ junit
+ 4.8.2
+ test
+
+
+ org.apache.derby
+ derby
+ 10.4.2.0
+ test
+
+
+ org.dbunit
+ dbunit
+ 2.4.5
+ test
+
+
+ org.apache.activemq
+ activemq-core
+ 5.2.0
+ test
+
+
+ org.apache.openejb
+ openejb-cxf
+ 3.1.4
+ test
+
+
+ org.hibernate
+ hibernate-validator
+ 4.0.2.GA
+ test
+
+
+ org.slf4j
+ slf4j-api
+ 1.6.1
+ test
+
+
+ be.dabla
+ tomee-maven-demo-jar
+ ${project.version}
+ test
+ tests
+
+
+ javax.validation
+ validation-api
+ 1.0.0.GA
+ provided
+
+
+
+ javax.ejb
+ ejb-api
+ 3.0
+ provided
+
+
+ javaee
+ javaee-api
+ 5
+ provided
+
+
+
+
+
+
+ src/test/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-ejb-plugin
+ 2.3
+
+ 3.0
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ test-jar
+
+ test-jar
+
+
+
+ META-INF/*-jar.xml
+ jndi.properties
+ logging.properties
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ pertest
+ -javaagent:${basedir}/target/openejb-javaagent-3.1.4.jar
+ ${basedir}/target
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ process-resources
+
+ copy
+
+
+
+
+ org.apache.openejb
+ openejb-javaagent
+ 3.1.4
+ ${project.build.directory}
+
+
+ javax
+ javaee-endorsed-api
+ 6.0
+ jar
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+
+ process-test-resources
+
+ copy-resources
+
+
+ ${basedir}/target/test-classes/META-INF
+
+
+ src/main/resources/META-INF
+
+ persistence.xml
+ orm.xml
+
+
+
+
+
+
+
+
+
+
+
+
+ default
+
+ true
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ tomcat
+
+
+
+ src/main/resources
+ true
+
+ **/*ejb*.xml
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ejb/src/main/java/be/dabla/domain/MessageEJB.java b/ejb/src/main/java/be/dabla/domain/MessageEJB.java
new file mode 100644
index 0000000..392ebcb
--- /dev/null
+++ b/ejb/src/main/java/be/dabla/domain/MessageEJB.java
@@ -0,0 +1,57 @@
+package be.dabla.domain;
+
+import java.util.List;
+
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import be.dabla.model.Message;
+
+@Stateless(name="MessageEJB",mappedName="MessageEJB")
+@Remote(MessageEJBRemote.class)
+public class MessageEJB implements MessageEJBLocal {
+ @PersistenceContext(unitName = "tomee-maven-demo-pu")
+ protected EntityManager em;
+
+ @Override
+ public Number count() {
+ return (Number)em.createQuery("SELECT COUNT(m.id) FROM Message m").getSingleResult();
+ }
+
+ @Override
+ public List findAll(int start, int size) {
+ return em.createNamedQuery("Message.findAll").setFirstResult(start).setMaxResults(size).getResultList();
+ }
+
+ @Override
+ public Message findById(final Long id) {
+ return em.find(Message.class, id);
+ }
+
+ @Override
+ public Message create(final Message entity) {
+ if (entity != null) {
+ em.persist(entity);
+ }
+
+ return entity;
+ }
+
+ @Override
+ public void delete(final Message entity) {
+ if (entity != null) {
+ em.remove(em.merge(entity));
+ }
+ }
+
+ @Override
+ public Message update(final Message entity) {
+ if (entity != null) {
+ return em.merge(entity);
+ }
+
+ return entity;
+ }
+}
\ No newline at end of file
diff --git a/ejb/src/main/java/be/dabla/domain/MessageMDBSender.java b/ejb/src/main/java/be/dabla/domain/MessageMDBSender.java
new file mode 100644
index 0000000..90a35a3
--- /dev/null
+++ b/ejb/src/main/java/be/dabla/domain/MessageMDBSender.java
@@ -0,0 +1,59 @@
+package be.dabla.domain;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.Resource;
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import be.dabla.model.Message;
+import be.dabla.service.handler.Address;
+
+@Stateless(name="MessageMDBSender",mappedName="MessageMDBSender")
+@Remote(MessageMDBSenderRemote.class)
+public class MessageMDBSender implements MessageMDBSenderRemote {
+ public static final int TIME_TO_LIVE = 120000; // set expiration time to 2 minutes
+ private static final Logger logger = Logger.getLogger(MessageMDBSender.class.getName());
+ @Resource(mappedName="jms/tomee-maven-demo-cf")
+ ConnectionFactory connectionFactory;
+ @Resource(mappedName="jms/tomee-maven-demo-q")
+ Queue queue;
+
+ public void sendMessage(final Address address) throws JMSException {
+ logger.log(Level.INFO, "sendMessage: {0}", address);
+
+ Connection connection = null;
+ Session session = null;
+
+ try {
+ connection = connectionFactory.createConnection();
+ connection.start();
+ session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
+ final MessageProducer producer = session.createProducer(queue);
+ producer.setTimeToLive(TIME_TO_LIVE);
+ final ObjectMessage message = session.createObjectMessage(address);
+ producer.send(message);
+
+ logger.log(Level.FINE, "Message {0} send...", message);
+ }
+ finally {
+ try {
+ if (session != null) {
+ session.close();
+ }
+ } finally {
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ejb/src/main/java/be/dabla/mdb/MessageMDB.java b/ejb/src/main/java/be/dabla/mdb/MessageMDB.java
new file mode 100644
index 0000000..761cf29
--- /dev/null
+++ b/ejb/src/main/java/be/dabla/mdb/MessageMDB.java
@@ -0,0 +1,80 @@
+package be.dabla.mdb;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.ejb.ActivationConfigProperty;
+import javax.ejb.EJB;
+import javax.ejb.MessageDriven;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import be.dabla.domain.MessageEJBRemote;
+import be.dabla.model.Message;
+import be.dabla.service.MessageService;
+import be.dabla.service.MessageServiceClient;
+import be.dabla.service.handler.Address;
+import be.dabla.service.handler.WSAddressingClientHandler;
+
+// http://download.oracle.com/javaee/6/tutorial/doc/gipvi.html (jee6/ejb3.1 would make it a lot easier)
+@MessageDriven(mappedName = "jms/tomee-maven-demo-q", activationConfig = {
+ @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName="destination",propertyValue="jms/tomee-maven-demo-q")
+})
+public class MessageMDB implements MessageListener {
+ private static final Logger logger = Logger.getLogger(MessageMDB.class.getName());
+ final WSAddressingClientHandler handler;
+ final MessageService port;
+
+ public MessageMDB() {
+ handler = new WSAddressingClientHandler();
+ final List handlerChain = new ArrayList();
+ handlerChain.add(handler);
+
+ port = new MessageServiceClient().getMessageService();
+ ((BindingProvider)port).getBinding().setHandlerChain(handlerChain);
+ }
+
+ @EJB
+ MessageEJBRemote ejb;
+
+ @Override
+ public void onMessage(final javax.jms.Message msg) {
+ logger.log(Level.INFO, "onMessage: {0}", msg);
+
+ try {
+ final Address address = (Address)((ObjectMessage)msg).getObject();
+
+ logger.log(Level.FINE, "address: {0}", address);
+
+ if (address != null) {
+ final Message message = ejb.create(address.getContent());
+
+ logger.log(Level.FINE, "message: {0}", message);
+
+ if (message != null) {
+ handler.setAddress(address);
+ ((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address.getReplyTo());
+ port.callbackMessage(message);
+
+ logger.log(Level.INFO, "Message with id {0} acknowledged...", message.getId());
+ }
+ else {
+ throw new Exception("Address doesn't contain a message!");
+ }
+ }
+ }
+ catch(SOAPFaultException e) {
+ logger.warning(e.toString());
+ }
+ catch(Exception e) {
+ logger.severe(e.toString());
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ejb/src/main/resources/META-INF/ejb-jar.xml b/ejb/src/main/resources/META-INF/ejb-jar.xml
new file mode 100644
index 0000000..446dae7
--- /dev/null
+++ b/ejb/src/main/resources/META-INF/ejb-jar.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/ejb/src/main/resources/META-INF/weblogic-ejb-jar.xml b/ejb/src/main/resources/META-INF/weblogic-ejb-jar.xml
new file mode 100644
index 0000000..60348a5
--- /dev/null
+++ b/ejb/src/main/resources/META-INF/weblogic-ejb-jar.xml
@@ -0,0 +1,35 @@
+
+
+
+ MessageEJB
+
+
+ be.dabla.domain.MessageEJBRemote
+ MessageEJB
+
+
+ true
+
+
+ MessageMDBSender
+
+
+ be.dabla.domain.MessageMDBSenderRemote
+ MessageMDBSender
+
+
+ true
+
+
+ MessageMDB
+
+
+ 1
+ 1
+
+ jms/tomee-maven-demo-q
+ jms/tomee-maven-demo-cf
+
+
+
\ No newline at end of file
diff --git a/ejb/src/test/java/be/dabla/domain/MessageEJBTest.java b/ejb/src/test/java/be/dabla/domain/MessageEJBTest.java
new file mode 100644
index 0000000..97416f5
--- /dev/null
+++ b/ejb/src/test/java/be/dabla/domain/MessageEJBTest.java
@@ -0,0 +1,49 @@
+package be.dabla.domain;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import javax.ejb.EJB;
+import javax.naming.NamingException;
+
+import org.apache.openejb.OpenEJBTestCase;
+import org.apache.openejb.api.LocalClient;
+import org.junit.Test;
+
+import be.dabla.domain.MessageEJB;
+import be.dabla.domain.MessageEJBRemote;
+import be.dabla.model.Message;
+
+@LocalClient
+public class MessageEJBTest extends OpenEJBTestCase {
+ @EJB
+ private MessageEJBRemote ejb;
+
+ @Test
+ public void testCreate() {
+ assertNull(ejb.create(null));
+
+ try {
+ ejb.create(new Message()); // NOT NULL
+ fail("org.eclipse.persistence.exceptions.DatabaseException");
+ }
+ catch(Exception e) {
+
+ }
+
+ assertNotNull(ejb.create(new Message("Hello World")));
+ assertNotNull(ejb.create(new Message("Hello David")));
+ }
+
+ @Test
+ public void testCount() throws NamingException {
+ assertNotNull(ejb.count());
+ }
+
+ @Test
+ public void testFindAll() throws NamingException {
+ assertNotNull(initialContext.lookup(MessageEJB.class.getSimpleName()));
+ assertNotNull(ejb.findAll(0, 10));
+ }
+}
\ No newline at end of file
diff --git a/ejb/src/test/java/org/apache/openejb/ClassLoaderUtil.java b/ejb/src/test/java/org/apache/openejb/ClassLoaderUtil.java
new file mode 100644
index 0000000..f1c4adb
--- /dev/null
+++ b/ejb/src/test/java/org/apache/openejb/ClassLoaderUtil.java
@@ -0,0 +1,264 @@
+/**
+ *
+ * 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;
+
+import java.beans.Introspector;
+import java.io.File;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarFile;
+
+import org.apache.openejb.core.TempClassLoader;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.UrlCache;
+
+/**
+ * @version $Revision: 948987 $ $Date: 2010-05-27 13:55:12 -0700 (Thu, 27 May 2010) $
+ */
+public class ClassLoaderUtil {
+ private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, ClassLoaderUtil.class);
+ private static final Map> classLoadersByApp = new HashMap>();
+ private static final Map> appsByClassLoader = new HashMap>();
+
+ private static final UrlCache urlCache = new UrlCache();
+
+ public static ClassLoader getContextClassLoader() {
+ return AccessController.doPrivileged(new PrivilegedAction() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+
+ public static URLClassLoader createClassLoader(String appId, URL[] urls, ClassLoader parent) {
+ urls = urlCache.cacheUrls(appId, urls);
+ URLClassLoader classLoader = new URLClassLoader(urls, parent);
+
+ List classLoaders = classLoadersByApp.get(appId);
+ if (classLoaders == null) {
+ classLoaders = new ArrayList(2);
+ classLoadersByApp.put(appId, classLoaders);
+ }
+ classLoaders.add(classLoader);
+
+ Set apps = appsByClassLoader.get(classLoader);
+ if (apps == null) {
+ apps = new LinkedHashSet(1);
+ appsByClassLoader.put(classLoader, apps);
+ }
+ apps.add(appId);
+
+ return classLoader;
+ }
+
+ public static void destroyClassLoader(ClassLoader classLoader) {
+ logger.debug("Destroying classLoader " + toString(classLoader));
+
+ // remove from the indexes
+ Set apps = appsByClassLoader.remove(classLoader);
+ if (apps != null) {
+ for (String appId : apps) {
+ List classLoaders = classLoadersByApp.get(appId);
+ if (classLoaders != null) {
+ classLoaders.remove(classLoader);
+ // if this is the last class loader in the app, clean up the app
+ if (classLoaders.isEmpty()) {
+ destroyClassLoader(appId);
+ }
+ }
+ }
+ }
+
+ // clear the lame openjpa caches
+ cleanOpenJPACache(classLoader);
+ }
+
+ public static void destroyClassLoader(String appId) {
+ logger.debug("Destroying classLoaders for application " + appId);
+
+ List classLoaders = classLoadersByApp.remove(appId);
+ if (classLoaders != null) {
+ for (ClassLoader classLoader : classLoaders) {
+ // get the apps using the class loader
+ Set apps = appsByClassLoader.get(classLoader);
+ if (apps == null) apps = Collections.emptySet();
+
+ // this app is no longer using the class loader
+ apps.remove(appId);
+
+ // if no apps are using the class loader, destroy it
+ if (apps.isEmpty()) {
+ appsByClassLoader.remove(classLoader);
+ destroyClassLoader(classLoader);
+ } else {
+ logger.debug("ClassLoader " + toString(classLoader) + " held open by the applications" + apps);
+ }
+ }
+ }
+ urlCache.releaseUrls(appId);
+ clearSunJarFileFactoryCache(appId);
+ }
+
+ public static URLClassLoader createTempClassLoader(ClassLoader parent) {
+ return new TempClassLoader(parent);
+ }
+
+ public static URLClassLoader createTempClassLoader(String appId, URL[] urls, ClassLoader parent) {
+ URLClassLoader classLoader = createClassLoader(appId, urls, parent);
+ TempClassLoader tempClassLoader = new TempClassLoader(classLoader);
+ return tempClassLoader;
+ }
+
+ /**
+ * Cleans well known class loader leaks in VMs and libraries. There is a lot of bad code out there and this method
+ * will clear up the know problems. This method should only be called when the class loader will no longer be used.
+ * It this method is called two often it can have a serious impact on preformance.
+ */
+ public static void clearClassLoaderCaches() {
+ clearSunSoftCache(ObjectInputStream.class, "subclassAudits");
+ clearSunSoftCache(ObjectOutputStream.class, "subclassAudits");
+ clearSunSoftCache(ObjectStreamClass.class, "localDescs");
+ clearSunSoftCache(ObjectStreamClass.class, "reflectors");
+ Introspector.flushCaches();
+ }
+
+ public static void clearSunJarFileFactoryCache(final String jarLocation) {
+ clearSunJarFileFactoryCacheImpl(jarLocation, 5);
+ }
+
+ private static void clearSunJarFileFactoryCacheImpl(final String jarLocation, final int attempt) {
+ logger.debug("Clearing Sun JarFileFactory cache for directory " + jarLocation);
+
+ try {
+ Class> jarFileFactory = Class.forName("sun.net.www.protocol.jar.JarFileFactory");
+
+ synchronized (jarFileFactory) {
+
+ Field fileCacheField = jarFileFactory.getDeclaredField("fileCache");
+
+ fileCacheField.setAccessible(true);
+ Map