Ignore:
Timestamp:
09/19/12 10:46:39 (12 years ago)
Author:
sherbold
Message:
  • converted JFCMonitor to Maven project
Location:
trunk/JFCMonitor
Files:
2 added
2 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/JFCMonitor

    • Property svn:ignore set to
      .settings
  • trunk/JFCMonitor/src/main/java/de/ugoe/cs/eventbench/jfcmonitor/JarLauncher.java

    r286 r822  
     1 
    12package de.ugoe.cs.eventbench.jfcmonitor; 
    23 
     
    1516/** 
    1617 * <p> 
    17  * Class that launches an executable Jar-file in the same thread and VM where 
    18  * the JarLauncher instance is created. The requirements on the Jar file are: 
     18 * Class that launches an executable Jar-file in the same thread and VM where the JarLauncher 
     19 * instance is created. The requirements on the Jar file are: 
    1920 * <li>Must contain a MANIFEST.</li> 
    20  * <li>The MANIFEST must define the main-class of the application ("Main-Class" 
    21  * entry).</li> 
    22  * <li>The MANIFEST must define the classpath of the application ("Class-Path" 
    23  * entry).</li> 
     21 * <li>The MANIFEST must define the main-class of the application ("Main-Class" entry).</li> 
     22 * <li>The MANIFEST must define the classpath of the application ("Class-Path" entry).</li> 
    2423 * </p> 
    2524 *  
     
    2928public class JarLauncher { 
    3029 
    31         /** 
    32          * <p> 
    33          * Name of the Jar file to be executed. 
    34          * </p> 
    35          */ 
    36         private String jarfile; 
    37  
    38         /** 
    39          * <p> 
    40          * Arguments for launching the Jar file. 
    41          * </p> 
    42          */ 
    43         private String[] args; 
    44  
    45         /** 
    46          * <p> 
    47          * Helper variable with the path to the working directory. 
    48          * </p> 
    49          */ 
    50         final String workingDir = System.getProperty("user.dir") + "/"; 
    51  
    52         /** 
    53          * <p> 
    54          * Internal variable used to store the classpath extracted from the Jar 
    55          * file's MANIFEST. 
    56          * </p> 
    57          */ 
    58         private String[] classPath = new String[] {}; 
    59  
    60         /** 
    61          * <p> 
    62          * Internal variable used to store the name (including package information) 
    63          * of the Jar file's main function extracted from the Jar file's MANIFEST. 
    64          * </p> 
    65          */ 
    66         private String mainClassName = ""; 
    67  
    68         /** 
    69          * <p> 
    70          * Inner class that defines an exception that is thrown if launching the 
    71          * application in the Jar file fails. 
    72          * </p> 
    73          *  
    74          * @author Steffen Herbold 
    75          * @version 1.0 
    76          */ 
    77         private static class JarLaunchException extends Exception { 
    78  
    79                 /** 
    80                  * <p> 
    81                  * Id for object serialization. 
    82                  * </p> 
    83                  */ 
    84                 private static final long serialVersionUID = 1L; 
    85  
    86                 /** 
    87                  * <p> 
    88                  * Constructor. Creates a new JarLaunchException. 
    89                  * </p> 
    90                  *  
    91                  * @param string 
    92                  *            error message of the exception 
    93                  */ 
    94                 public JarLaunchException(String string) { 
    95                         super(string); 
    96                 } 
    97  
    98                 /** 
    99                  * <p> 
    100                  * Constructor. Creates a new JarLaunchException as a copy of an 
    101                  * existing exception. 
    102                  * </p> 
    103                  *  
    104                  * @param e 
    105                  *            exception that is copied 
    106                  */ 
    107                 public JarLaunchException(Exception e) { 
    108                         super(e); 
    109                 } 
    110  
    111         } 
    112  
    113         /** 
    114          * <p> 
    115          * Constructor. Creates a new JarLauncher. 
    116          * </p> 
    117          *  
    118          * @param jarfile 
    119          *            file to be launched; must not be complete path but in relation 
    120          *            to the current working directory 
    121          * @param args 
    122          *            arguments with which the main function of the Jar file is 
    123          *            called 
    124          */ 
    125         public JarLauncher(String jarfile, String[] args) { 
    126                 this.jarfile = jarfile; 
    127                 this.args = Arrays.copyOf(args, args.length); 
    128         } 
    129  
    130         /** 
    131          * <p> 
    132          * Executes the main function of the Jar file associated with this launcher. 
    133          * </p> 
    134          */ 
    135         public void exec() { 
    136                 try { 
    137                         getInfoFromJar(); 
    138                         initClassLoader(); 
    139                         runMain(); 
    140                 } catch (JarLaunchException e) { 
    141                         System.err.println("Failure to launch application."); 
    142                         System.err.println(e.getMessage()); 
    143                 } 
    144         } 
    145  
    146         /** 
    147          * <p> 
    148          * Retrieves the classpath and main function from the Jar file's MANIFEST. 
    149          * </p> 
    150          *  
    151          * @throws JarLaunchException 
    152          *             thrown if reading of Jar file or MANIFEST fails 
    153          */ 
    154         private void getInfoFromJar() throws JarLaunchException { 
    155                 JarInputStream jarInputStream; 
    156                 try { 
    157                         jarInputStream = new JarInputStream(new FileInputStream(workingDir 
    158                                         + jarfile)); 
    159                 } catch (FileNotFoundException e) { 
    160                         throw new JarLaunchException(e); 
    161                 } catch (IOException e) { 
    162                         throw new JarLaunchException(e); 
    163                 } 
    164                 Manifest manifest = jarInputStream.getManifest(); 
    165                 mainClassName = manifest.getMainAttributes().getValue("Main-Class"); 
    166                 String jarClassPath = manifest.getMainAttributes().getValue( 
    167                                 "Class-Path"); 
    168                 String[] jarClassPathElements = jarClassPath.split(" "); 
    169                 classPath = new String[jarClassPathElements.length]; 
    170                 for (int i = 0; i < jarClassPathElements.length; i++) { 
    171                         classPath[i] = "file:" + workingDir + jarClassPathElements[i]; 
    172                 } 
    173                 try { 
    174                         jarInputStream.close(); 
    175                 } catch (IOException e) { 
    176                         e.printStackTrace(); 
    177                 } 
    178         } 
    179  
    180         /** 
    181          * <p> 
    182          * Modifies the {@link ClassLoader} of the current VM such that it includes 
    183          * the class path defined in the Jar file's MANIFEST. 
    184          * </p> 
    185          *  
    186          * @throws JarLaunchException 
    187          *             thrown if modification of {@link ClassLoader} fails. 
    188          */ 
    189         private void initClassLoader() throws JarLaunchException { 
    190                 URLClassLoader classLoader = (URLClassLoader) ClassLoader 
    191                                 .getSystemClassLoader(); 
    192                 Method method; 
    193                 try { 
    194                         method = URLClassLoader.class.getDeclaredMethod("addURL", 
    195                                         new Class[] { URL.class }); 
    196                 } catch (SecurityException e) { 
    197                         throw new JarLaunchException( 
    198                                         "addURL method of URLClassLoader not accessible via reflection."); 
    199                 } catch (NoSuchMethodException e) { 
    200                         throw new JarLaunchException( 
    201                                         "URLClassLoader does not have addURL method. Should be impossible!!"); 
    202                 } 
    203                 method.setAccessible(true); 
    204  
    205                 try { 
    206                         method.invoke(classLoader, new Object[] { new URL("file:" 
    207                                         + workingDir + jarfile) }); 
    208                         for (String element : classPath) { 
    209                                 method.invoke(classLoader, new Object[] { new URL(element) }); 
    210                         } 
    211                 } catch (IllegalArgumentException e) { 
    212                         throw new JarLaunchException( 
    213                                         "Illegal arguments for addURL method. Should be impossible!!"); 
    214                 } catch (MalformedURLException e) { 
    215                         throw new JarLaunchException(e); 
    216                 } catch (IllegalAccessException e) { 
    217                         throw new JarLaunchException( 
    218                                         "addURL method of URLClassLoader not accessible via reflection."); 
    219                 } catch (InvocationTargetException e) { 
    220                         e.printStackTrace(); 
    221                 } 
    222         } 
    223  
    224         /** 
    225          * <p> 
    226          * Executes the main function. 
    227          * </p> 
    228          *  
    229          * @throws JarLaunchException 
    230          *             thrown if execution of main function fails or the main 
    231          *             function itself throws an exception 
    232          */ 
    233         private void runMain() throws JarLaunchException { 
    234                 Class<?> mainClass; 
    235                 try { 
    236                         mainClass = Class.forName(mainClassName); 
    237                 } catch (ClassNotFoundException e) { 
    238                         throw new JarLaunchException("Main class not found: " 
    239                                         + mainClassName); 
    240                 } 
    241                 Method mainMethod; 
    242                 try { 
    243                         mainMethod = mainClass.getMethod("main", 
    244                                         new Class[] { String[].class }); 
    245                 } catch (SecurityException e) { 
    246                         throw new JarLaunchException("Main method not accessible."); 
    247                 } catch (NoSuchMethodException e) { 
    248                         throw new JarLaunchException("Main method not found."); 
    249                 } 
    250                 try { 
    251                         mainMethod.invoke(null, new Object[] { args }); 
    252                 } catch (IllegalArgumentException e) { 
    253                         throw new JarLaunchException( 
    254                                         "Illegal arguments for main method. Should be impossible!!"); 
    255                 } catch (IllegalAccessException e) { 
    256                         throw new JarLaunchException("Main method not accessible."); 
    257                 } catch (InvocationTargetException e) { 
    258                         throw new JarLaunchException(e); 
    259                 } 
    260         } 
     30    /** 
     31     * <p> 
     32     * Name of the Jar file to be executed. 
     33     * </p> 
     34     */ 
     35    private String jarfile; 
     36 
     37    /** 
     38     * <p> 
     39     * Arguments for launching the Jar file. 
     40     * </p> 
     41     */ 
     42    private String[] args; 
     43 
     44    /** 
     45     * <p> 
     46     * Helper variable with the path to the working directory. 
     47     * </p> 
     48     */ 
     49    final String workingDir = System.getProperty("user.dir") + "/"; 
     50 
     51    /** 
     52     * <p> 
     53     * Internal variable used to store the classpath extracted from the Jar file's MANIFEST. 
     54     * </p> 
     55     */ 
     56    private String[] classPath = new String[] { }; 
     57 
     58    /** 
     59     * <p> 
     60     * Internal variable used to store the name (including package information) of the Jar file's 
     61     * main function extracted from the Jar file's MANIFEST. 
     62     * </p> 
     63     */ 
     64    private String mainClassName = ""; 
     65 
     66    /** 
     67     * <p> 
     68     * Inner class that defines an exception that is thrown if launching the application in the Jar 
     69     * file fails. 
     70     * </p> 
     71     *  
     72     * @author Steffen Herbold 
     73     * @version 1.0 
     74     */ 
     75    private static class JarLaunchException extends Exception { 
     76 
     77        /** 
     78         * <p> 
     79         * Id for object serialization. 
     80         * </p> 
     81         */ 
     82        private static final long serialVersionUID = 1L; 
     83 
     84        /** 
     85         * <p> 
     86         * Constructor. Creates a new JarLaunchException. 
     87         * </p> 
     88         *  
     89         * @param string 
     90         *            error message of the exception 
     91         */ 
     92        public JarLaunchException(String string) { 
     93            super(string); 
     94        } 
     95 
     96        /** 
     97         * <p> 
     98         * Constructor. Creates a new JarLaunchException as a copy of an existing exception. 
     99         * </p> 
     100         *  
     101         * @param e 
     102         *            exception that is copied 
     103         */ 
     104        public JarLaunchException(Exception e) { 
     105            super(e); 
     106        } 
     107 
     108    } 
     109 
     110    /** 
     111     * <p> 
     112     * Constructor. Creates a new JarLauncher. 
     113     * </p> 
     114     *  
     115     * @param jarfile 
     116     *            file to be launched; must not be complete path but in relation to the current 
     117     *            working directory 
     118     * @param args 
     119     *            arguments with which the main function of the Jar file is called 
     120     */ 
     121    public JarLauncher(String jarfile, String[] args) { 
     122        this.jarfile = jarfile; 
     123        this.args = Arrays.copyOf(args, args.length); 
     124    } 
     125 
     126    /** 
     127     * <p> 
     128     * Executes the main function of the Jar file associated with this launcher. 
     129     * </p> 
     130     */ 
     131    public void exec() { 
     132        try { 
     133            getInfoFromJar(); 
     134            initClassLoader(); 
     135            runMain(); 
     136        } 
     137        catch (JarLaunchException e) { 
     138            System.err.println("Failure to launch application."); 
     139            System.err.println(e.getMessage()); 
     140        } 
     141    } 
     142 
     143    /** 
     144     * <p> 
     145     * Retrieves the classpath and main function from the Jar file's MANIFEST. 
     146     * </p> 
     147     *  
     148     * @throws JarLaunchException 
     149     *             thrown if reading of Jar file or MANIFEST fails 
     150     */ 
     151    private void getInfoFromJar() throws JarLaunchException { 
     152        JarInputStream jarInputStream; 
     153        try { 
     154            jarInputStream = new JarInputStream(new FileInputStream(workingDir + jarfile)); 
     155        } 
     156        catch (FileNotFoundException e) { 
     157            throw new JarLaunchException(e); 
     158        } 
     159        catch (IOException e) { 
     160            throw new JarLaunchException(e); 
     161        } 
     162        Manifest manifest = jarInputStream.getManifest(); 
     163        mainClassName = manifest.getMainAttributes().getValue("Main-Class"); 
     164        String jarClassPath = manifest.getMainAttributes().getValue("Class-Path"); 
     165        String[] jarClassPathElements = jarClassPath.split(" "); 
     166        classPath = new String[jarClassPathElements.length]; 
     167        for (int i = 0; i < jarClassPathElements.length; i++) { 
     168            classPath[i] = "file:" + workingDir + jarClassPathElements[i]; 
     169        } 
     170        try { 
     171            jarInputStream.close(); 
     172        } 
     173        catch (IOException e) { 
     174            e.printStackTrace(); 
     175        } 
     176    } 
     177 
     178    /** 
     179     * <p> 
     180     * Modifies the {@link ClassLoader} of the current VM such that it includes the class path 
     181     * defined in the Jar file's MANIFEST. 
     182     * </p> 
     183     *  
     184     * @throws JarLaunchException 
     185     *             thrown if modification of {@link ClassLoader} fails. 
     186     */ 
     187    private void initClassLoader() throws JarLaunchException { 
     188        URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 
     189        Method method; 
     190        try { 
     191            method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] 
     192                { URL.class }); 
     193        } 
     194        catch (SecurityException e) { 
     195            throw new JarLaunchException( 
     196                                         "addURL method of URLClassLoader not accessible via reflection."); 
     197        } 
     198        catch (NoSuchMethodException e) { 
     199            throw new JarLaunchException( 
     200                                         "URLClassLoader does not have addURL method. Should be impossible!!"); 
     201        } 
     202        method.setAccessible(true); 
     203 
     204        try { 
     205            method.invoke(classLoader, new Object[] 
     206                { new URL("file:" + workingDir + jarfile) }); 
     207            for (String element : classPath) { 
     208                method.invoke(classLoader, new Object[] 
     209                    { new URL(element) }); 
     210            } 
     211        } 
     212        catch (IllegalArgumentException e) { 
     213            throw new JarLaunchException( 
     214                                         "Illegal arguments for addURL method. Should be impossible!!"); 
     215        } 
     216        catch (MalformedURLException e) { 
     217            throw new JarLaunchException(e); 
     218        } 
     219        catch (IllegalAccessException e) { 
     220            throw new JarLaunchException( 
     221                                         "addURL method of URLClassLoader not accessible via reflection."); 
     222        } 
     223        catch (InvocationTargetException e) { 
     224            e.printStackTrace(); 
     225        } 
     226    } 
     227 
     228    /** 
     229     * <p> 
     230     * Executes the main function. 
     231     * </p> 
     232     *  
     233     * @throws JarLaunchException 
     234     *             thrown if execution of main function fails or the main function itself throws an 
     235     *             exception 
     236     */ 
     237    private void runMain() throws JarLaunchException { 
     238        Class<?> mainClass; 
     239        try { 
     240            mainClass = Class.forName(mainClassName); 
     241        } 
     242        catch (ClassNotFoundException e) { 
     243            throw new JarLaunchException("Main class not found: " + mainClassName); 
     244        } 
     245        Method mainMethod; 
     246        try { 
     247            mainMethod = mainClass.getMethod("main", new Class[] 
     248                { String[].class }); 
     249        } 
     250        catch (SecurityException e) { 
     251            throw new JarLaunchException("Main method not accessible."); 
     252        } 
     253        catch (NoSuchMethodException e) { 
     254            throw new JarLaunchException("Main method not found."); 
     255        } 
     256        try { 
     257            mainMethod.invoke(null, new Object[] 
     258                { args }); 
     259        } 
     260        catch (IllegalArgumentException e) { 
     261            throw new JarLaunchException( 
     262                                         "Illegal arguments for main method. Should be impossible!!"); 
     263        } 
     264        catch (IllegalAccessException e) { 
     265            throw new JarLaunchException("Main method not accessible."); 
     266        } 
     267        catch (InvocationTargetException e) { 
     268            throw new JarLaunchException(e); 
     269        } 
     270    } 
    261271} 
Note: See TracChangeset for help on using the changeset viewer.