KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > appclient > Main


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.appclient;
24
25 import com.sun.appserv.naming.S1ASCtxFactory;
26 import com.sun.enterprise.appclient.AppContainer;
27 import com.sun.enterprise.appclient.HttpAuthenticator;
28 import com.sun.enterprise.appclient.jws.TemplateCache;
29 import com.sun.enterprise.appclient.jws.Util;
30 import com.sun.enterprise.config.clientbeans.CertDb;
31 import com.sun.enterprise.config.clientbeans.ClientBeansFactory;
32 import com.sun.enterprise.config.clientbeans.ClientContainer;
33 import com.sun.enterprise.config.clientbeans.ClientCredential;
34 import com.sun.enterprise.config.clientbeans.ElementProperty;
35 import com.sun.enterprise.config.clientbeans.Security;
36 import com.sun.enterprise.config.clientbeans.Ssl;
37 import com.sun.enterprise.config.clientbeans.TargetServer;
38 import com.sun.enterprise.config.ConfigContext;
39 import com.sun.enterprise.config.ConfigException;
40 import com.sun.enterprise.config.ConfigFactory;
41 import com.sun.enterprise.connectors.ActiveResourceAdapter;
42 import com.sun.enterprise.connectors.ConnectorRegistry;
43 import com.sun.enterprise.connectors.ConnectorRuntime;
44 import com.sun.enterprise.deployment.*;
45 import com.sun.enterprise.deployment.archivist.AppClientArchivist;
46 import com.sun.enterprise.deployment.archivist.ApplicationArchivist;
47 import com.sun.enterprise.deployment.backend.ClientJarMakerThread;
48 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
49 import com.sun.enterprise.deployment.deploy.shared.FileArchive;
50 import com.sun.enterprise.deployment.deploy.shared.InputJarArchive;
51 import com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactory;
52 import com.sun.enterprise.deployment.interfaces.SecurityRoleMapperFactoryMgr;
53 import com.sun.enterprise.InjectionManager;
54 import com.sun.enterprise.J2EESecurityManager;
55 import com.sun.enterprise.naming.ProviderManager;
56 import com.sun.enterprise.security.GUIErrorDialog;
57 import com.sun.enterprise.security.SSLUtils;
58 import com.sun.enterprise.server.logging.ACCLogManager;
59 import com.sun.enterprise.Switch;
60 import com.sun.enterprise.util.FileUtil;
61 import com.sun.enterprise.util.i18n.StringManager;
62 import com.sun.enterprise.util.JarClassLoader;
63 import com.sun.enterprise.util.ORBManager;
64 import com.sun.enterprise.util.shared.ArchivistUtils;
65 import com.sun.enterprise.util.Utility;
66 import com.sun.logging.LogDomains;
67 import com.sun.web.server.HttpsURLStreamHandlerFactory;
68
69 import java.io.*;
70 import java.net.*;
71 import java.util.Iterator JavaDoc;
72 import java.util.jar.JarFile JavaDoc;
73 import java.util.logging.Level JavaDoc;
74 import java.util.logging.Logger JavaDoc;
75 import java.util.logging.LogManager JavaDoc;
76 import java.util.Properties JavaDoc;
77 import java.util.Vector JavaDoc;
78
79 /**
80  * This is the main that gets invoked first. It initializes the application
81  * client container for an application client component
82  * and other related items and then invokes the real main written by the
83  * application developer.
84  */

85 public class Main
86 {
87     private static final String JavaDoc CLIENT = "-client";
88     private static final String JavaDoc NAME = "-name";
89     private static final String JavaDoc MAIN_CLASS = "-mainclass";
90     private static final String JavaDoc TEXT_AUTH = "-textauth";
91     private static final String JavaDoc XML_PATH = "-xml";
92     private static final String JavaDoc ACC_CONFIG_XML = "-configxml";
93     private static final String JavaDoc DEFAULT_CLIENT_CONTAINER_XML = "sun-acc.xml";
94     // duplicated in com.sun.enterprise.jauth.ConfigXMLParser
95
private static final String JavaDoc SUNACC_XML_URL = "sun-acc.xml.url";
96     private static final String JavaDoc NO_APP_INVOKE = "-noappinvoke";
97     //Added for allow user to pass user name and password through command line.
98
private static final String JavaDoc USER = "-user";
99     private static final String JavaDoc PASSWORD = "-password";
100     private static final String JavaDoc PASSWORD_FILE = "-passwordfile";
101     private static final String JavaDoc LOGIN_NAME = "j2eelogin.name";
102     private static final String JavaDoc LOGIN_PASSWORD = "j2eelogin.password";
103     private static final String JavaDoc DASH = "-";
104
105     private static final String JavaDoc lineSep = System.getProperty("line.separator");
106     
107     /**
108      * Property names used on the server to send these values to a Java Web Start client
109      * and by the ACC when running under Java Web Start to retrieve them
110      */

111     public static final String JavaDoc APPCLIENT_IIOP_DEFAULTHOST_PROPERTYNAME = "com.sun.aas.jws.iiop.defaultHost";
112     public static final String JavaDoc APPCLIENT_IIOP_DEFAULTPORT_PROPERTYNAME = "com.sun.aas.jws.iiop.defaultPort";
113     public static final String JavaDoc APPCLIENT_IIOP_FAILOVER_ENDPOINTS_PROPERTYNAME = "com.sun.aas.jws.iiop.failover.endpoints";
114     public static final String JavaDoc APPCLIENT_PROBE_CLASSNAME_PROPERTYNAME = "com.sun.aas.jws.probeClassName";
115     
116     /** Prop name for keeping temporary files */
117     public static final String JavaDoc APPCLIENT_RETAIN_TEMP_FILES_PROPERTYNAME = "com.sun.aas.jws.retainTempFiles";
118     
119     /** property name used to indicate that Java Web Start is active */
120     public static final String JavaDoc APPCLIENT_ISJWS_PROPERTYNAME = "com.sun.aas.jws.isJWS";
121     
122     /** Prop used when running under Java Web Start to point to a temporarily-created default file.
123      *This property appears in the template for the default sun-acc.xml content. Logic below
124      *assigns a value to it and then uses it to substitute in the template to create the
125      *actual content. (This is not a property set in the environment and then retrieved by Main.)
126     */

127     public static final String JavaDoc SUN_ACC_SECURITY_CONFIG_PROPERTY = "security.config.file";
128     
129     /** Used for constructing the name of the temp file that will hold the login conf. content */
130     private static final String JavaDoc LOGIN_CONF_FILE_PREFIX = "login";
131     private static final String JavaDoc LOGIN_CONF_FILE_SUFFIX = ".conf";
132     
133     /** The system property to be set that is later read by jaas */
134     private static final String JavaDoc LOGIN_CONF_PROPERTY_NAME = "java.security.auth.login.config";
135     
136     /** Names of templates for default config for Java Web Start */
137     private static final String JavaDoc DEFAULT_TEMPLATE_PREFIX = "jws/templates/";
138     private static final String JavaDoc SUN_ACC_DEFAULT_TEMPLATE = DEFAULT_TEMPLATE_PREFIX + "default-sun-accTemplate.xml";
139     private static final String JavaDoc WSS_CLIENT_CONFIG_TEMPLATE = DEFAULT_TEMPLATE_PREFIX + "default-wss-client-configTemplate.xml";
140     private static final String JavaDoc LOGIN_CONF_TEMPLATE = DEFAULT_TEMPLATE_PREFIX + "appclientlogin.conf";
141     
142     /** Naming for temporary files created under Java Web Start */
143     private static final String JavaDoc WSS_CLIENT_CONFIG_PREFIX = "wsscc";
144     private static final String JavaDoc WSS_CLIENT_CONFIG_SUFFIX = ".xml";
145     private static final String JavaDoc SUN_ACC_PREFIX = "sunacc";
146     private static final String JavaDoc SUN_ACC_SUFFIX = ".xml";
147     
148     private static Logger JavaDoc _logger;
149
150     private static final boolean debug = false;
151     private static StringManager localStrings =
152                             StringManager.getManager(Main.class);
153     private static boolean guiAuth;
154     private static boolean runClient=true;
155
156     private static String JavaDoc host;
157
158     private static String JavaDoc port;
159
160     /** accumulates info to be logged before the logger is initialized */
161     private static StringBuilder JavaDoc pendingLogInfo = new StringBuilder JavaDoc();
162     private static StringBuilder JavaDoc pendingLogFine = new StringBuilder JavaDoc();
163             
164     /** Saved arguments so they are accessible from the AWT thread if needed */
165     private static String JavaDoc [] args;
166
167     /** Records whether ACC is currently running under Java Web Start */
168     private static boolean isJWS;
169     
170     /** Records whether temp config files created while running under Java Web Start should be retained */
171     private static boolean retainTempFiles = false;
172     
173     private static final String JavaDoc SUPPORT_MODULE_FORMAT = "support.module.format";
174     private static final String JavaDoc SUPPORT_MODULE_FORMAT_DEFAULT_VALUE = "true";
175     private static final String JavaDoc supportModuleFormatValue = System.getProperty(SUPPORT_MODULE_FORMAT, SUPPORT_MODULE_FORMAT_DEFAULT_VALUE);
176     private static final boolean supportModuleFormat = Boolean.parseBoolean(supportModuleFormatValue);
177     
178     public static void main(String JavaDoc[] args) {
179         if (supportModuleFormat) {
180             new MainWithModuleSupport(args);
181         } else {
182             new Main(args);
183         }
184     }
185
186     public Main(String JavaDoc[] args) {
187
188         String JavaDoc arg = null;
189         String JavaDoc clientJar = null;
190         String JavaDoc displayName = null;
191         String JavaDoc mainClass = null;
192         String JavaDoc xmlPath = null;
193         String JavaDoc accConfigXml = null;
194         String JavaDoc jwsACCConfigXml = null;
195         Vector JavaDoc<String JavaDoc> appArgs = new Vector JavaDoc<String JavaDoc>();
196         int i = 0;
197
198         isJWS = Boolean.getBoolean(APPCLIENT_ISJWS_PROPERTYNAME);
199         retainTempFiles = Boolean.getBoolean(APPCLIENT_RETAIN_TEMP_FILES_PROPERTYNAME);
200         
201         guiAuth = Boolean.valueOf
202             (System.getProperty("auth.gui", "true")).booleanValue();
203         // Parse command line arguments.
204
if(args.length < 1) {
205             usage();
206         } else {
207             while(i < args.length) {
208                 arg = args[i++];
209                 if(arg.equals(CLIENT)) {
210                     if(i < args.length && !args[i].startsWith(DASH)) {
211                         clientJar = args[i++];
212                     } else {
213                         usage();
214                     }
215                 } else if(arg.equals(NAME) && !args[i].startsWith(DASH)) {
216                     //only one option can be used [-mainclass|-name]
217
if(i < args.length && mainClass == null) {
218                         displayName = args[i++];
219                     } else {
220                         usage();
221                     }
222                 } else if(arg.equals(MAIN_CLASS) && !args[i].startsWith(DASH)) {
223                     //only one option can be used [-mainclass|-name]
224
if(i < args.length && displayName == null) {
225                         mainClass = args[i++];
226                     } else {
227                         usage();
228                     }
229                 } else if(arg.equals(XML_PATH) ) {
230                     if(i < args.length && xmlPath == null) {
231                         xmlPath = args[i++];
232                     } else {
233                         usage();
234                     }
235                 } else if(arg.equals(ACC_CONFIG_XML) ) {
236                     if(i < args.length && accConfigXml == null) {
237                         accConfigXml = args[i++];
238                     } else {
239                         usage();
240                     }
241                 } else if(arg.equals(TEXT_AUTH)) {
242                     // Overrides legacy auth.gui setting.
243
guiAuth = false;
244                 } else if(arg.equals(NO_APP_INVOKE)) {
245                     runClient = false;
246                 } else if(arg.equals(USER)) {
247                     if(i < args.length) {
248                         System.setProperty(LOGIN_NAME, args[i++]);
249                     } else {
250                         usage();
251                     }
252                 } else if(arg.equals(PASSWORD)) {
253                     if (i < args.length) {
254                         System.setProperty(LOGIN_PASSWORD, args[i++]);
255                     } else {
256                         usage();
257                     }
258                 } else if (arg.equals(PASSWORD_FILE)) {
259                     if (i < args.length) {
260                         try {
261                             System.setProperty(LOGIN_PASSWORD,
262                                 loadPasswordFromFile(args[i++]));
263                         } catch(IOException ex) {
264                             throw new IllegalArgumentException JavaDoc(ex.getMessage());
265                         }
266                     } else {
267                         usage();
268                     }
269                 } else {
270                     appArgs.add(arg);
271                 }
272             }
273         }
274         
275         String JavaDoc className=null;
276         
277         if(clientJar == null && ! isJWS) {
278             // maybe the user has specified the appclient class as the first
279
// parameter using the local directory as the classpath.
280
if (appArgs.size()==0 && mainClass==null) {
281                 usage();
282             }
283             // ok, if the first parameter may be the appclient class, let's check
284
// for its existence.
285
String JavaDoc value;
286             if (mainClass==null) {
287                 value = appArgs.elementAt(0);
288             } else {
289                 value = mainClass;
290             }
291             if (value.endsWith(".class")) {
292                 className = value.substring(0, value.length()-".class".length());
293             } else {
294                 className = value;
295             }
296             
297             String JavaDoc path = className.replace('.', File.separatorChar) + ".class";
298             File JavaDoc file = new File JavaDoc(path);
299             if (!file.isAbsolute()) {
300                 file = new File JavaDoc(System.getProperty("user.dir"), path);
301             }
302             /*
303              *If the user omitted the client jar from the command line and
304              *we cannot find the first argument as a class in the user's
305              *home directory and this is not a JWS launch, then the user has
306              *not entered a valid command.
307              */

308             if (!file.exists() && ! isJWS) {
309                 // no clue what the user is trying to do
310
usage();
311             }
312         }
313         
314         /* validate xmlPath */
315         if (xmlPath != null) {
316             validateXMLFile(xmlPath);
317         } else if (accConfigXml != null ) {
318             validateXMLFile(accConfigXml);
319             xmlPath = accConfigXml; //use AS_ACC_CONFIG
320
} else if (isJWS) {
321             /*
322              *Neither -xml nor -configxml were present and this is a Java
323              *Web Start invocation. Use
324              *the alternate mechanism to create the default config.
325              */

326             try {
327                 jwsACCConfigXml = prepareJWSConfig();
328                 if (jwsACCConfigXml != null) {
329                     validateXMLFile(jwsACCConfigXml);
330                     xmlPath = jwsACCConfigXml;
331                 }
332             } catch (Throwable JavaDoc thr) {
333                 System.err.println("Error preparing configuration");
334                 thr.printStackTrace(System.err);
335                 System.exit(1);
336             }
337         }
338
339
340         // make sure the default logger for ACCLogManager is set
341
_logger = LogDomains.getLogger(LogDomains.ACC_LOGGER);
342
343         LogManager logMgr = LogManager.getLogManager();
344         if (logMgr instanceof ACCLogManager) {
345             ((ACCLogManager) logMgr).init(xmlPath);
346         }
347
348         /*
349          *Flush any pending log output.
350          */

351         if (pendingLogInfo.length() > 0) {
352             _logger.info(pendingLogInfo.toString());
353             
354             if (pendingLogFine.length() > 0) {
355                 _logger.fine(pendingLogFine.toString());
356             }
357         }
358         
359         /*
360          *If this is a Java Web Start invocation, prepare the user-specified
361          *or default login configuration.
362          */

363         if (isJWS) {
364             try {
365                 prepareJWSLoginConfig();
366             } catch (Throwable JavaDoc thr) {
367                 _logger.log(Level.SEVERE, "Error preparing default login configuration", thr);
368                 System.exit(1);
369             }
370         }
371         
372         
373         Utility.checkJVMVersion();
374         
375         /* security init */
376         SecurityManager JavaDoc secMgr = System.getSecurityManager();
377         if (secMgr != null &&
378                 !(J2EESecurityManager.class.equals(secMgr.getClass()))) {
379             J2EESecurityManager mgr = new J2EESecurityManager();
380             System.setSecurityManager(mgr);
381         }
382         if (_logger.isLoggable(Level.INFO)) {
383             if (secMgr != null) {
384                 _logger.info("acc.secmgron");
385             } else {
386                 _logger.info("acc.secmgroff");
387             }
388         }
389
390         com.sun.enterprise.security.KeyTool.initProvider();
391         try{
392             /* setup keystores.
393              * This is required, for appclients that want to use SSL, especially
394              * HttpsURLConnection to perform Https.
395              */

396             SSLUtils.initStoresAtStartup();
397         } catch (Exception JavaDoc e){
398              /* This is not necessarily an error. This will arise
399               * if the user has not specified keystore/truststore properties.
400               * and does not want to use SSL.
401               */

402             if(_logger.isLoggable(Level.FINER)){
403                 // show the exact stack trace
404
_logger.log(Level.FINER, "main.ssl_keystore_init_failed", e);
405             } else{
406                 // just log it as a warning.
407
_logger.log(Level.WARNING, "main.ssl_keystore_init_failed");
408             }
409         }
410
411     try {
412         Switch.getSwitch().setProviderManager(ProviderManager.getProviderManager());
413         // added for ClientContainer.xml initialization
414
setTargetServerProperties(xmlPath);
415         
416         int exitCode = 0; // 0 for success
417
AppContainer container = null;
418         
419         // Ensure cleanup is performed, even if
420
// application client calls System.exit().
421
Cleanup cleanup = new Cleanup();
422         Runtime JavaDoc runtime = Runtime.getRuntime();
423         runtime.addShutdownHook(cleanup);
424         
425             // Set the HTTPS URL stream handler.
426
java.security.AccessController.doPrivileged(new
427                        java.security.PrivilegedAction JavaDoc() {
428             public Object JavaDoc run() {
429             URL.setURLStreamHandlerFactory(new
430                        HttpsURLStreamHandlerFactory());
431             return null;
432             }
433         });
434         
435             File JavaDoc appClientFile;
436             /*
437              *For Java Web Start launches, locate the jar file implicitly.
438              *Otherwise, if the user omitted the clientjar argument (and the
439              *code has gotten this far) then the user must have used the
440              *first argument as the name of the class in ${user.dir} to run. If
441              *the user actually specified the clientjar argument, then use that
442              *value as the file spec for the client jar.
443              */

444             if (isJWS) {
445                 /*
446                  *Java Web Start case.
447                  */

448                 appClientFile = findAppClientFileForJWSLaunch();
449             } else if (clientJar==null) {
450                 /*
451                  *First-argument-as-class-name case
452                  */

453                 File JavaDoc userDir = new File JavaDoc(System.getProperty("user.dir"));
454                 File JavaDoc appClientClass = new File JavaDoc(userDir, className);
455                 appClientFile = appClientClass.getParentFile();
456             } else {
457                 /*
458                  *Normal case - clientjar argument specified.
459                  */

460                 appClientFile = new File JavaDoc(clientJar);
461             }
462         
463             // class loader
464
URL[] urls = new URL[1];
465             urls[0] = appClientFile.toURI().toURL();
466             /*
467              *Set the parent of the new class loader to the current loader.
468              *The Java Web Start-managed class path is implemented in the
469              *current loader, so it must remain on the loader stack.
470              */

471             ClassLoader JavaDoc currentCL = Thread.currentThread().getContextClassLoader();
472             ClassLoader JavaDoc jcl = new URLClassLoader(urls, currentCL);
473             Thread.currentThread().setContextClassLoader(jcl);
474             ApplicationClientDescriptor appDesc = null;
475             
476             // create the application container and call preInvoke.
477

478             /*
479              *Note that if the client jar argument is missing it can mean one of
480              *two things: Either the user used the first argument to specify
481              *the class to execute or
482              *this is a Java Web Start launch.
483              */

484             if((clientJar!=null || isJWS ) && FileUtil.isEARFile(appClientFile)) {
485
486
487                 // loads application with only the clients
488
Application app = null;
489                 try {
490                     ApplicationArchivist arch = new ApplicationArchivist();
491                     arch.setAnnotationProcessingRequested(true);
492
493                     // Set class loader here before opening archive
494
// to enable validation.
495
arch.setClassLoader(jcl);
496                     app = (Application) arch.open(appClientFile);
497
498                 } catch (Throwable JavaDoc t) {
499                    _logger.log(Level.WARNING, "acc.failed_load_client_desc",
500                         clientJar);
501                     throw t;
502                 }
503                 app.setClassLoader(jcl);
504                 appDesc = null;
505
506         int appclientCount = 0;
507         for (Iterator JavaDoc itr =
508                     app.getApplicationClientDescriptors().iterator();
509                     itr.hasNext();) {
510             ApplicationClientDescriptor next =
511               (ApplicationClientDescriptor) itr.next();
512             appclientCount++;
513         }
514
515                 for (Iterator JavaDoc itr =
516                     app.getApplicationClientDescriptors().iterator();
517                     itr.hasNext();) {
518
519                     ApplicationClientDescriptor next =
520                         (ApplicationClientDescriptor) itr.next();
521             if (appclientCount == 1) {
522             //for -mainclass <class name> option
523
if (mainClass != null) {
524                 if (!next.getMainClassName().equals(mainClass)) {
525                     next.setMainClassName(mainClass);
526                 }
527             }
528             appDesc = next;
529             break;
530             } else {//app contains multiple app client jars
531
if (mainClass != null) {
532                 if (next.getMainClassName().equals(mainClass)) {
533                     appDesc = next;
534                 break;
535                 }
536             } else {
537                 if (displayName == null) {
538                     _logger.log(Level.SEVERE,"acc.no_mainclass_or_displayname");
539                 System.exit(1);
540                 } else if (displayName != null && next.getName().equals(displayName)) {
541                     if(appDesc == null) {
542                     appDesc = next;
543                 } else {
544                     //multiple app duplicated display name
545
_logger.log(Level.WARNING, "acc.duplicate_display_name");
546                     System.exit(1);
547                 }
548                 }
549             }
550             }
551                     
552                 }
553                 //construct AppContainer using appDesc
554
if (appDesc != null) {
555                     container = new AppContainer(appDesc, guiAuth);
556                     // the archive uri must have absolute path
557
//f = new File (f, appDesc.getModuleDescriptor().getArchiveUri());
558
}
559             } else {
560
561                 // we are dealing with a class file or a client jar
562

563                 // reads std & iAS application xml
564

565                 try {
566                     // Set classloader before opening archive to enable
567
// validation.
568
AppClientArchivist arch = new AppClientArchivist();
569                     arch.setAnnotationProcessingRequested(true);
570                     arch.setClassLoader(jcl);
571
572                     // for class case, get default bundle
573
if (className!=null) {
574                         appDesc = (ApplicationClientDescriptor) arch.getDefaultBundleDescriptor();
575                     } else {
576                         // for client jar case, do not process annotations.
577
// use AppClientArchivist.open(String) instead of
578
// AppClientArchivist.open(AbstractArchive) since the
579
// open(String) method calls validate.
580
appDesc = (ApplicationClientDescriptor) arch.open(appClientFile.getAbsolutePath());
581                     }
582
583                     if (className!=null) {
584                         // post masssaging
585
AbstractArchive archive;
586                         if (appClientFile.isDirectory()) {
587                             archive = new FileArchive();
588                             ((FileArchive) archive).open(appClientFile.getAbsolutePath());
589                         } else {
590                             archive = new InputJarArchive();
591                             ((InputJarArchive) archive).open(appClientFile.getAbsolutePath());
592                         }
593
594                         if (appDesc.getMainClassName()==null || appDesc.getMainClassName().length()==0) {
595                             appDesc.setMainClassName(className);
596                             arch.processAnnotations(appDesc, archive);
597                             
598                             // let's remove our appArgs first element since it was the app client class name
599
//...but only if this is not a Java Web Start launch.
600
if (mainClass==null && ! isJWS) {
601                                 appArgs.removeElementAt(0);
602                             }
603                         }
604                     }
605                     
606                 } catch (Throwable JavaDoc t) {
607                     _logger.log(Level.WARNING,
608                             "main.appclient_descriptors_failed", (displayName == null) ? mainClass : displayName);
609                     throw t;
610                 }
611                 container = new AppContainer(appDesc, guiAuth);
612             }
613             if(container == null) {
614                 _logger.log(Level.WARNING, "acc.no_client_desc",
615                             (displayName == null) ? mainClass : displayName);
616
617                 System.exit(1);
618             }
619             // Set the authenticator which is called back when a
620
// protected web resource is requested and authentication data is
621
// needed.
622
Authenticator.setDefault(new HttpAuthenticator(container));
623
624             // log a machine name, port number per Jagadesh's request
625
_logger.log(Level.INFO, "acc.orb_host_name", host);
626             _logger.log(Level.INFO, "acc.orb_port_number", port);
627                       
628         Properties JavaDoc props = new Properties JavaDoc();
629         props.put("org.omg.CORBA.ORBInitialHost", host);
630         props.put("org.omg.CORBA.ORBInitialPort", port);
631
632             String JavaDoc appMainClass = container.preInvoke(props);
633             cleanup.setAppContainer(container);
634
635             // load and invoke the real main of the application.
636
Class JavaDoc cl = null;
637             try {
638                 cl = jcl.loadClass(appMainClass);
639             } catch (java.lang.ClassNotFoundException JavaDoc cnf) {
640                 String JavaDoc errorMessage = localStrings.getString
641                     ("appclient.mainclass.not.found", appMainClass);
642                 _logger.log(Level.WARNING, errorMessage);
643                 throw cnf;
644             }
645
646             _logger.log(Level.INFO, "acc.load_app_class", appMainClass);
647
648             String JavaDoc[] applicationArgs = new String JavaDoc[appArgs.size()];
649             for(int sz = 0; sz < applicationArgs.length; sz++) {
650                 applicationArgs[sz] = (String JavaDoc) appArgs.elementAt(sz);
651             }
652
653             // check if we are dealing with an application client containing
654
// service references... if this is the case, I need to explode
655
// the appclient jar file to be able to access its wsdl files
656
// with a URL (so that imports can work)
657
if (appDesc.hasWebServiceClients()) {
658                 File JavaDoc moduleFile;
659                 if (appDesc.getApplication()==null
660                       || appDesc.getApplication().isVirtual()) {
661                     // this is a standalone module, I can do Wsdl file
662
// resolution directly on it.
663
moduleFile = appClientFile;
664                 } else {
665                     InputJarArchive earFile = new InputJarArchive();
666                     earFile.open(appClientFile.getAbsolutePath());
667                     String JavaDoc moduleName = appDesc.getModuleDescriptor().getArchiveUri();
668                     InputStream is = earFile.getEntry(moduleName);
669                     moduleFile = File.createTempFile("appclient", ".jar");
670                     moduleFile.deleteOnExit();
671                     OutputStream os = new FileOutputStream(moduleFile);
672                     ArchivistUtils.copy(new BufferedInputStream(is), new BufferedOutputStream(os));
673                     earFile.close();
674                 }
675                 // now perform wsdl file resolution
676
for (Iterator JavaDoc itr = appDesc.getServiceReferenceDescriptors().iterator();
677                     itr.hasNext();) {
678                         
679                     ServiceReferenceDescriptor serviceRef = (ServiceReferenceDescriptor) itr.next();
680                     if (serviceRef.getWsdlFileUri()!=null) {
681                         // In case WebServiceRef does not specify wsdlLocation, we get wsdlLocation from @WebClient
682
// in wsimport generated source; If wsimport was given a local WSDL file, then WsdlURI will
683
// be an absolute path - in that case it should not be prefixed with modileFileDir
684
File JavaDoc wsdlFile = new File JavaDoc(serviceRef.getWsdlFileUri());
685                         if(wsdlFile.isAbsolute()) {
686                             serviceRef.setWsdlFileUrl(wsdlFile.toURI().toURL());
687                         } else {
688                             // This is the case where WsdlFileUri is a relative path (hence relative to the root of
689
// this module or wsimport was executed with WSDL in HTTP URL form
690
serviceRef.setWsdlFileUrl(FileUtil.getEntryAsUrl(moduleFile, serviceRef.getWsdlFileUri()));
691                         }
692                     }
693                 }
694             }
695             
696
697             // This is required for us to enable interrupt jaxws service creation calls
698
System.setProperty("javax.xml.ws.spi.Provider", "com.sun.enterprise.webservice.spi.ProviderImpl");
699             // Inject the application client's injectable resources. This
700
// must be done after java:comp/env is initialized but before
701
// the application client's main class is invoked.
702
InjectionManager injMgr = Switch.getSwitch().getInjectionManager();
703             injMgr.injectClass(cl, appDesc);
704                             
705             if(runClient) {
706                 Utility.invokeApplicationMain(cl, applicationArgs);
707                 _logger.info("Application main() finished normally");
708             }
709
710
711             // inject the pre-destroy methods before shutting down
712
injMgr.invokeClassPreDestroy(cl, appDesc);
713
714         // Let's shutdown all the system resource adapters that are
715
// active in the container.
716
shutDownSystemAdapters();
717
718             // System.exit is not called if application main returned
719
// without error. Registered shutdown hook will perform
720
// container cleanup
721
} catch (java.lang.reflect.InvocationTargetException JavaDoc ite) {
722             Throwable JavaDoc tt = ite.getTargetException();
723             _logger.log(Level.WARNING, "acc.app_exception", tt);
724         shutDownSystemAdapters();
725             System.exit(1);
726         } catch (Throwable JavaDoc t) {
727             if (t instanceof javax.security.auth.login.FailedLoginException JavaDoc){
728
729                _logger.info("acc.login_error");
730                 boolean isGui =
731                     Boolean.valueOf
732                         (System.getProperty ("auth.gui","true")).booleanValue();
733                 String JavaDoc errorMessage =
734                     localStrings.getString
735                         ("main.exception.loginError",
736                          "Incorrect login and/or password");
737
738                 if (isGui) {
739                     GUIErrorDialog ged = new GUIErrorDialog (errorMessage);
740                     ged.show ();
741                 }
742             }
743
744             _logger.log(Level.WARNING, "acc.app_exception", t);
745
746             if (t instanceof javax.naming.NamingException JavaDoc) {
747                 _logger.log(Level.WARNING, "acc.naming_exception_received");
748             }
749      
750         shutDownSystemAdapters();
751         
752             System.exit(1);
753         }
754     }
755
756     private static void setTargetServerProperties(String JavaDoc clientXmlLocation)
757     throws ConfigException {
758         //FIXME: may need to set the context in switch or generic context. but later
759
try {
760             if(clientXmlLocation == null || clientXmlLocation.equals("")) {
761                 clientXmlLocation = DEFAULT_CLIENT_CONTAINER_XML;
762             }
763
764         // set for com.sun.enterprise.security.jauth.ConfigXMLParser
765
System.setProperty(SUNACC_XML_URL, clientXmlLocation);
766              _logger.log(Level.INFO, "acc.using_xml_location", clientXmlLocation);
767            
768             ConfigContext ctx = ConfigFactory.createConfigContext(
769         clientXmlLocation, true,
770         false, false,
771         ClientContainer.class,
772         new ACCEntityResolver());
773
774             ClientContainer cc = ClientBeansFactory.getClientBean(ctx);
775         
776         host = cc.getTargetServer(0).getAddress();
777         port = cc.getTargetServer(0).getPort();
778
779         //check for targetServerEndpoints
780
TargetServer[] tServer = cc.getTargetServer();
781         String JavaDoc targetServerEndpoints = null;
782         if (tServer.length > 1) {
783         for (int i = 0; i < tServer.length; i++) {
784             if (targetServerEndpoints == null) {
785             targetServerEndpoints = tServer[i].getAddress() +
786                 ":" + tServer[i].getPort();
787             } else {
788             targetServerEndpoints = targetServerEndpoints + "," +
789                 tServer[i].getAddress() +
790                 ":" + tServer[i].getPort();
791             }
792         }
793         }
794
795             setSSLData(cc);
796
797             //FIXME: what do we do about realm
798
ClientCredential cCrd = cc.getClientCredential();
799             if(cCrd != null) {
800                 // if user entered user/password from command line,
801
// it take percedence over the xml file. - y.l. 05/15/02
802
if (System.getProperty(LOGIN_NAME) == null) {
803                     _logger.config("using login name from client container xml...");
804                     System.setProperty(LOGIN_NAME, cCrd.getUserName());
805                 }
806                 if (System.getProperty(LOGIN_PASSWORD) == null) {
807                     _logger.config("using password from client container xml...");
808                     System.setProperty(LOGIN_PASSWORD, cCrd.getPassword());
809                 }
810             }
811         String JavaDoc endpoints_property = null;
812         // Check if client requires SSL to be used
813
ElementProperty[] props = cc.getElementProperty();
814         for ( int i=0; i<props.length; i++ ) {
815         if ( props[i].getName().equals("ssl") ) {
816             if ( props[i].getValue().equals("required") ) {
817             (ORBManager.getCSIv2Props()).put(ORBManager.ORB_SSL_CLIENT_REQUIRED,
818                        "true");
819             }
820         }
821         if ( props[i].getName().equals(S1ASCtxFactory.LOAD_BALANCING_PROPERTY) ) {
822             System.setProperty(props[i].getName(),props[i].getValue());
823         }
824         if ( props[i].getName().equals(S1ASCtxFactory.IIOP_ENDPOINTS_PROPERTY) ) {
825             endpoints_property = props[i].getValue().trim();
826             
827         }
828         }
829             
830             /*
831              *If the endpoints property was not set in the XML file's property
832              *settings, try to set it from the server's assignment in the JNLP document.
833              */

834             String JavaDoc jwsEndpointsProperty = null;
835             if (endpoints_property == null) {
836                 jwsEndpointsProperty = System.getProperty(Main.APPCLIENT_IIOP_FAILOVER_ENDPOINTS_PROPERTYNAME);
837                 endpoints_property = jwsEndpointsProperty;
838             }
839             
840         _logger.fine("targetServerEndpoints = " + targetServerEndpoints +
841              "endpoints_property = " +
842              endpoints_property);
843         if (targetServerEndpoints == null && endpoints_property != null) {
844         System.setProperty(
845                    S1ASCtxFactory.IIOP_ENDPOINTS_PROPERTY,
846                    endpoints_property);
847
848         /*
849                  *Suppress the warning if the endpoints_property was set
850                  *from the JNLP document, since that is in fact the preferred
851                  *way to set the endpoints.
852                  */

853                 if (jwsEndpointsProperty == null) {
854                     _logger.warning("acc.targetserver.endpoints.warning");
855                 }
856         } else if (targetServerEndpoints != null && endpoints_property == null) {
857         System.setProperty(
858                    S1ASCtxFactory.IIOP_ENDPOINTS_PROPERTY,
859                    targetServerEndpoints.trim());
860         } else if (targetServerEndpoints != null && endpoints_property != null) {
861         System.setProperty(
862                    S1ASCtxFactory.IIOP_ENDPOINTS_PROPERTY,
863                    targetServerEndpoints.trim() + "," +
864                    endpoints_property);
865                 /*
866                  *Suppress the warning if the endpoints_property was set
867                  *from the JNLP document, since that is in fact the preferred
868                  *way to set the endpoints.
869                  */

870         if (jwsEndpointsProperty == null) {
871                                     _logger.warning("acc.targetserver.endpoints.warning");
872                 }
873         _logger.fine("System.getProperty(S1ASCtxFactory.IIOP_ENDPOINTS_PROPERTY) ==> " + System.getProperty(S1ASCtxFactory.IIOP_ENDPOINTS_PROPERTY));
874         }
875     } catch (ConfigException t) {
876         _logger.log(Level.WARNING,"acc.acc_xml_file_error" ,
877             new Object JavaDoc[] {clientXmlLocation, t.getMessage()});
878         _logger.log(Level.FINE, "exception : " + t.toString(), t);
879         throw t;
880     }
881     }
882
883     private static void setSSLData(ClientContainer cc) {
884         try {
885             // Set the SSL related properties for ORB
886
TargetServer tServer = cc.getTargetServer(0);
887             // TargetServer is required.
888
//temp solution to target-server+ change in DTD
889
// assuming that multiple servers can be specified but only 1st
890
// first one will be used.
891
Security security = tServer.getSecurity();
892         if (security == null) {
893         _logger.fine("No Security input set in ClientContainer.xml");
894         // do nothing
895
return;
896         }
897         Ssl ssl = security.getSsl();
898         if (ssl == null) {
899         _logger.fine("No SSL input set in ClientContainer.xml");
900         // do nothing
901
return;
902         
903         }
904         //XXX do not use NSS in this release
905
//CertDb certDB = security.getCertDb();
906
SSLUtils.setAppclientSsl(ssl);
907     } catch (Exception JavaDoc ex) {
908
909         }
910     }
911
912     
913     private static void validateXMLFile(String JavaDoc xmlFullName)
914     {
915         //<Bug # 4689278-Start>
916
if(xmlFullName == null ||
917            xmlFullName.startsWith("-")){ // If no file name is given after -xml argument
918
usage();
919         }
920         try {
921             File JavaDoc f = new File JavaDoc(xmlFullName);
922             if((f != null) && f.exists() && f.isFile() && f.canRead()){
923                 return;
924             }else{// If given file does not exists
925
xmlMessage(xmlFullName);
926                 usage();
927             }
928         } catch (Exception JavaDoc ex) {
929             xmlMessage(xmlFullName);
930             usage();
931         }
932         //</Bug # 4689278-End>
933
}
934
935     // Shut down system resource adapters. Currently it is
936
// only JMS.
937
private void shutDownSystemAdapters() {
938        try {
939         com.sun.enterprise.PoolManager poolmgr =
940             Switch.getSwitch().getPoolManager();
941         if ( poolmgr != null ) {
942             Switch.getSwitch().getPoolManager().killFreeConnectionsInPools();
943         }
944     } catch( Exception JavaDoc e ) {
945         //ignore
946
}
947         
948     try {
949             ConnectorRegistry registry = ConnectorRegistry.getInstance();
950             ActiveResourceAdapter activeRar = registry.getActiveResourceAdapter
951                                          (ConnectorRuntime.DEFAULT_JMS_ADAPTER);
952             if (activeRar != null) {
953                 activeRar.destroy();
954             }
955         } catch (Exception JavaDoc e) {
956             // Some thing has gone wrong. No problem
957
_logger.fine("Exception caught while shutting down system adapter:"+e.getMessage());
958         }
959     }
960
961     private static void usage() {
962         System.out.println(localStrings.getString("main.usage",
963             "appclient [ -client <appjar> ] [-mainclass <appClass-name>|-name <display-name>] [-xml <xml>] [-textauth] [-user <username>] [-password <password>|-passwordfile <password-file>] [app-args]"));
964     System.exit(1);
965     }
966     
967     private static void xmlMessage(String JavaDoc xmlFullName)
968     {
969         System.out.println(localStrings.getString("main.cannot_read_clientContainer_xml", xmlFullName,
970              "Client Container xml: " + xmlFullName + " not found or unable to read.\nYou may want to use the -xml option to locate your configuration xml."));
971        
972     }
973
974     private String JavaDoc loadPasswordFromFile(String JavaDoc fileName)
975             throws IOException {
976         InputStream inputStream = null;
977         try {
978             inputStream = new BufferedInputStream(new FileInputStream(fileName));
979             Properties JavaDoc props = new Properties JavaDoc();
980             props.load(inputStream);
981             return props.getProperty("PASSWORD");
982         } finally {
983             if (inputStream != null) {
984                 inputStream.close();
985             }
986         }
987     }
988
989     private static class Cleanup extends Thread JavaDoc {
990         private AppContainer appContainer = null;
991         private boolean cleanedUp = false;
992
993         public Cleanup() {
994         }
995
996         public void setAppContainer(AppContainer container) {
997             appContainer = container;
998         }
999
1000        public void run() {
1001            cleanUp();
1002        }
1003
1004        public void cleanUp() {
1005            if( !cleanedUp ) {
1006                try {
1007                    if( appContainer != null ) {
1008                        appContainer.postInvoke();
1009                    }
1010                }
1011                catch(Throwable JavaDoc t) {
1012                }
1013                finally {
1014                    cleanedUp = true;
1015                }
1016            } // End if -- cleanup required
1017
}
1018    }
1019    /**
1020     *Sets up the user-provided or default sun-acc.xml and
1021     *wss-client-config.xml configurations.
1022     *@return the file name of the sun-acc.xml file
1023     */

1024    private String JavaDoc prepareJWSConfig() throws IOException, FileNotFoundException {
1025        return prepareJWSDefaultConfig();
1026    }
1027    
1028    /**
1029     *Creates temporary files for use as default sun-acc.xml and
1030     *wss-client-config.xml configurations.
1031     *@return the file name of the temporary sun-acc.xml file
1032     */

1033    private String JavaDoc prepareJWSDefaultConfig() throws IOException, FileNotFoundException {
1034        String JavaDoc result = null;
1035        
1036        /*
1037         *Retrieve the sun-acc and wss-client-config templates.
1038         */

1039        String JavaDoc sunACCTemplate = Util.loadResource(this.getClass(), SUN_ACC_DEFAULT_TEMPLATE);
1040        String JavaDoc wssClientConfigTemplate = Util.loadResource(this.getClass(), WSS_CLIENT_CONFIG_TEMPLATE);
1041        
1042        /*
1043         *Prepare the property names and values for substitution in the templates. Some
1044         *of the properties are specified in the environment already, so use those
1045         *as defaults and just add the extra ones.
1046         */

1047        Properties JavaDoc tokenValues = new Properties JavaDoc(System.getProperties());
1048        
1049        /**
1050         *Create the wss client config defaults, then write them to a temporary file.
1051         */

1052        String JavaDoc wssClientConfig = Util.replaceTokens(wssClientConfigTemplate, tokenValues);
1053        File JavaDoc wssClientConfigFile = Util.writeTextToTempFile(wssClientConfig, WSS_CLIENT_CONFIG_PREFIX, WSS_CLIENT_CONFIG_SUFFIX, retainTempFiles);
1054        pendingLogFine.append("Temporary wss-client-config.xml file: " + wssClientConfigFile.getAbsolutePath() + lineSep);
1055        
1056        /*
1057         *Now that the wss temp file is created, insert its name into the default
1058         *sun-acc text and write that to another temp file.
1059         *
1060         *On Windows, the backslashes in the path will be consumed by the replaceTokens method which will
1061         *interpret them as quoting the following character. So replace each \ with \\ first. All the slashes
1062         *have to do with quoting a slash to the Java compiler, then quoting it again to the regex
1063         *processor.
1064         */

1065        String JavaDoc quotedConfigFileSpec = wssClientConfigFile.getAbsolutePath().replaceAll("\\\\", "\\\\\\\\");
1066        tokenValues.setProperty(SUN_ACC_SECURITY_CONFIG_PROPERTY, quotedConfigFileSpec);
1067        
1068        String JavaDoc sunaccContent = Util.replaceTokens(sunACCTemplate, tokenValues);
1069        File JavaDoc sunaccFile = Util.writeTextToTempFile(sunaccContent, SUN_ACC_PREFIX, SUN_ACC_SUFFIX, retainTempFiles);
1070        pendingLogFine.append("Temporary sun-acc.xml file: " + sunaccFile.getAbsolutePath());
1071        
1072        return sunaccFile.getAbsolutePath();
1073    }
1074
1075    /**
1076     *Prepares the JAAS login configuration for a Java Web Start invocation.
1077     *
1078     */

1079    private void prepareJWSLoginConfig() throws IOException, FileNotFoundException {
1080        prepareJWSDefaultLoginConfig();
1081    }
1082    
1083    /**
1084     *Extracts the default login.conf file into a temporary file and assigns the
1085     *java.security.auth.login.config property accordingly.
1086     */

1087    private void prepareJWSDefaultLoginConfig() throws IOException, FileNotFoundException {
1088        String JavaDoc configContent = Util.loadResource(this.getClass(), LOGIN_CONF_TEMPLATE);
1089        File JavaDoc configFile = Util.writeTextToTempFile(configContent, LOGIN_CONF_FILE_PREFIX, LOGIN_CONF_FILE_SUFFIX, retainTempFiles);
1090        String JavaDoc configFilePath = configFile.getAbsolutePath();
1091        pendingLogFine.append("Temporary appclientlogin.conf file: " + configFilePath);
1092        System.setProperty(LOGIN_CONF_PROPERTY_NAME, configFilePath);
1093    }
1094    
1095    /**
1096     *Locate the app client jar file during a Java Web Start launch.
1097     *@return File object for the client jar file
1098     */

1099    private File JavaDoc findAppClientFileForJWSLaunch() throws ClassNotFoundException JavaDoc, URISyntaxException {
1100        /*
1101         *Locate the file by using the name of the "probe" class, passed from the
1102         *server, to load the class and then find the location of the jar that
1103         *contains that class.
1104         */

1105        String JavaDoc probeClassName = System.getProperty(APPCLIENT_PROBE_CLASSNAME_PROPERTYNAME);
1106        _logger.fine("Probing class " + probeClassName);
1107        Class JavaDoc probeClass = Class.forName(probeClassName);
1108        URL workingURL = probeClass.getProtectionDomain().getCodeSource().getLocation();
1109        _logger.fine("Location of appclient jar file: " + workingURL.toString());
1110
1111        /*
1112         *workingURL.toURI() on Windows gives (for example) file:c:/<rest of URI>.
1113         *This cannot be used directly in new File(workingURI) because File complains
1114         *that the URI is not hierarchical - it is missing the / that would
1115         *normally precede the device. So, get the scheme-specific part and
1116         *use that in the File constructor, which gives us the result we need.
1117         */

1118        URI workingURI = workingURL.toURI();
1119        String JavaDoc ssp = workingURI.getSchemeSpecificPart();
1120        return new File JavaDoc(ssp);
1121    }
1122}
1123
Popular Tags