| Jdk |

    1   /*
    2    *  Jdk.java
    3    *
    4    *  Copyright (c) 1998-2001, The University of Sheffield.
    5    *
    6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
    7    *  software, licenced under the GNU Library General Public License,
    8    *  Version 2, June 1991 (in the distribution as file licence.html,
    9    *  and also available at http://gate.ac.uk/gate/licence.html).
    10   *
    11   *  Hamish Cunningham, 04/05/00
    12   *
    13   *  $Id: Jdk.java,v 1.13 2001/09/20 13:32:30 hamish Exp $
    14   *
    15   *  Developer notes:
    16   *
    17   *  It would be better to have a compile method that took two arrays
    18   *  of string for a set of classes, and to compile all in one go
    19   *
    20   *  Also, should change gate.jape.RHS to use the methods here for
    21   *  defining and instantiating classes.
    22   *
    23   * We might also try dispensing with javacompiler.jar and overriding
    24   * File instead to take input from string, then using the normal
    25   * Sun compiler.
    26   */
    27
    28  package gate.util;
    29
    30  import java.io.*;
    31  import java.lang.reflect.*;
    32  import java.util.*;
    33
    34  import sun.toolsx.java.*;
    35  import sun.toolsx.javac.*;
    36
    37  import gate.*;
    38
    39
    40  /** Jdk encapsulates some utilities for poking around in your Java
    41    * environment.
    42    */
    43  public class Jdk {
    44
    45    /** Debug flag */
    46    private static final boolean DEBUG = false;
    47
    48    /** Anonymous construction. */
    49    public Jdk() {
    50    } // anon constructor
    51
    52    /** main. */
    53    public static void main(String[] args) throws GateException {
    54      Jdk jdk = new Jdk();
    55      jdk.testMe();
    56    } // main
    57
    58    /** Test method. Better to use TestJdk via the TestGate suite instead. */
    59    public void testMe() throws GateException {
    60      Out.println("Testing gate.util.Jdk");
    61      Out.println("getToolsHome(): " + getToolsHome());
    62    } // testMe
    63
    64    /** Possible locations of the tools <CODE>bin</CODE> directory.
    65      * (relative to "java.home").
    66      */
    67    private String[] toolsLocations = {
    68      "/../bin",    // jdk1.2 final gives java.home as the jre directory)
    69      "/bin",   // (jdk1.1 and 1.2 betas give java.home as the jdk directory)
    70      "",     // getting desperate!
    71      "/../../bin"  // e.g. we're running a JRE that's installed beside a JDK
    72    };
    73
    74    /** Returns a File specifying the location of the JDK tools, i.e.
    75      * the location of programs like <CODE>java, javac, jar</CODE>. It
    76      * assumes that if it finds <CODE>javac</CODE> or <CODE>javac.exe</CODE>
    77      * then it found the tools home.
    78      */
    79    public File getToolsHome() throws GateException {
    80      File javaHome = new File(System.getProperty("java.home"));
    81      if(! javaHome.exists())
    82        throw new GateException(
    83          "directory " + javaHome.getPath() + " doesn't exist!"
    84        );
    85
    86      // try the likely spots
    87      for(int i=0; i<toolsLocations.length; i++) {
    88        try {
    89          File javac = new
    90            File(javaHome.getCanonicalPath() + toolsLocations[i] + "/javac");
    91          if(javac.exists())
    92            return new File(javaHome.getCanonicalPath() + toolsLocations[i]);
    93          javac = new
    94            File(javaHome.getCanonicalPath() + toolsLocations[i] + "/javac.exe");
    95          if(javac.exists())
    96            return new File(javaHome.getCanonicalPath() + toolsLocations[i]);
    97        } catch(IOException e) {
    98        }
    99      }
    100
    101     throw new GateException(
    102       "Found no javac or javac.exe in likely places relative to java.home"
    103     );
    104   } // getToolsHome
    105
    106   /** Compile a class from its source code string.
    107     * @param className should have the package path to the source, e.g.
    108     * com/thing/MyClass.java.
    109     */
    110   public byte[] compile(String javaCode, String className)
    111   throws GateException {
    112     sun.toolsx.javac.Main compiler = new sun.toolsx.javac.Main(
    113       System.out, "gate.util.Jdk"
    114     );
    115     String argv[] = new String[5];
    116     argv[0] = "-classpath";
    117     argv[1] = System.getProperty("java.class.path");
    118     argv[2] = "-nodisk";
    119     argv[3] = className;
    120     argv[4] = javaCode;
    121     compiler.compile(argv);
    122     List compilerOutput = compiler.getCompilerOutput();
    123
    124     Iterator iter = compilerOutput.iterator();
    125     while(iter.hasNext()) {
    126       byte[] classBytes = (byte[]) iter.next();
    127
    128     if(classBytes == null || classBytes.length == 0)
    129       throw new GateException("no bytes returned from compiler");
    130
    131       // possibly this test is wrong - what about sources that contain
    132       // multiple classes or have inner classes? at any rate we currently
    133       // have no way to return them
    134     if(iter.hasNext())
    135       throw
    136         new GateException("only compiled one class but got multiple results");
    137
    138       return classBytes;
    139     } // while
    140
    141     throw new GateException("no compiler output");
    142   } // compile(String, String)
    143
    144
    145   /** Read the bytes for a class.
    146     * @param classFileName should have the path to the .class
    147     * file, e.g. com/thing/MyClass.class.
    148     */
    149   public byte[] readClass(String classFileName) throws GateException {
    150     byte[] classBytes = null;
    151     try {
    152       File f = new File(classFileName);
    153       FileInputStream fis = new FileInputStream(classFileName);
    154       classBytes = new byte[(int) f.length()];
    155       fis.read(classBytes, 0, (int) f.length());
    156       fis.close();
    157     } catch(IOException e) {
    158       throw(new GateException("couldn't read class bytes: " + e));
    159     }
    160
    161     return classBytes;
    162   } // readClass
    163
    164   /** Load a class.
    165     * @param classFileName is the path to the .class
    166     * file, e.g. com/thing/MyClass.class.
    167     */
    168   public Class loadActionClass(String classFileName) throws GateException {
    169     Class theClass = null;
    170     try {
    171       theClass = Gate.getClassLoader().loadClass(classFileName, true);
    172     } catch(Exception e) {
    173       e.printStackTrace();
    174       throw new GateException(
    175         "couldn't load " + classFileName + ": " + e.getMessage()
    176       );
    177     }
    178
    179     return theClass;
    180   } // loadActionClass
    181
    182   /** Define a class from its qualified name and
    183     * the byte array of its binary.
    184     * @param classQualified name should be e.g. com.thing.MyClass.
    185     * @param contains the bytes from a .class file.
    186     */
    187   public Class defineClass(String classQualifiedName, byte[] classBytes)
    188   throws GateException {
    189     Class theClass = null;
    190     try {
    191       theClass = Gate.getClassLoader().defineGateClass(
    192         classQualifiedName, classBytes, 0, classBytes.length
    193       );
    194     } catch(ClassFormatError e) {
    195       e.printStackTrace();
    196       throw new GateException(
    197         "couldn't define " + classQualifiedName + ": " + e
    198       );
    199
    200     }
    201     Gate.getClassLoader().resolveGateClass(theClass);
    202     return theClass;
    203   } // defineClass
    204
    205   /** Create an instance of a class. */
    206   public Object instantiateClass(Class theClass) throws GateException {
    207     Object theObject = null;
    208     try {
    209       theObject = theClass.newInstance();
    210     } catch(Exception e) {
    211       throw new GateException(
    212         "couldn't create instance of class " + theClass + ": " + e
    213       );
    214     }
    215
    216     return theObject;
    217   } // instantiateClass
    218
    219 } // Jdk
    220
    221
    222
    223

| Jdk |