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);
+ }
+ }
+
+ }
+
+}