• Views
  • Iteration Report
  • My Iteration Report
  •  
OMERO.server
  • Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • Last Change
  • Annotate
  • Revision Log

root/tags/omero-3.0-M3/lib/tools/omero.java

Revision 677, 15.0 kB (checked in by jmoore, 3 years ago)

Reworking TestNG. Closes #100. Needed for #84.

  • Includes patched testng jar (a debug version was in r676)
  • Added testng-dep bsh.jar (removable?)
  • Copied antlib's testng.xml to each component
Line 
1/*
2 * omero
3 *
4 *------------------------------------------------------------------------------
5 *
6 *  Copyright (C) 2005 Open Microscopy Environment
7 *      Massachusetts Institute of Technology,
8 *      National Institutes of Health,
9 *      University of Dundee
10 *
11 *
12 *
13 *    This library is free software; you can redistribute it and/or
14 *    modify it under the terms of the GNU Lesser General Public
15 *    License as published by the Free Software Foundation; either
16 *    version 2.1 of the License, or (at your option) any later version.
17 *
18 *    This library is distributed in the hope that it will be useful,
19 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 *    Lesser General Public License for more details.
22 *
23 *    You should have received a copy of the GNU Lesser General Public
24 *    License along with this library; if not, write to the Free Software
25 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 *------------------------------------------------------------------------------
28 */
29
30//Java imports
31import java.io.File;
32import java.io.FileFilter;
33import java.lang.reflect.Method;
34import java.net.URI;
35import java.net.URL;
36import java.net.URLClassLoader;
37import java.util.Locale;
38import java.util.Properties;
39
40//Third-party libraries
41
42//Application-internal dependencies
43
44/**
45 * The Build Tool.
46 * This class is in charge of launching Ant with a suitable environment.
47 * <p>The workflow is (in principle) identical to the Ant Launcher class (see
48 * <code>org.apache.tools.ant.launch.Launcher</code>): set up the required
49 * system properties, locate all the required libraries (including the JDK
50 * tools), and launch Ant with a suitable classpath and with whatever arguments
51 * were supplied on the command line.</p>
52 * <p>The implementation however is quite different.  In fact, on one hand we
53 * know exactly how the tool is deployed and run, so some aspects of the
54 * launch procedure can be simplified.  On the other hand we tailor this
55 * procedure to the needs of our build system.</p>
56 * <p>The launch procedure assumes the following:</p>
57 * <ul>
58 *  <li>This class is compiled in the <i>build</i> directory under the
59 *      Shoola CVS root.  Its file name is <i>"omero.class"</i> and it
60 *      belongs to the default namespace (unnamed package).</li>
61 *  <li>The <i>build</i> directory contains a sub-directory named <i>tools</i>.
62 *      The latter contains the Ant core jars, the Ant jars for the optional
63 *      tasks that we use, and all the external libraries required for those
64 *      optional tasks.  Optionally, it may contain the Sun JDK tools jar.
65 *      (Because of licensing issues, we can't add the <i>tools.jar</i> to CVS;
66 *      however developers may want to drop that file into this directory after
67 *      downloading from CVS.)</li>
68 *  <li>The Sun JDK tools can be accessed because the classes:
69 *    <ul>
70 *     <li>Are in the default classpath (boot, ext) of the JVM that is used to
71 *         invoke the Build Tool, or</li>
72 *     <li>Are contained in a jar file named <i>"tools.jar"</i> under
73 *         <i>{java.home}/lib</i> (JDK installed; if {java.home} points to the
74 *         <i>jre</i> directory within the JDK, then the jar is expected to be
75 *         in the <i>lib</i> sibling directory), or</li>
76 *     <li>Are contained in a jar file under the <i>build/tools</i> directory.
77 *         In this case, the version of the JDK tools is expected to be the
78 *         same as the one of the JVM that is used to invoke the Build Tool. 
79 *         (Failure to comply may result in compilation errors due to class
80 *         file version incompatibilities.)</li>
81 *    </ul>
82 *  </li>
83 *  <li>The Build Tool is invoked with the following syntax: <code>java build
84 *      [options] [target1 [target2 [target3] ...]]</code>, where
85 *      <code>options</code> are any of the Ant options and <code>targetN</code>
86 *      is any of the available targets.  Note that we assume no classpath is
87 *      ever specified to <code>java</code>.</li>
88 * </ul>
89 * <p>A final important remark.  Before dropping the JDK tools into
90 * <i>build/tools</i>, you should make sure they're not available to the JVM
91 * in use.  (Just run the Build Tool to compile, if it fails the JDK tools are
92 * not available.)  This is important because if the JDK tools are already
93 * available, adding a copy under <i>build/tools</i> would result in having
94 * two sets of JDK tools classes on the classpath.  As you can imagine, some
95 * nasty runtime behavior could originate from that if the JDK tools have
96 * different versions.</p>
97 *
98 * @author  Jean-Marie Burel &nbsp;&nbsp;&nbsp;&nbsp;
99 *                              <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
100 * @author  <br>Andrea Falconi &nbsp;&nbsp;&nbsp;&nbsp;
101 *                              <a href="mailto:a.falconi@dundee.ac.uk">
102 *                                      a.falconi@dundee.ac.uk</a>
103 * @version 2.2
104 * <small>
105 * (<b>Internal version:</b> $Revision: 2359 $ $Date: 2005-02-10 19:16:23 +0100 (Thu, 10 Feb 2005) $)
106 * </small>
107 * @since OME2.2
108 */
109public class omero
110    implements FileFilter
111{
112
113    /**
114     * The <i>build</i> directory under the Shoola CVS root.
115     * This is the directory where this class is compiled.
116     */
117    private File    buildDir;
118   
119    /**
120     * The <i>tools</i> directory under {@link #buildDir}.
121     * This directory contains all the libraries required by the Build Tool,
122     * except the JDK tools which can be added after downloading from CVS. 
123     */
124    private File    toolsDir;
125   
126    /**
127     * Points to the Sun JDK tools jar file, if any, in the java installation
128     * directory.
129     * This is the installation directory of the JVM used to launch the build
130     * tool and is given by the <i>java.home</i> system property.
131     * Note that this file may not exist.  (For example if the Sun JDK is not
132     * installed or the JVM used to run the Build Tool is not part of the JDK.)
133     */
134    private File    jdkTools;
135   
136   
137    /**
138     * Locates the needed filesystem entries and initializes the corresponding
139     * fields.
140     * We throw an exception if the <i>build</i> and <i>tools</i> directories
141     * can't be located from the position of the <code>build</code> class on
142     * the filesystem.  We try and guess the position of the Sun JDK tools, but
143     * we don't check whether this file actually exists.  In fact, the JDK tools
144     * classes may turn out to be available to the current JVM by some other
145     * means.  (For example, they are already in the bootclasspath or the tools
146     * jar file has been dropped into our <i>tools</i> directory.)
147     *
148     * @throws Exception If <i>build</i> and <i>tools</i> directories can't be
149     *                   located.
150     */
151    private omero()
152        throws Exception
153    {
154        //First locate the build directory.
155        //We assume this class always belongs to the default package and
156        //is compiled in the build directory.
157        URL url = omero.class.getClassLoader().getResource("omero.class");
158        if (url == null) throw new Exception("Can't locate omero class.");
159        File build = new File(new URI(url.toExternalForm()));
160        buildDir = build.getParentFile();
161        if (!buildDir.exists() || !buildDir.isDirectory())
162            throw new Exception("Invalid location: "+buildDir.getAbsolutePath()+
163                    " is not a directory.");
164       
165        //Now locate the tools sub-directory.
166        toolsDir = new File(buildDir, "lib");
167        if (!toolsDir.exists() || !toolsDir.isDirectory())
168            throw new Exception("Invalid location: "+toolsDir.getAbsolutePath()+
169                    " is not a directory.");
170       
171        //Finally guess the location of the JDK tools.jar file.
172        String javaHome = System.getProperty("java.home");
173        if (javaHome.toLowerCase(Locale.US).endsWith("jre"))
174            javaHome = javaHome.substring(0, javaHome.length()-4);
175        jdkTools = new File(javaHome+"/lib/tools.jar");
176    }
177   
178    /**
179     * Tests for availability of the JDK tools in the JVM default classpath.
180     * (Recall that the Build Tool is invoked like: java build, so no -cp
181     * is ever specified.)
182     *
183     * @return <code>true</code> if the JDK tools are found, <code>false</code>
184     *          otherwise.
185     */
186    private boolean isJDKToolsAvailable()
187    {
188        String[] main = {"com.sun.tools.javac.Main", "sun.tools.javac.Main"};
189        for (int i = 0; i < main.length; ++i)
190           try {
191               Class.forName(main[i]);
192               return true;
193           } catch (ClassNotFoundException cnfe) {}
194        return false;
195    }
196   
197    /**
198     * Locates all the libraries required by the Build Tool.
199     * We consider <i>any jar</i> file in <i>build/tools</i> under the
200     * Shoola CVS root to be a library required by the Build Tool.
201     * Moreover, if the JDK tools are not already in the JVM default classpath,
202     * we try and grab the <i>tools.jar</i> file and then add it to the
203     * returned array.  This could potentially be a problem if a jar file
204     * containing the JDK tools is also present in <i>build/tools</i>.  In this
205     * case we would end up with two sets of JDK tools classes on the classpath,
206     * which could originate some nasty runtime behavior if the JDK tools have
207     * different versions.
208     *
209     * @return A file object for each jar file found in <i>build/tools</i>.
210     * @throws Exception If no libraries were found in <i>build/tools</i>.
211     */
212    private File[] locateBuildJars()
213        throws Exception
214    {
215        File[] jars = new File[7];
216        jars[0] = new File(mavenPath("ant","ant","1.6.5"));
217        jars[1] = new File(mavenPath("ant","ant-launcher","1.6.5"));
218        jars[2] = new File(mavenPath("xml-apis","xml-apis","1.0.b2"));
219        jars[3] = new File(mavenPath("xerces","xerces","2.0.2"));
220        jars[4] = new File(mavenPath("junit","junit","3.8.1"));
221        jars[5] = new File("lib/tools/ant-junit-1.6.5.jar");
222        jars[6] = new File("lib/tools/bsh-2.0b4.jar");
223        //jars[7] = new File("lib/tools/ant-apache-log4j.jar");
224        //jars[5] = new File(mavenPath("log4j","log4j","1.2.8"));
225
226        if (!isJDKToolsAvailable()) {  //Try and grab tools.jar.
227            if (jdkTools.exists()) {  //Add it to the other jars.
228                File[] tmp = new File[jars.length+1];
229                System.arraycopy(jars, 0, tmp, 0, jars.length);
230                tmp[jars.length] = jdkTools;
231                jars = tmp;
232            }
233            //Else we assume the JDK tools are in a jar under build/tools.
234        }
235        //Else the jdk tools are either in the bootclasspath or in the ext.
236        //In fact, the Build Tool is never invoked w/ -cp.
237       
238        return jars;
239    }
240
241    String mavenPath(String grp, String art, String ver){
242        return "lib/repository/"+grp+"/"+art+"/"+ver+"/"+art+"-"+ver+".jar";
243    }
244   
245    /**
246     * Sets the classpath to the libraries required by the Build Tool.
247     *
248     * @param buildJars The list of the required libraries.
249     */
250    private void setClasspath(File[] buildJars)
251    {
252        StringBuffer cp = new StringBuffer();
253        for (int i = 0; i < buildJars.length; ++i) {
254            cp.append(buildJars[i].getAbsolutePath());
255            cp.append(File.pathSeparator);
256        }
257        System.setProperty("java.class.path", cp.toString());
258        //The above wipes out the current classpath.  This is not a problem
259        //b/c the Build Tool is never invoked w/ -cp and . contains no other
260        //classes besides this one.
261    }
262   
263    private void setSystemProperties()
264    {
265        //Set Ant properties.
266        System.setProperty("ant.home", toolsDir.getAbsolutePath());
267        System.setProperty("ant.library.dir", toolsDir.getAbsolutePath());
268        System.setProperty("build.sysclasspath","last"); // or first, ignore, only
269        // This solves the problem of users having conflicting
270        // versions on their CLASSPATH
271       
272        //Set Xerces properties.
273        System.setProperty("javax.xml.parsers.DocumentBuilderFactory", 
274                           "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
275        System.setProperty("javax.xml.parsers.SAXParserFactory", 
276                           "org.apache.xerces.jaxp.SAXParserFactoryImpl");
277//        System.setProperty(
278//                "org.apache.xerces.xni.parser.XMLParserConfiguration",
279//                "org.apache.xerces.parsers.XML11Configuration");
280        System.setProperty("org.xml.sax.driver", 
281                           "org.apache.xerces.parsers.SAXParser");
282
283        //Set Xalan properties.
284        System.setProperty("javax.xml.transform.TransformerFactory", 
285                           "org.apache.xalan.processor.TransformerFactoryImpl");
286        System.setProperty("org.apache.xml.dtm.DTMManager", 
287                           "org.apache.xml.dtm.ref.DTMManagerDefault");
288    }
289   
290    /**
291     * Sets the environment and then starts Ant with the specified command line.
292     * 
293     * @param args Ant command line.
294     * @throws Exception If the Build Tool can't be started.
295     */
296    private void startAnt(String[] args)
297        throws Exception
298    {
299        try {
300            //Set system properties, then set classpath and replace classloader
301            //with one that is aware of the new classpath.
302            setSystemProperties();
303            File[] buildJars = locateBuildJars();
304            setClasspath(buildJars);
305            URL[] buildJarsURLs = new URL[buildJars.length];
306            for (int i = 0; i < buildJarsURLs.length; i++)
307                buildJarsURLs[i] = buildJars[i].toURL();
308            URLClassLoader loader = new URLClassLoader(buildJarsURLs);
309            Thread.currentThread().setContextClassLoader(loader);
310           
311            //Emacs logging
312            String[] tmp = new String[args.length+3];
313            System.arraycopy(args, 0, tmp, 0, args.length);
314            tmp[args.length]    = "-emacs";
315            tmp[args.length+1]  = "-logger";
316            tmp[args.length+2]  = "org.apache.tools.ant.NoBannerLogger";
317            args = tmp;
318
319            //Load and start Ant.
320            Class mainClass = loader.loadClass("org.apache.tools.ant.Main");
321            Method entry = mainClass.getMethod("startAnt", 
322                                new Class[] {String[].class, Properties.class, 
323                                             ClassLoader.class});
324            Object antMain = mainClass.newInstance();
325            entry.invoke(antMain, new Object[] {args, null, null});
326        } catch (Throwable t) {
327            throw new Exception("Couldn't start the Build Tool. \n"+
328                                t.getMessage(),t);
329        }
330    }
331
332    /**
333     * Grabs every file with a jar extension.
334     * @see java.io.FileFilter#accept(java.io.File)
335     */
336    public boolean accept(File pathname)
337    {
338        String name = pathname.getName();
339        if (name.toLowerCase().endsWith(".jar")) return true;
340        return false;
341    }
342   
343    /**
344     * Build Tool entry point.
345     *
346     * @param args Any valid Ant options and targets.
347     * @throws Exception If the Build Tool can't be started.
348     */
349    public static void main(String[] args) 
350        throws Exception
351    {
352        omero launcher = new omero();
353        launcher.startAnt(args);
354    }
355   
356}
Note: See TracBrowser for help on using the browser.

Download in other formats:

  • Plain Text
  • Original Format

Trac Powered

Powered by Trac 0.11
By Edgewall Software.

Visit the Trac open source project at
http://trac.edgewall.org/