[Buix-commits] r1037 - lutinjaxx/trunk/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action
Author: chemit Date: 2008-11-30 18:31:15 +0000 (Sun, 30 Nov 2008) New Revision: 1037 Modified: lutinjaxx/trunk/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java Log: fix ServiceLoader failure when application is launched from a java -jar Modified: lutinjaxx/trunk/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java =================================================================== --- lutinjaxx/trunk/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java 2008-11-30 14:05:52 UTC (rev 1036) +++ lutinjaxx/trunk/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java 2008-11-30 18:31:15 UTC (rev 1037) @@ -21,6 +21,7 @@ import jaxx.runtime.swing.JAXXToggleButton; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.codelutin.util.Resource; import javax.swing.AbstractButton; import javax.swing.Action; @@ -29,6 +30,8 @@ import javax.swing.JComponent; import java.awt.event.ActionEvent; import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.net.URLClassLoader; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -389,6 +392,12 @@ if (log.isDebugEnabled()) { log.debug("start loading " + this); } + URLClassLoader newCL = fixClassLoader(getClass()); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (newCL != null) { + // replace current cl by our fiexed cl + Thread.currentThread().setContextClassLoader(newCL); + } // obtain a ServiceLoader on ActionProvider ServiceLoader<ActionProvider> loader = ServiceLoader.load(ActionProvider.class); Map<String, Class<? extends MyAbstractAction>> cache = new TreeMap<String, Class<? extends MyAbstractAction>>(); @@ -399,7 +408,50 @@ } cache.putAll(actionProvider.getClasses()); } + if (newCL != null) { + // to avoid side effects, push back old cl + Thread.currentThread().setContextClassLoader(cl); + } return cache; } + /** + * Fix the class loader when application is launched from a java -jar + * The ServiceLoader seems not to find services from jar manifest... + * <p/> + * Our solution is to get all jar from the jar manifest and create a URLClassLoader, this is not perfect but works. + * <p/> + * TODO Put this nice code in a ServiceLoaderUtil in lutinutil... + * + * @param klass class to use to obtain classloader + * @return the fixed classloader + */ + public static URLClassLoader fixClassLoader(Class klass) { + ClassLoader l = klass.getClassLoader(); + URLClassLoader cl; + if (!(l instanceof URLClassLoader)) { + log.warn("using cl is not a URL classloader " + l); + cl = new URLClassLoader(new URL[0], l); + } else { + cl = (URLClassLoader) l; + } + if (cl.getURLs().length == 1) { + // come from a java -jar, must expand all jar to make possible ServiceLoader to work + try { + //todo put this in lutinutil ServiceLoaderUtil + URL[] urls = Resource.getClassPathURLsFromJarManifest(cl.getURLs()[0]); + URLClassLoader newCL = new URLClassLoader(urls); + if (log.isTraceEnabled()) { + for (URL url : newCL.getURLs()) { + log.trace(url); + } + } + return newCL; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return null; + } + } \ No newline at end of file
participants (1)
-
chemit@users.labs.libre-entreprise.org