From: Jeremias Maerki Date: Mon, 18 Jul 2005 16:41:18 +0000 (+0000) Subject: Dynamic classpath setup in case not all required dependencies are available in the... X-Git-Tag: fop-0_90-alpha1~485 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c5d54602fa18f05bb46acaee056dfa4ec62d00e6;p=xmlgraphics-fop.git Dynamic classpath setup in case not all required dependencies are available in the given classpath. Useful when starting FOP using "java -jar fop.jar". This is actually a replacement for the manifest "Class-Path" entry and even picks up additional JARs it finds. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@219531 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/fop/apps/Fop.java b/src/java/org/apache/fop/apps/Fop.java index 243448d29..8e3938686 100644 --- a/src/java/org/apache/fop/apps/Fop.java +++ b/src/java/org/apache/fop/apps/Fop.java @@ -20,8 +20,14 @@ package org.apache.fop.apps; // Java import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileFilter; import java.io.FileOutputStream; import java.io.OutputStream; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; // XML import org.xml.sax.helpers.DefaultHandler; @@ -131,10 +137,108 @@ public class Fop implements Constants { } /** - * The main routine for the command line interface - * @param args the command line parameters + * @return the list of URLs to all libraries. + * @throws MalformedURLException In case there is a problem converting java.io.File + * instances to URLs. */ - public static void main(String[] args) { + public static URL[] getJARList() throws MalformedURLException { + File baseDir = new File(".").getAbsoluteFile().getParentFile(); + File buildDir; + if ("build".equals(baseDir.getName())) { + buildDir = baseDir; + baseDir = baseDir.getParentFile(); + } else { + buildDir = new File(baseDir, "build"); + } + File fopJar = new File(buildDir, "fop.jar"); + if (!fopJar.exists()) { + fopJar = new File(baseDir, "fop.jar"); + } + if (!fopJar.exists()) { + throw new RuntimeException("fop.jar not found in directory: " + + baseDir.getAbsolutePath() + " (or below)"); + } + List jars = new java.util.ArrayList(); + jars.add(fopJar.toURL()); + File[] files; + FileFilter filter = new FileFilter() { + public boolean accept(File pathname) { + return pathname.getName().endsWith(".jar"); + } + }; + File libDir = new File(baseDir, "lib"); + if (!libDir.exists()) { + libDir = baseDir; + } + files = libDir.listFiles(filter); + if (files != null) { + for (int i = 0, size = files.length; i < size; i++) { + jars.add(files[i].toURL()); + } + } + String optionalLib = System.getProperty("fop.optional.lib"); + if (optionalLib != null) { + files = new File(optionalLib).listFiles(filter); + if (files != null) { + for (int i = 0, size = files.length; i < size; i++) { + jars.add(files[i].toURL()); + } + } + } + URL[] urls = (URL[])jars.toArray(new URL[jars.size()]); + /* + for (int i = 0, c = urls.length; i < c; i++) { + System.out.println(urls[i]); + }*/ + return urls; + } + + /** + * @return true if FOP's dependecies are available in the current ClassLoader setup. + */ + public static boolean checkDependencies() { + try { + //System.out.println(Thread.currentThread().getContextClassLoader()); + Class clazz = Class.forName("org.apache.batik.Version"); + if (clazz != null) { + clazz = Class.forName("org.apache.avalon.framework.configuration.Configuration"); + } + return (clazz != null); + } catch (Exception e) { + return false; + } + } + + /** + * Dynamically builds a ClassLoader and executes FOP. + * @param args command-line arguments + */ + public static void startFOPWithDynamicClasspath(String[] args) { + try { + URL[] urls = getJARList(); + //System.out.println("CCL: " + // + Thread.currentThread().getContextClassLoader().toString()); + ClassLoader loader = new java.net.URLClassLoader(urls, null); + Thread.currentThread().setContextClassLoader(loader); + Class clazz = Class.forName("org.apache.fop.apps.Fop", true, loader); + //System.out.println("CL: " + clazz.getClassLoader().toString()); + Method mainMethod = clazz.getMethod("startFOP", new Class[] {String[].class}); + mainMethod.invoke(null, new Object[] {args}); + } catch (Exception e) { + System.err.println("Unable to start FOP:"); + e.printStackTrace(); + System.exit(-1); + } + } + + /** + * Executes FOP with the given ClassLoader setup. + * @param args command-line arguments + */ + public static void startFOP(String[] args) { + //System.out.println("static CCL: " + // + Thread.currentThread().getContextClassLoader().toString()); + //System.out.println("static CL: " + Fop.class.getClassLoader().toString()); CommandLineOptions options = null; FOUserAgent foUserAgent = null; BufferedOutputStream bos = null; @@ -173,6 +277,19 @@ public class Fop implements Constants { System.exit(1); } } + + /** + * The main routine for the command line interface + * @param args the command line parameters + */ + public static void main(String[] args) { + if (checkDependencies()) { + startFOP(args); + } else { + startFOPWithDynamicClasspath(args); + } + } + /** * Get the version of FOP