First steps at build simplification. Removed Class-Path manifest entries for Squiggle and Rasterizer. Introduced AppStarterUtil that handles the dynamic classpath setup when invoked using "java -jar" to make Class-Path manifest entries unnecessary. Simplified javac class by using Ant's presetdef. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/batik/branches/build-simplification@1066387 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/build.xml b/build.xml index 4b85892..b637bde 100644 --- a/build.xml +++ b/build.xml
@@ -92,7 +92,9 @@ <property name="debug" value="off"/> <property name="optimize" value="on"/> <property name="deprecation" value="on"/> - + <property name="javac.source" value="1.5"/> + <property name="javac.target" value="1.5"/> + <property name="src" value="sources"/> <property name="src-internal-codec" value="sources-internal-codec"/> <property name="resources" value="resources"/> @@ -218,6 +220,11 @@ <echo message=" JAVA_HOME: ${env.JAVA_HOME}"/> <echo message=" VM: ${java.vm.version}, ${java.vm.vendor}"/> + <presetdef name="javac"> + <javac source="${javac.source}" target="${javac.target}" + debug="${debug}" deprecation="${deprecation}" optimize="${optimize}"/> + </presetdef> + <property name="init.done" value="true"/> </target> @@ -577,8 +584,7 @@ <attribute name="Implementation-Version" value="${completeVersion}${svn-revision-suffix}"/> <attribute name="Implementation-Vendor" value="The Apache Software Foundation (http://xmlgraphics.apache.org/batik/)"/> <attribute name="Build-Id" value="${build.id}"/> - <attribute name="Main-Class" value="org.apache.batik.apps.rasterizer.Main"/> - <attribute name="Class-Path" value="batik-ext-${completeVersion}.jar batik-dom-${completeVersion}.jar batik-css-${completeVersion}.jar batik-svg-dom-${completeVersion}.jar batik-gvt-${completeVersion}.jar batik-parser-${completeVersion}.jar batik-script-${completeVersion}.jar batik-bridge-${completeVersion}.jar batik-anim-${completeVersion}.jar batik-transcoder-${completeVersion}.jar batik-awt-util-${completeVersion}.jar batik-codec-${completeVersion}.jar batik-util-${completeVersion}.jar batik-xml-${completeVersion}.jar xerces-2.5.0.jar xalan-2.6.0.jar xml-apis-1.3.04.jar xml-apis-ext-1.3.04.jar fop-0.94.jar batik-js.jar"/> + <attribute name="Main-Class" value="org.apache.batik.apps.rasterizer.DynamicMain"/> </manifest> <metainf dir="${basedir}" includes="LICENSE,NOTICE"/> <fileset dir="${dest}"> @@ -645,12 +651,11 @@ <attribute name="Implementation-Version" value="${completeVersion}${svn-revision-suffix}"/> <attribute name="Implementation-Vendor" value="The Apache Software Foundation (http://xmlgraphics.apache.org/batik/)"/> <attribute name="Build-Id" value="${build.id}"/> - <attribute name="Main-Class" value="org.apache.batik.apps.svgbrowser.Main"/> - <attribute name="Class-Path" value="batik-ext-${completeVersion}.jar batik-dom-${completeVersion}.jar batik-css-${completeVersion}.jar batik-svg-dom-${completeVersion}.jar batik-gvt-${completeVersion}.jar batik-parser-${completeVersion}.jar batik-script-${completeVersion}.jar batik-bridge-${completeVersion}.jar batik-swing-${completeVersion}.jar batik-anim-${completeVersion}.jar batik-transcoder-${completeVersion}.jar batik-gui-util-${completeVersion}.jar batik-awt-util-${completeVersion}.jar batik-codec-${completeVersion}.jar batik-util-${completeVersion}.jar batik-xml-${completeVersion}.jar xerces-2.5.0.jar xalan-2.6.0.jar xml-apis-1.3.04.jar xml-apis-ext-1.3.04.jar batik-js.jar"/> </manifest> <metainf dir="${basedir}" includes="LICENSE,NOTICE"/> <fileset dir="${dest}"> <include name="${package-prefix}/apps/svgbrowser/**/*.class"/> + <include name="${package-prefix}/util/AppStarterUtil*.class"/> </fileset> <fileset dir="${resources}" excludes="**/.svn/"> <include name="${package-prefix}/apps/svgbrowser/**/resources/**"/> @@ -819,8 +824,7 @@ <echo message="debug ${debug}, optimize ${optimize}, deprecation ${deprecation}"/> - <javac srcdir="${testsrc}" destdir="${dest}" deprecation="${deprecation}" - debug="${debug}" optimize="${optimize}" encoding="UTF-8"> + <javac srcdir="${testsrc}" destdir="${dest}" encoding="UTF-8"> <classpath> <pathelement location="${dest}"/> <path refid="libs-classpath"/> @@ -843,8 +847,7 @@ <echo message="debug ${debug}, optimize ${optimize}, deprecation ${deprecation}"/> - <javac srcdir="${samples}/tests/resources/java/sources" destdir="${samples}/tests/resources/java/classes" deprecation="${deprecation}" - debug="${debug}" optimize="${optimize}" encoding="UTF-8"> + <javac srcdir="${samples}/tests/resources/java/sources" destdir="${samples}/tests/resources/java/classes" encoding="UTF-8"> <classpath> <pathelement location="${dest}"/> <pathelement location="${samples}/tests/resources/java/classes"/> @@ -853,8 +856,7 @@ </classpath> </javac> - <javac srcdir="${testresources}" destdir="${testresources}/classes" deprecation="${deprecation}" - debug="${debug}" optimize="${optimize}" encoding="UTF-8"> + <javac srcdir="${testresources}" destdir="${testresources}/classes" encoding="UTF-8"> <classpath> <pathelement location="${dest}"/> <pathelement location="${testresources}/classes"/> @@ -989,8 +991,7 @@ </target> <target name="compile" depends="init, compile-prepare" unless="compile.done"> - <javac destdir="${dest}" deprecation="${deprecation}" - debug="${debug}" optimize="${optimize}" encoding="UTF-8"> + <javac destdir="${dest}" encoding="UTF-8"> <src path="${src}"/> <classpath refid="libs-classpath"/> <exclude name="**/*.html"/> @@ -1637,6 +1638,7 @@ <metainf dir="${basedir}" includes="LICENSE,NOTICE"/> <fileset dir="${dest}"> <include name="${package-prefix}/apps/svgbrowser/**/*.class"/> + <include name="${package-prefix}/util/AppStarterUtil*.class"/> </fileset> <fileset dir="${resources}" excludes="**/.svn/"> <include name="${package-prefix}/apps/svgbrowser/**/resources/**"/> @@ -1687,6 +1689,7 @@ <metainf dir="${basedir}" includes="LICENSE,NOTICE"/> <fileset dir="${dest}"> <include name="${package-prefix}/apps/rasterizer/**/*.class"/> + <include name="${package-prefix}/util/AppStarterUtil*.class"/> </fileset> <fileset dir="${resources}" excludes="**/.svn/"> <include name="${package-prefix}/apps/rasterizer/**/resources/**"/>
diff --git a/sources/batik-browser.mf b/sources/batik-browser.mf index a878f15..47fe19c 100644 --- a/sources/batik-browser.mf +++ b/sources/batik-browser.mf
@@ -1,23 +1,2 @@ Manifest-Version: 1.0 -Main-Class: org.apache.batik.apps.svgbrowser.Main -Class-Path: lib/batik-ext.jar \ - lib/batik-dom.jar \ - lib/batik-css.jar \ - lib/batik-svg-dom.jar \ - lib/batik-gvt.jar \ - lib/batik-parser.jar \ - lib/batik-script.jar \ - lib/batik-bridge.jar \ - lib/batik-swing.jar \ - lib/batik-anim.jar \ - lib/batik-transcoder.jar \ - lib/batik-gui-util.jar \ - lib/batik-awt-util.jar \ - lib/batik-codec.jar \ - lib/batik-util.jar \ - lib/batik-xml.jar \ - lib/xerces_2_5_0.jar \ - lib/xalan-2.6.0.jar \ - lib/xml-apis.jar \ - lib/xml-apis-ext.jar \ - lib/js.jar +Main-Class: org.apache.batik.apps.svgbrowser.MainDynamic
diff --git a/sources/batik-rasterizer.mf b/sources/batik-rasterizer.mf index 018bd39..6cadc05 100644 --- a/sources/batik-rasterizer.mf +++ b/sources/batik-rasterizer.mf
@@ -1,22 +1,2 @@ Manifest-Version: 1.0 -Main-Class: org.apache.batik.apps.rasterizer.Main -Class-Path: lib/batik-ext.jar \ - lib/batik-dom.jar \ - lib/batik-css.jar \ - lib/batik-svg-dom.jar \ - lib/batik-gvt.jar \ - lib/batik-parser.jar \ - lib/batik-script.jar \ - lib/batik-bridge.jar \ - lib/batik-anim.jar \ - lib/batik-transcoder.jar \ - lib/batik-awt-util.jar \ - lib/batik-codec.jar \ - lib/batik-util.jar \ - lib/batik-xml.jar \ - lib/xerces_2_5_0.jar \ - lib/xalan-2.6.0.jar \ - lib/xml-apis.jar \ - lib/xml-apis-ext.jar \ - lib/pdf-transcoder.jar \ - lib/js.jar +Main-Class: org.apache.batik.apps.rasterizer.MainDynamic
diff --git a/sources/org/apache/batik/apps/rasterizer/MainDynamic.java b/sources/org/apache/batik/apps/rasterizer/MainDynamic.java new file mode 100644 index 0000000..6dc20e1 --- /dev/null +++ b/sources/org/apache/batik/apps/rasterizer/MainDynamic.java
@@ -0,0 +1,36 @@ +/* + + 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.batik.apps.rasterizer; + +import org.apache.batik.util.AppStarterUtil; + +/** + * Main class with dynamic classpath setup for "java -jar" startup. + */ +public class MainDynamic { + + /** + * Main application method. + * @param args the command-line arguments + */ + public static void main(String[] args) { + AppStarterUtil.startApp(MainDynamic.class, args); + } + +}
diff --git a/sources/org/apache/batik/apps/svgbrowser/MainDynamic.java b/sources/org/apache/batik/apps/svgbrowser/MainDynamic.java new file mode 100644 index 0000000..ece6282 --- /dev/null +++ b/sources/org/apache/batik/apps/svgbrowser/MainDynamic.java
@@ -0,0 +1,36 @@ +/* + + 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.batik.apps.svgbrowser; + +import org.apache.batik.util.AppStarterUtil; + +/** + * Main class with dynamic classpath setup for "java -jar" startup. + */ +public class MainDynamic { + + /** + * Main application method. + * @param args the command-line arguments + */ + public static void main(String[] args) { + AppStarterUtil.startApp(MainDynamic.class, args); + } + +}
diff --git a/sources/org/apache/batik/util/AppStarterUtil.java b/sources/org/apache/batik/util/AppStarterUtil.java new file mode 100644 index 0000000..9944858 --- /dev/null +++ b/sources/org/apache/batik/util/AppStarterUtil.java
@@ -0,0 +1,151 @@ +/* + + 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.batik.util; + +import java.io.File; +import java.io.FileFilter; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; + +import org.apache.batik.apps.svgbrowser.Main; + +/** + * Utility class for starting applications with a dynamic classpath setup for "java -jar". + * This avoids having to hard-code the manifest's "Class-Path" entry. Instead, the library + * JARs are automatically picked up from the "./lib" directory, or if that's not found, the + * current directory. + */ +public class AppStarterUtil { + + private static final Class<?> STRING_ARRAY_CLASS = new String[0].getClass(); + + /** + * Starts the application derived from the "MainDynamic" class. + * @param starterClass the "MainDynamic" class + * @param args the command-line arguments + */ + public static void startApp(Class<?> starterClass, String[] args) { + String className = starterClass.getName(); + String mainClassName = className.substring(0, className.lastIndexOf("Dynamic")); + startApp(mainClassName, args); + } + /** + * Starts the application given the main class name. + * @param mainClassName the main class name + * @param args the command-line arguments + */ + public static void startApp(String mainClassName, String[] args) { + try { + Class<?> mainClazz; + try { + //If the following class is not available, we need to dynamically build + //the classpath. "-jar" was used. + Class.forName("org.apache.batik.bridge.Bridge"); + mainClazz = Class.forName(mainClassName); + } catch (ClassNotFoundException cnfe) { + URL[] urls = getJARList(); + ClassLoader loader = new BatikFirstClassLoader(urls, + AppStarterUtil.class.getClassLoader()); + mainClazz = Class.forName(mainClassName, true, loader); + } + Method mainMethod = mainClazz.getMethod("main", STRING_ARRAY_CLASS); + mainMethod.invoke(null, new Object[] {args}); + } catch (Exception e) { + System.err.println("Unable to start " + Main.class.getName() + ":"); + e.printStackTrace(); + System.exit(-1); + } + } + + /** + * Determines the dynamic class path. + * @return the array of JAR files for the class path + * @throws MalformedURLException if there is a problem constructing URLs + */ + private static URL[] getJARList() throws MalformedURLException { + File baseDir = new File("."); + List<URL> jars = new java.util.ArrayList<URL>(); + + //Get JARs from the "normal" class path... + String cp = System.getProperty("java.class.path"); + String[] cpEntries = cp.split(";"); + for (String entry : cpEntries) { + File f = new File(baseDir, entry); + jars.add(f.toURI().toURL()); + } + + //...and add JARs from the lib (or base) directory. + 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].toURI().toURL()); + } + } + URL[] urls = jars.toArray(new URL[jars.size()]); + return urls; + } + + /** + * A special {@link URLClassLoader} subclass that loads Batik classes before before looking up + * classes in the parent class loader. + */ + private static class BatikFirstClassLoader extends URLClassLoader { + + public BatikFirstClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + } + + /** {@inheritDoc} */ + @Override + protected synchronized Class<?> loadClass(String name, boolean resolve) + throws ClassNotFoundException { + if (!name.startsWith("org.apache.batik.")) { + return super.loadClass(name, resolve); + } + //Load all Batik-related classes before consulting the parent class loader + try { + Class<?> clazz = findLoadedClass(name); + if (clazz == null) { + clazz = super.findClass(name); + } + if (resolve) { + resolveClass(clazz); + } + return clazz; + } catch (ClassNotFoundException cnfe) { + return super.loadClass(name, resolve); + } + } + + } + +}