001 package com.croftsoft.core.lang.classloader; 002 003 import java.awt.*; 004 import java.io.*; 005 import java.lang.reflect.*; 006 import java.net.*; 007 import java.util.*; 008 009 /********************************************************************* 010 * <P> 011 * Upgrade this source code when the switch is made from Java 1.1 to 012 * Java 1.2. 013 * <P> 014 * <B> 015 * References 016 * </B> 017 * Scott Oaks, <U>Java Security</U>, O'Reilly, 1998. 018 * <P> 019 * @version 020 * 1998-09-06 021 * @author 022 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 023 *********************************************************************/ 024 025 public class NetClassLoader extends CustomClassLoader 026 ////////////////////////////////////////////////////////////////////// 027 ////////////////////////////////////////////////////////////////////// 028 { 029 030 protected URL codebaseURL; 031 032 ////////////////////////////////////////////////////////////////////// 033 ////////////////////////////////////////////////////////////////////// 034 035 /********************************************************************* 036 * Loads a remote class and launches its main() method. 037 * 038 * @param 039 * Command-line arguments: 040 * <OL> 041 * <LI> The URL for the codebase. 042 * <LI> The name of the class with the "main(args)" method. 043 * <LI> Subsequent arguments to be passed to the invoked main method. 044 * </OL> 045 * Example 046 *********************************************************************/ 047 public static void main ( String [ ] args ) 048 throws Exception 049 ////////////////////////////////////////////////////////////////////// 050 { 051 String [ ] shiftedArgs = new String [ args.length - 2 ]; 052 for ( int i = 2; i < args.length; i++ ) 053 { 054 shiftedArgs [ i - 2 ] = args [ i ]; 055 } 056 057 launchMain ( args [ 0 ], args [ 1 ], shiftedArgs ); 058 } 059 060 /********************************************************************* 061 * Loads a remote class and launches its main() method. 062 *********************************************************************/ 063 public static void launchMain ( 064 String codebaseURLName, 065 String mainClassName, 066 String [ ] args ) 067 throws ClassNotFoundException, 068 IllegalAccessException, 069 MalformedURLException 070 ////////////////////////////////////////////////////////////////////// 071 { 072 URL codebaseURL = new URL ( codebaseURLName ); 073 ClassLoader classLoader = new NetClassLoader ( codebaseURL ); 074 Class c = classLoader.loadClass ( mainClassName ); 075 invokeMain ( c, args ); 076 } 077 078 public static void invokeMain ( Class c, String [ ] args ) 079 throws IllegalAccessException 080 ////////////////////////////////////////////////////////////////////// 081 { 082 Method method; 083 084 try 085 { 086 method = c.getMethod ( "main", 087 new Class [ ] { String [ ].class } ); 088 } 089 catch ( NoSuchMethodException ex ) 090 { 091 System.err.println ( "No main() method in class \"" 092 + c.getName ( ) + "\"." ); 093 return; 094 } 095 096 try 097 { 098 method.invoke ( null, new Object [ ] { args } ); 099 } 100 catch ( InvocationTargetException ex ) 101 { 102 Throwable t = ex.getTargetException ( ); 103 System.err.println ( 104 "\"main()\" method exited with exception \"" + t + "\"." ); 105 t.printStackTrace ( ); 106 } 107 } 108 109 /********************************************************************* 110 * Ex: "http://www.mysticmayhem.com/lib/" 111 *********************************************************************/ 112 public NetClassLoader ( URL codebaseURL ) 113 ////////////////////////////////////////////////////////////////////// 114 { 115 this.codebaseURL = codebaseURL; 116 } 117 118 protected byte [ ] loadClassData ( String name ) 119 ////////////////////////////////////////////////////////////////////// 120 { 121 try 122 { 123 String pathName = name.replace ( '.', '/' ) + ".class"; 124 BufferedInputStream in = new BufferedInputStream ( 125 getResourceAsStream ( pathName ) ); 126 if ( in == null ) return null; 127 ByteArrayOutputStream out = new ByteArrayOutputStream ( ); 128 int i; 129 while ( ( i = in.read ( ) ) > -1 ) out.write ( i ); 130 in.close ( ); 131 return out.toByteArray ( ); 132 } 133 catch ( Exception ex ) { ex.printStackTrace ( ); return null; } 134 } 135 136 /********************************************************************* 137 *********************************************************************/ 138 public URL getResource ( String name ) 139 ////////////////////////////////////////////////////////////////////// 140 { 141 try 142 { 143 return new URL ( codebaseURL, name ); 144 } 145 catch ( Exception ex ) { ex.printStackTrace ( ); return null; } 146 } 147 148 /********************************************************************* 149 * Loads a stream from the URL given by getResource(name). 150 * Does not use a cache. 151 *********************************************************************/ 152 public InputStream getResourceAsStream ( String name ) 153 ////////////////////////////////////////////////////////////////////// 154 { 155 try 156 { 157 URL url = getResource ( name ); 158 System.out.println ( "Loading \"" + url + "\"..." ); 159 URLConnection urlConnection = url.openConnection ( ); 160 if ( urlConnection instanceof HttpURLConnection ) 161 { 162 HttpURLConnection httpURLConnection 163 = ( HttpURLConnection ) urlConnection; 164 httpURLConnection.setFollowRedirects ( true ); 165 httpURLConnection.setRequestMethod ( "GET" ); 166 int responseCode = httpURLConnection.getResponseCode ( ); 167 System.out.println ( 168 httpURLConnection.getResponseMessage ( ) 169 + ", " + httpURLConnection.getContentLength ( ) + " bytes" 170 + ", " + new Date ( httpURLConnection.getDate ( ) ) 171 + ", " + new Date ( httpURLConnection.getLastModified ( ) ) ); 172 if ( responseCode != HttpURLConnection.HTTP_OK ) 173 { 174 return null; 175 } 176 } 177 return urlConnection.getInputStream ( ); 178 } 179 catch ( Exception ex ) { ex.printStackTrace ( ); return null; } 180 } 181 182 /********************************************************************* 183 * Creates the image by calling getResourceAsStream(imageName). 184 *********************************************************************/ 185 public Image createImage ( String imageName ) 186 throws IOException 187 ////////////////////////////////////////////////////////////////////// 188 { 189 InputStream inputStream = getResourceAsStream ( imageName ); 190 BufferedInputStream in = new BufferedInputStream ( inputStream ); 191 ByteArrayOutputStream out = new ByteArrayOutputStream ( ); 192 int i; 193 while ( ( i = in.read ( ) ) > -1 ) out.write ( i ); 194 byte [ ] imageData = out.toByteArray ( ); 195 out.close ( ); 196 in.close ( ); 197 return Toolkit.getDefaultToolkit ( ).createImage ( imageData ); 198 } 199 200 ////////////////////////////////////////////////////////////////////// 201 ////////////////////////////////////////////////////////////////////// 202 }