KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > agent > client > util > types > JavaApplicationType


1 /* HEADER */
2 package com.sslexplorer.agent.client.util.types;
3
4 import java.io.File JavaDoc;
5 import java.io.IOException JavaDoc;
6 import java.lang.reflect.Method JavaDoc;
7 import java.text.MessageFormat JavaDoc;
8 import java.util.Enumeration JavaDoc;
9 import java.util.Vector JavaDoc;
10
11 import com.sslexplorer.agent.client.util.AbstractApplicationLauncher;
12 import com.sslexplorer.agent.client.util.ApplicationLauncherEvents;
13 import com.sslexplorer.agent.client.util.ApplicationType;
14 import com.sslexplorer.agent.client.util.ProcessMonitor;
15 import com.sslexplorer.agent.client.util.Utils;
16 import com.sslexplorer.agent.client.util.XMLElement;
17
18 /**
19  * Application type that locates a suitable JVM and launchs a Java application.
20  *
21  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
22  */

23 public class JavaApplicationType implements ApplicationType {
24
25     // Protected instance variables
26

27     protected ApplicationLauncherEvents events;
28     protected AbstractApplicationLauncher launcher;
29
30     // Prive instance variables
31

32     private String JavaDoc classpath = ""; //$NON-NLS-1$
33
private String JavaDoc mainclass;
34     private File JavaDoc workingDir;
35     private String JavaDoc[] jvm;
36     private Vector JavaDoc programArgs = new Vector JavaDoc();
37     private Vector JavaDoc jvmArgs = new Vector JavaDoc();
38     private Vector JavaDoc envVars = new Vector JavaDoc();
39     private ProcessMonitor process;
40     private String JavaDoc javaLibraryPath = ""; //$NON-NLS-1$
41

42     /*
43      * (non-Javadoc)
44      *
45      * @see com.sslexplorer.vpn.util.ApplicationType#prepare(com.sslexplorer.vpn.util.ApplicationLauncher,
46      * com.sslexplorer.vpn.util.XMLElement)
47      */

48     public void prepare(AbstractApplicationLauncher launcher, ApplicationLauncherEvents events, XMLElement element)
49                     throws IOException JavaDoc {
50
51         if (events != null)
52             events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.processingForJavaType"), new Object JavaDoc[] { element.getName() })); //$NON-NLS-1$
53

54         this.launcher = launcher;
55         this.events = events;
56
57         if (element.getName().equals(getTypeName())) { //$NON-NLS-1$
58

59             String JavaDoc jre = (String JavaDoc) element.getAttribute("jre"); //$NON-NLS-1$
60

61             if (events != null)
62                 events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.checkingJRE"), //$NON-NLS-1$
63
new Object JavaDoc[] { jre }));
64
65             if (!Utils.checkVersion(jre)) {
66                 String JavaDoc mesage = Messages.getString("JavaApplicationType.applicationRequires", new Object JavaDoc[] { jre }); //$NON-NLS-1$
67
if (events != null) {
68                     events.error(mesage);
69                 }
70                 return;
71             }
72
73             /**
74              * LDP - Don't reset the classpath as this stops extended extensions
75              * (such as the agent extension itself) from adding addtional
76              * classpath entries.
77              */

78             // Reset the classpath
79
// classpath = "";
80
if (System.getProperty("java.version").startsWith("1.1") //$NON-NLS-1$ //$NON-NLS-2$
81
&& !System.getProperty("java.vendor").startsWith( //$NON-NLS-1$
82
"Microsoft")) //$NON-NLS-1$
83
classpath = System.getProperty("java.home") //$NON-NLS-1$
84
+ File.pathSeparator
85                     + "lib" + File.pathSeparator //$NON-NLS-1$
86
+ "classes.zip"; //$NON-NLS-1$
87

88             Enumeration JavaDoc e = element.enumerateChildren();
89
90             while (e.hasMoreElements()) {
91                 XMLElement el = (XMLElement) e.nextElement();
92
93                 if (el.getName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$
94
buildClassPath(el);
95                 } else if (el.getName().equalsIgnoreCase("main")) { //$NON-NLS-1$
96
mainclass = (String JavaDoc) el.getAttribute("class"); //$NON-NLS-1$
97
if (events != null)
98                         events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.mainClass"), new Object JavaDoc[] { mainclass })); //$NON-NLS-1$
99
String JavaDoc dir = (String JavaDoc) el.getAttribute("dir"); //$NON-NLS-1$
100
if (events != null)
101                         events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.directoryIs"), new Object JavaDoc[] { dir })); //$NON-NLS-1$
102
if (dir != null) {
103                         workingDir = new File JavaDoc(launcher.replaceTokens(dir));
104                     } else {
105                         workingDir = null;
106                     }
107                     buildProgramArguments(el);
108                 }
109             }
110
111             if (events != null)
112                 events.debug(Messages.getString("JavaApplicationType.finishedPreparingDescriptor")); //$NON-NLS-1$
113
} else {
114             if (events != null)
115                 events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.ignoringTagAsNotJavaTag"), new Object JavaDoc[] { element.getName() })); //$NON-NLS-1$
116
}
117
118     }
119
120     /*
121      * (non-Javadoc)
122      *
123      * @see com.sslexplorer.vpn.util.ApplicationType#start()
124      */

125     public void start() {
126         execute(classpath, mainclass, workingDir);
127     }
128
129     /**
130      * Add an entry to the classpath.
131      *
132      * @param e classpath element
133      * @throws IOException
134      */

135     public void addClasspathEntry(XMLElement e) throws IOException JavaDoc {
136         addClasspathEntry(e, null);
137     }
138
139     /**
140      * Add an entry to the classpath.
141      *
142      * @param e classpath element
143      * @param app application
144      * @throws IOException
145      */

146     public void addClasspathEntry(XMLElement e, String JavaDoc app) throws IOException JavaDoc {
147
148         String JavaDoc shared = (String JavaDoc) e.getAttribute("shared"); //$NON-NLS-1$
149
File JavaDoc entry;
150         if (shared != null && shared.equalsIgnoreCase("true")) { //$NON-NLS-1$
151
entry = launcher.addShared(e);
152         } else {
153             entry = launcher.addFile(e, app);
154         }
155
156         if (entry != null && events != null)
157             events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.addingToClasspath"), new Object JavaDoc[] { entry.getAbsolutePath() })); //$NON-NLS-1$ //$NON-NLS-2$
158

159         // The entry may be null because were not the correct platform
160
if (entry != null)
161             classpath += (!classpath.equals("") ? File.pathSeparator : "") //$NON-NLS-1$ //$NON-NLS-2$
162
+ entry.getAbsolutePath();
163     }
164
165     protected void buildClassPath(XMLElement element) throws IOException JavaDoc {
166         buildClassPath(element, null);
167     }
168
169     protected void buildClassPath(XMLElement element, String JavaDoc app) throws IOException JavaDoc {
170
171         if (events != null)
172             events.debug(Messages.getString("JavaApplicationType.buildingClasspath")); //$NON-NLS-1$
173
Enumeration JavaDoc en = element.enumerateChildren();
174         XMLElement e;
175
176         while (en.hasMoreElements()) {
177             e = (XMLElement) en.nextElement();
178             if (e.getName().equalsIgnoreCase("jar")) { //$NON-NLS-1$
179
if (AbstractApplicationLauncher.checkCondition(this, e, launcher.getDescriptorParams())) {
180                     addClasspathEntry(e, app);
181                 }
182             } else if (e.getName().equals("if")) { //$NON-NLS-1$
183
if (AbstractApplicationLauncher.checkCondition(this, e, launcher.getDescriptorParams())) {
184                     buildClassPath(e, app);
185                 }
186             } else
187                 throw new IOException JavaDoc(MessageFormat.format(Messages.getString("JavaApplicationType.invalidElementInClasspath"), new Object JavaDoc[] { e.getName() })); //$NON-NLS-1$
188
}
189
190     }
191
192     protected void addArgument(String JavaDoc arg) {
193         if (arg != null)
194             programArgs.addElement(launcher.replaceTokens(arg));
195     }
196
197     protected void addEnvVar(String JavaDoc envVar) {
198         if (envVar != null)
199             envVars.addElement(launcher.replaceTokens(envVar));
200     }
201
202     protected void addJVMArgument(String JavaDoc arg) {
203         if (arg != null) {
204
205             if (arg.startsWith("java.library.path")) { //$NON-NLS-1$
206
int idx = arg.indexOf('=');
207
208                 if (idx > -1) {
209                     String JavaDoc val = arg.substring(idx + 1).replace('/', File.separatorChar);
210                     javaLibraryPath += (javaLibraryPath.equals("") ? val : System.getProperty("path.separator") + val); //$NON-NLS-1$//$NON-NLS-2$
211

212                     if (events != null)
213                         events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.valueAppendedToJavaLibraryPath"), new Object JavaDoc[] { val })); //$NON-NLS-1$
214
} else if (events != null)
215                     events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.invalidJavaLibraryPath"), new Object JavaDoc[] { arg })); //$NON-NLS-1$
216

217             } else
218                 jvmArgs.addElement(launcher.replaceTokens(arg));
219         }
220     }
221
222     private void addArgument(XMLElement e) throws IOException JavaDoc {
223         if (e.getName().equalsIgnoreCase("arg")) //$NON-NLS-1$
224
addArgument(Utils.trimmedBothOrBlank(e.getContent()));
225         else if (e.getName().equalsIgnoreCase("env")) //$NON-NLS-1$
226
addEnvVar(Utils.trimmedBothOrBlank(e.getContent()));
227         else if (e.getName().equalsIgnoreCase("jvm")) { //$NON-NLS-1$
228
addJVMArgument(Utils.trimmedBothOrBlank(e.getContent()));
229         } else {
230             throw new IOException JavaDoc(MessageFormat.format(Messages.getString("JavaApplicationType.unexpectedElementFound"), new Object JavaDoc[] { e.getName() })); //$NON-NLS-1$
231
}
232     }
233
234     private void buildProgramArguments(XMLElement element) throws IOException JavaDoc {
235
236         Enumeration JavaDoc en = element.enumerateChildren();
237
238         while (en.hasMoreElements()) {
239
240             XMLElement e = (XMLElement) en.nextElement();
241             if (e.getName().equalsIgnoreCase("arg")) //$NON-NLS-1$
242
addArgument(e);
243             else if (e.getName().equalsIgnoreCase("jvm")) { //$NON-NLS-1$
244
addArgument(e);
245             } else if (e.getName().equalsIgnoreCase("env")) { //$NON-NLS-1$
246
addArgument(e);
247             } else if (e.getName().equalsIgnoreCase("if")) { //$NON-NLS-1$
248

249                 String JavaDoc jre = (String JavaDoc) e.getAttribute("jre"); //$NON-NLS-1$
250
if (jre == null) {
251                     String JavaDoc parameter = (String JavaDoc) e.getAttribute("parameter"); //$NON-NLS-1$
252
boolean not = "true".equalsIgnoreCase((String JavaDoc) e //$NON-NLS-1$
253
.getAttribute("not")); //$NON-NLS-1$
254

255                     if (parameter != null) {
256                         String JavaDoc requiredValue = (String JavaDoc) e.getAttribute("value"); //$NON-NLS-1$
257

258                         // Check the parameter
259
String JavaDoc value = (String JavaDoc) launcher.getDescriptorParams().get(parameter);
260
261                         if ((!not && requiredValue.equalsIgnoreCase(value)) || (not && !requiredValue.equalsIgnoreCase(value))) {
262                             buildProgramArguments(e);
263                         }
264
265                     } else
266                         throw new IOException JavaDoc(Messages.getString("JavaApplicationType.ifElementRequiresJreOrParameterAttribute")); //$NON-NLS-1$
267
} else {
268                     // Check the jre
269
if (Utils.isSupportedJRE(jre)) {
270                         buildProgramArguments(e);
271                     }
272
273                 }
274
275             } else
276                 throw new IOException JavaDoc(MessageFormat.format(Messages.getString("JavaApplicationType.unexpectedElementFoundInMain"), new Object JavaDoc[] { e.getName() })); //$NON-NLS-1$
277
}
278
279     }
280     
281     private void execute(String JavaDoc classpath, String JavaDoc mainclass, File JavaDoc workingDir) {
282
283         String JavaDoc[] args = new String JavaDoc[programArgs.size()];
284         programArgs.copyInto(args);
285         addDefaultEnvironment();
286         String JavaDoc[] envp = new String JavaDoc[envVars.size()];
287         envVars.copyInto(envp);
288         
289         if (!javaLibraryPath.equals("")) //$NON-NLS-1$
290
jvmArgs.addElement("java.library.path=" + launcher.replaceTokens(javaLibraryPath)); //$NON-NLS-1$
291

292         jvm = new String JavaDoc[jvmArgs.size()];
293         jvmArgs.copyInto(jvm);
294
295         String JavaDoc[] cmdargs = new String JavaDoc[jvm.length + args.length + 4];
296
297         if (!System.getProperty("java.vendor").startsWith("Microsoft")) { //$NON-NLS-1$ //$NON-NLS-2$
298
/**
299              * Setup the command line in the format expected by Sun Microsystems
300              * java command line interpreter
301              */

302             cmdargs[0] = Utils.getJavaHome() + File.separator //$NON-NLS-1$
303
+ "bin" + File.separator + "java"; //$NON-NLS-1$ //$NON-NLS-2$
304
cmdargs[1] = "-classpath"; //$NON-NLS-1$
305
cmdargs[2] = classpath;
306
307             for (int i = 0; i < jvm.length; i++) {
308                 cmdargs[3 + i] = "-D" + jvm[i]; //$NON-NLS-1$
309
}
310
311             cmdargs[jvm.length + 3] = mainclass;
312
313             System.arraycopy(args, 0, cmdargs, jvm.length + 4, args.length);
314
315         } else {
316             /**
317              * Were using the Microsoft VM. This requires quotes around any
318              * arguments and different command line syntax
319              */

320             cmdargs[0] = "jview.exe"; //$NON-NLS-1$
321
cmdargs[1] = "/cp"; //$NON-NLS-1$
322
cmdargs[2] = "\"" + classpath + "\""; //$NON-NLS-1$ //$NON-NLS-2$
323

324             for (int i = 0; i < jvm.length; i++) {
325                 cmdargs[3 + i] = "\"/d:" + jvm[i] + "\""; //$NON-NLS-1$ //$NON-NLS-2$
326
}
327
328             cmdargs[jvm.length + 3] = mainclass;
329
330             for (int i = 0; i < args.length; i++) {
331                 if (args[i].indexOf(' ') > -1)
332                     cmdargs[4 + i + jvm.length] = "\"" + args[i] + "\""; //$NON-NLS-1$ //$NON-NLS-2$
333
else
334                     cmdargs[4 + i + jvm.length] = args[i];
335             }
336
337         }
338
339         String JavaDoc cmdline = ""; //$NON-NLS-1$
340
for (int i = 0; i < cmdargs.length; i++)
341             cmdline += " " + cmdargs[i]; //$NON-NLS-1$
342

343         if (events != null)
344             events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.executingCommand"), new Object JavaDoc[] { cmdline })); //$NON-NLS-1$
345

346         try {
347
348             if (events != null)
349                 events.executingApplication(launcher.getName(), cmdline.trim());
350
351             
352             /**
353              * The following code caused problems with class loading in non-debug mode agent! Error
354              * message stated that "Invalid length 65528 in LocalVariableTable" and it seems to be
355              * related to the if(1 == 2) as I found references to this same error with if(true) after
356              * some googling.
357              */

358             // Write a script to do the launch as well (for debug)
359

360 // if (1 == 2) { // TODO get from a configuration property somehow
361
// File scriptFile = new File(workingDir == null ? launcher.getInstallDir() : workingDir,
362
// "debug-launch." + (Utils.isSupportedPlatform("Windows") ? "bat" : "sh"));
363
// FileOutputStream fos = new FileOutputStream(scriptFile);
364
// try {
365
// PrintWriter pw = new PrintWriter(fos);
366
// if (!Utils.isSupportedPlatform("Windows")) {
367
// pw.println("#!/bin/sh");
368
// }
369
// for (int i = 0; i < cmdargs.length; i++) {
370
// if (i > 0) {
371
// pw.print(" ");
372
// }
373
// pw.print("\"" + cmdargs[i] + "\"");
374
// }
375
// pw.flush();
376
// } finally {
377
// if (fos != null)
378
// fos.close();
379
// }
380
// }
381

382             // // Can we change the working directory of the process?
383
try {
384                 Method JavaDoc m = Runtime JavaDoc.class.getMethod("exec", new Class JavaDoc[] { //$NON-NLS-1$
385
String JavaDoc[].class, String JavaDoc[].class, File JavaDoc.class });
386                 Process JavaDoc prc = (Process JavaDoc) m.invoke(Runtime.getRuntime(), new Object JavaDoc[] { cmdargs, envp, workingDir });
387                 process = new ProcessMonitor(launcher.getName(), prc);
388             } catch (Throwable JavaDoc t) {
389                 if (workingDir != null) {
390                     throw new IOException JavaDoc(Messages.getString("JavaApplicationType.failedToChangeWorkingDirectory") //$NON-NLS-1$
391
+ "changed, but this Java Virtual Machine does not support that."); //$NON-NLS-1$
392
}
393                 process = new ProcessMonitor(launcher.getName(), Runtime.getRuntime().exec(cmdargs));
394             }
395         } catch (IOException JavaDoc ex) {
396             if (events != null)
397                 events.debug(MessageFormat.format(Messages.getString("JavaApplicationType.processExecutionFailed"), new Object JavaDoc[] { ex.getMessage() })); //$NON-NLS-1$
398
}
399
400     }
401     
402     void addDefaultEnvironment() {
403         /* This will only work on 1.5+ runtimes. It is currently only needed
404          * by Converse which is 1.5 dependant anyway
405          */

406         try {
407             Class JavaDoc iteratorClass = getClass().getClassLoader().loadClass("java.util.Iterator");
408             Class JavaDoc mapClass = getClass().getClassLoader().loadClass("java.util.Map");
409             Object JavaDoc mapObject = System JavaDoc.class.getMethod("getenv", new Class JavaDoc[] { }).invoke(null, new Object JavaDoc[] { });
410             Object JavaDoc setObject = mapClass.getMethod("keySet", new Class JavaDoc[] { }).invoke(mapObject, new Object JavaDoc[] { });
411             Object JavaDoc iteratorObject = getClass().getClassLoader().loadClass("java.util.Set").getMethod("iterator", new Class JavaDoc[] { }).invoke(setObject, new Object JavaDoc[] { });
412             while( ((Boolean JavaDoc)iteratorClass.getMethod("hasNext", new Class JavaDoc[] { }).invoke(iteratorObject, new Object JavaDoc[] { })).booleanValue()) {
413                 String JavaDoc name = (String JavaDoc)iteratorClass.getMethod("next", new Class JavaDoc[] { }).invoke(iteratorObject, new Object JavaDoc[] { });
414                 if(!envVarExists(name)) {
415                     envVars.addElement(name + "=" + ( mapClass.getMethod("get", new Class JavaDoc[] { Object JavaDoc.class }).invoke(mapObject, new Object JavaDoc[] { name })));
416                 }
417             }
418         } catch (Exception JavaDoc e) {
419         }
420         
421     }
422     
423     boolean envVarExists(String JavaDoc name) {
424         for(Enumeration JavaDoc e = envVars.elements(); e.hasMoreElements(); ) {
425             if(((String JavaDoc)e.nextElement()).startsWith(name)) {
426                 return true;
427             }
428         }
429         return false;
430     }
431
432     /*
433      * (non-Javadoc)
434      *
435      * @see com.sslexplorer.vpn.util.ApplicationType#getProcessMonitor()
436      */

437     public ProcessMonitor getProcessMonitor() {
438         return process;
439     }
440
441     /*
442      * (non-Javadoc)
443      *
444      * @see com.sslexplorer.vpn.util.ApplicationType#getRedirectParameters()
445      */

446     public String JavaDoc getRedirectParameters() {
447         return null;
448     }
449
450     /*
451      * (non-Javadoc)
452      *
453      * @see com.sslexplorer.agent.client.util.ApplicationType#getTypeName()
454      */

455     public String JavaDoc getTypeName() {
456         return "java";
457     }
458 }
459
Popular Tags