00001
00026 package org.objectweb.jonas.client;
00027
00028 import java.io.File;
00029 import java.io.IOException;
00030 import java.lang.reflect.InvocationTargetException;
00031 import java.lang.reflect.Method;
00032 import java.net.MalformedURLException;
00033 import java.net.URL;
00034 import java.net.URLClassLoader;
00035 import java.util.ArrayList;
00036 import java.util.Iterator;
00037 import java.util.List;
00038 import java.util.Map;
00039 import java.util.StringTokenizer;
00040 import java.util.jar.Attributes;
00041 import java.util.jar.JarFile;
00042 import java.util.jar.Manifest;
00043
00044 import javax.naming.Context;
00045 import javax.naming.LinkRef;
00046 import javax.naming.NamingException;
00047 import javax.naming.Reference;
00048 import javax.naming.StringRefAddr;
00049 import javax.security.auth.callback.CallbackHandler;
00050 import javax.security.auth.login.LoginContext;
00051
00052 import org.objectweb.carol.util.configuration.CarolConfiguration;
00053
00054 import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDesc;
00055 import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDescException;
00056 import org.objectweb.jonas_client.deployment.lib.ClientDeploymentDescManager;
00057
00058 import org.objectweb.jonas_ear.deployment.api.EarDeploymentDesc;
00059 import org.objectweb.jonas_ear.deployment.api.EarDeploymentDescException;
00060 import org.objectweb.jonas_ear.deployment.lib.EarDeploymentDescManager;
00061 import org.objectweb.jonas_ear.deployment.xml.Web;
00062
00063 import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
00064
00065 import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
00066 import org.objectweb.jonas_lib.deployment.api.EnvEntryDesc;
00067 import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc;
00068 import org.objectweb.jonas_lib.deployment.api.ResourceEnvRefDesc;
00069 import org.objectweb.jonas_lib.deployment.api.ResourceRefDesc;
00070 import org.objectweb.jonas_lib.deployment.work.EarFileManager;
00071 import org.objectweb.jonas_lib.naming.ContainerNaming;
00072
00073 import org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager;
00074
00075 import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc;
00076
00077 import org.objectweb.jonas.common.Log;
00078 import org.objectweb.jonas.ear.lib.EarClassPathManager;
00079 import org.objectweb.jonas.ear.lib.EarClassPathManagerException;
00080 import org.objectweb.jonas.ear.lib.JarList;
00081 import org.objectweb.jonas.ear.lib.JarListException;
00082 import org.objectweb.jonas.naming.NamingManager;
00083 import org.objectweb.jonas.security.auth.callback.NoInputCallbackHandler;
00084 import org.objectweb.jonas.security.jacc.JPolicyUserRoleMapping;
00085 import org.objectweb.jonas.ws.ClientJServiceFactoryFinder;
00086 import org.objectweb.jonas.ws.JServiceFactory;
00087
00088 import org.objectweb.util.monolog.api.BasicLevel;
00089 import org.objectweb.util.monolog.api.Logger;
00090
00096 public class ClientContainer {
00097
00101 private static final String CAROL_FILE = "carol.properties";
00102
00106 private String mainClass = null;
00107
00111 private String tmpDir = null;
00112
00116 private String jarClient = null;
00117
00121 private String classpath = null;
00122
00126 private String clientTraceFile = null;
00127
00131 private ContainerNaming naming;
00132
00136 private String carolFile = null;
00137
00141 private String[] args = null;
00142
00146 private URLClassLoader earClassLoader = null;
00147
00151 private ArrayList appArgs = null;
00152
00156 private URL[] extensionsURLs = null;
00157
00161 private Logger logger = null;
00162
00167 private ClientContainer(String[] args) {
00168 this.args = args;
00169
00170 appArgs = new ArrayList();
00171 }
00172
00176 private void initLogger() {
00177
00178 Log.configure(clientTraceFile);
00179
00180 this.logger = Log.getLogger(Log.JONAS_CLIENT_PREFIX);
00181 }
00182
00187 public static void main(String[] args) {
00188
00189 ClientContainer cc = new ClientContainer(args);
00190
00191 try {
00192 cc.start();
00193 } catch (InvocationTargetException ite) {
00194 Throwable t = ite.getTargetException();
00195 String message = t.getMessage();
00196 if (t instanceof Error) {
00197 System.err.println("There was the following error : " + message);
00198 } else if (t instanceof Exception) {
00199 System.err.println("There was the following exception : " + message);
00200 }
00201 t.printStackTrace(System.err);
00202 } catch (Exception e) {
00203 System.err.println("There was the following exception : " + e.getMessage());
00204 e.printStackTrace();
00205 System.exit(-1);
00206 }
00207 }
00208
00213 private void start() throws Exception {
00214 analyzeArgs();
00215
00216
00217 if (clientTraceFile != null) {
00218 File tClient = new File(clientTraceFile);
00219
00220 if (!tClient.exists()) {
00221 throw new ClientContainerException("The file '" + clientTraceFile + "' was not found.");
00222 }
00223
00224 if (!tClient.isFile()) {
00225 throw new ClientContainerException("The file '" + clientTraceFile
00226 + "' is not a valid file. Maybe a directory ?");
00227 }
00228
00229
00230 System.setProperty("jonas.client.trace.file", clientTraceFile);
00231 Log.reset();
00232 } else {
00233 clientTraceFile = "traceclient";
00234 }
00235
00236 initLogger();
00237
00238
00239 String userArg = null;
00240 String fileName = null;
00241 boolean fileMode = true;
00242
00243 try {
00244 userArg = (String) appArgs.get(0);
00245 } catch (IndexOutOfBoundsException ioobe) {
00246 usage();
00247 throw new ClientContainerException(
00248 "You haven't specify a jar, an ear file or class name as argument. See the Usage.");
00249 }
00250
00251 String className = null;
00252
00253 if (!(userArg.toLowerCase().endsWith(".jar") || userArg.toLowerCase().endsWith(".ear"))) {
00254 className = userArg;
00255 fileMode = false;
00256 } else {
00257 fileMode = true;
00258 fileName = userArg;
00259 }
00260
00261
00262 File clientJarFile = null;
00263 if (fileMode) {
00264 File argFile = new File(fileName);
00265
00266 if (!argFile.exists()) {
00267 throw new ClientContainerException("The specified file '" + fileName + "' doesn't exists.");
00268 }
00269
00270
00271 if (fileName.toLowerCase().endsWith(".ear")) {
00272 clientJarFile = extractAndAnalyzeEar(argFile);
00273 } else {
00274
00275 clientJarFile = argFile;
00276 }
00277 }
00278
00279
00280 System.setProperty("javax.rmi.CORBA.PortableRemoteObjectClass",
00281 "org.objectweb.carol.rmi.multi.MultiPRODelegate");
00282 System.setProperty("java.naming.factory.initial", "org.objectweb.carol.jndi.spi.MultiOrbInitialContextFactory");
00283 System.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.org.objectweb.jotm.ots.OTSORBInitializer",
00284 "");
00285 System.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.org.objectweb.jonas.security.interceptors.iiop.SecurityInitializer",
00286 "");
00287 System.setProperty("org.omg.CORBA.ORBClass" , "org.jacorb.orb.ORB");
00288 System.setProperty("org.omg.CORBA.ORBSingletonClass", "org.jacorb.orb.ORBSingleton");
00289 System.setProperty("org.omg.PortableInterceptor.ORBInitializerClass.standard_init" , "org.jacorb.orb.standardInterceptors.IORInterceptorInitializer");
00290
00291
00292 System.setProperty("axis.jaxrpc11Compliance", "true");
00293
00294
00295
00296
00297
00298
00299 URL urlCarolFile = null;
00300
00301 if (carolFile != null) {
00302 File fCarol = new File(carolFile);
00303
00304 if (!fCarol.exists()) {
00305 throw new ClientContainerException("The file '" + carolFile + "' was not found.");
00306 }
00307
00308 if (!fCarol.isFile()) {
00309 throw new ClientContainerException("The file '" + carolFile
00310 + "' is not a valid file. Maybe a directory ?");
00311 }
00312
00313 if (!fCarol.getName().equals(CAROL_FILE)) {
00314 throw new ClientContainerException("The file '" + carolFile + "' must be named '" + CAROL_FILE + "'.");
00315 }
00316
00317 try {
00318 urlCarolFile = fCarol.getParentFile().toURL();
00319 } catch (MalformedURLException mue) {
00320 throw new ClientContainerException("Error when building an URL for the file '" + fCarol + "'.");
00321 }
00322 }
00323
00324 ArrayList sysCP = getSystemClassPath();
00325 URL[] urlsCarol = null;
00326 int urlInd = 0;
00327
00328
00329
00330 int argNumberFile = 0;
00331 if (fileMode) {
00332 argNumberFile++;
00333 }
00334
00335 if (urlCarolFile != null) {
00336
00337 urlsCarol = new URL[sysCP.size() + 1 + argNumberFile];
00338 urlsCarol[urlInd] = urlCarolFile;
00339 urlInd++;
00340 } else {
00341
00342 urlsCarol = new URL[sysCP.size() + argNumberFile];
00343 }
00344
00345 try {
00346
00347 if (fileMode) {
00348 urlsCarol[urlInd] = clientJarFile.toURL();
00349 urlInd++;
00350 }
00351 int classPathSize = sysCP.size();
00352 for (int j = 0; j < classPathSize; j++) {
00353 urlsCarol[urlInd] = new File(((String) sysCP.get(j))).toURL();
00354 urlInd++;
00355 }
00356 } catch (MalformedURLException mue) {
00357 throw new ClientContainerException("Error when building an URL for the classpath.");
00358 }
00359
00360 ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
00361 URLClassLoader newCL = new URLClassLoader(urlsCarol, null);
00362 Thread.currentThread().setContextClassLoader(newCL);
00363
00364 if (logger.isLoggable(BasicLevel.DEBUG)) {
00365 URL[] urls = newCL.getURLs();
00366 logger.log(BasicLevel.DEBUG, "URLs of the classloader for Carol :");
00367 for (int u = 0; u < urls.length; u++) {
00368 logger.log(BasicLevel.DEBUG, "URL[" + u + "] = " + urls[u]);
00369 }
00370 }
00371
00372
00373 CarolConfiguration.init(Log.getLoggerFactory());
00374 Thread.currentThread().setContextClassLoader(oldCL);
00375
00376
00377 CarolConfiguration.addInterceptors("iiop", "org.objectweb.jonas.security.iiop.Csiv2Initializer");
00378
00379
00380
00381
00382 if (fileMode) {
00383 Manifest manifest = new JarFile(clientJarFile).getManifest();
00384
00385 if (manifest == null) {
00386 throw new ClientContainerException("No manifest was found inside the file" + clientJarFile);
00387 }
00388
00389
00390 Attributes attributes = manifest.getMainAttributes();
00391
00392 if (attributes == null) {
00393 throw new ClientContainerException("No attributes were found in the manifest of the file '"
00394 + clientJarFile + "'.");
00395 }
00396 mainClass = attributes.getValue(Attributes.Name.MAIN_CLASS);
00397 } else {
00398 mainClass = className;
00399 }
00400
00401
00402 if (!fileMode) {
00403 ClassLoader clientCL = new URLClassLoader(getUserClasspathUrls());
00404 Thread.currentThread().setContextClassLoader(clientCL);
00405 invokeClient();
00406 return;
00407 }
00408
00409 if (mainClass == null || mainClass.length() == 0) {
00410 throw new ClientContainerException("No main class was found inside the Manifest of the file '"
00411 + clientJarFile + "'. This attribute is required to launch the application client.");
00412 }
00413
00414 if (logger.isLoggable(BasicLevel.DEBUG)) {
00415 logger.log(BasicLevel.DEBUG, "Using Main-Class :" + mainClass);
00416 }
00417
00418
00419 URL clientJarURL = null;
00420
00421 try {
00422 clientJarURL = clientJarFile.toURL();
00423 } catch (MalformedURLException mue) {
00424 throw new ClientContainerException("Error when building an URL with the file '" + clientJarFile + "'.");
00425 }
00426
00427
00428 URL[] urlsClient = null;
00429
00430
00431 if (extensionsURLs != null) {
00432
00433 urlsClient = new URL[extensionsURLs.length + 1];
00434
00435 for (int i = 0; i < extensionsURLs.length; i++) {
00436 urlsClient[i] = extensionsURLs[i];
00437
00438 if (logger.isLoggable(BasicLevel.DEBUG)) {
00439 logger.log(BasicLevel.DEBUG, "Adding " + extensionsURLs[i] + " to the urls of the client");
00440 }
00441 }
00442
00443 urlsClient[extensionsURLs.length] = clientJarURL;
00444 } else {
00445 if (logger.isLoggable(BasicLevel.DEBUG)) {
00446 logger.log(BasicLevel.DEBUG, "Only one url for urls of client");
00447 }
00448
00449
00450 urlsClient = new URL[1];
00451 urlsClient[0] = clientJarURL;
00452 }
00453
00454
00455 URLClassLoader clientClassloader = new URLClassLoader(urlsClient, Thread.currentThread()
00456 .getContextClassLoader());
00457 Thread.currentThread().setContextClassLoader(clientClassloader);
00458
00459
00460 ClientContainerDeploymentDesc clientDD = null;
00461 if (extensionsURLs != null) {
00462 EjbDeploymentDescManager.getInstance().addClassLoaderUrlMapping(clientClassloader, extensionsURLs);
00463 }
00464
00465 try {
00466 clientDD = ClientDeploymentDescManager.getInstance().getDeploymentDesc(clientJarURL, clientClassloader, earClassLoader);
00467 } catch (ClientContainerDeploymentDescException e) {
00468 String err = "Cannot read the deployment descriptors '" + clientJarURL + "'";
00469 error(err + ": " + e);
00470 throw new ClientContainerException(err + e.getMessage());
00471 }
00472
00473
00474 try {
00475 setClientEnvironment(clientDD);
00476 } catch (Exception e) {
00477
00478 String err = "Error when populating ";
00479 error(err + e.getMessage());
00480 throw new ClientContainerException(err, e);
00481 }
00482
00483
00484 String jaasFile = clientDD.getJaasFile();
00485 String jaasEntry = clientDD.getJaasEntry();
00486 String username = clientDD.getUsername();
00487 String password = clientDD.getPassword();
00488
00489 if (logger.isLoggable(BasicLevel.DEBUG)) {
00490 logger.log(BasicLevel.DEBUG, "Using jaas file = " + jaasFile);
00491 }
00492
00493 String jaasConfigFile = null;
00494
00495 if (jaasFile != null) {
00496
00497 jaasConfigFile = "jar:" + clientJarURL.toExternalForm() + "!/" + jaasFile;
00498 System.setProperty("java.security.auth.login.config", jaasConfigFile);
00499 }
00500
00501 CallbackHandler ch = null;
00502
00503 if ((username != null) && (password != null)) {
00504 ch = new NoInputCallbackHandler(username, password);
00505 info("Using the login/password specified in the jonas-client.xml file with a specific CallbackHandler");
00506 } else {
00507
00508 String ddCallbackHandler = clientDD.getCallbackHandler();
00509
00510 if (ddCallbackHandler != null) {
00511 if (logger.isLoggable(BasicLevel.DEBUG)) {
00512 logger.log(BasicLevel.DEBUG, "Using '" + ddCallbackHandler + "' class as CallbackHandler.");
00513 }
00514
00515 Class clazz = null;
00516
00517
00518 try {
00519 clazz = clientClassloader.loadClass(ddCallbackHandler);
00520 } catch (Exception e) {
00521 throw new ClientContainerException("There was an error while trying to instantiate the class '"
00522 + ddCallbackHandler
00523 + "' which is specified in the application.xml as CallbackHandler class", e);
00524 }
00525
00526 try {
00527 ch = (CallbackHandler) clazz.newInstance();
00528 } catch (Exception e) {
00529 throw new ClientContainerException(
00530 "Error while triyng to cast the class '"
00531 + ddCallbackHandler
00532 + "' to CallbackHandler interface, maybe the specified class doesn't implement this interface.",
00533 e);
00534 }
00535 }
00536 }
00537
00538
00539 if (ch != null) {
00540 if (jaasFile == null) {
00541 throw new ClientContainerException(
00542 "You have defined that you want use a CallbackHandler but you haven't specify the jaas file to use for the JAAS configuration.");
00543 }
00544
00545 if (jaasEntry == null) {
00546 throw new ClientContainerException(
00547 "You have defined that you want use a CallbackHandler but you haven't specify the jaas entry to use from the jaas config file.");
00548 }
00549
00550 info("Using JAAS loginContext '" + jaasEntry + "' from the file '" + jaasConfigFile + "'.");
00551
00552 try {
00553 LoginContext lc = new LoginContext(jaasEntry, ch);
00554 lc.login();
00555 } catch (Exception e) {
00556 String err = "Can not use the JAAS authentication";
00557 error(err);
00558 throw new ClientContainerException(err, e);
00559 }
00560 }
00561
00562
00563 invokeClient();
00564
00565 }
00566
00574 private void invokeClient() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
00575 InvocationTargetException {
00576 ClassLoader clientClassloader = Thread.currentThread().getContextClassLoader();
00577
00578 if (logger.isLoggable(BasicLevel.DEBUG)) {
00579 if (clientClassloader instanceof URLClassLoader) {
00580 URLClassLoader urlClassLoader = (URLClassLoader) clientClassloader;
00581 URL[] urls = urlClassLoader.getURLs();
00582 logger.log(BasicLevel.DEBUG, "URLs of the classloader :");
00583 for (int u = 0; u < urls.length; u++) {
00584 logger.log(BasicLevel.DEBUG, "URL[" + u + "] = " + urls[u]);
00585 }
00586 }
00587 }
00588
00589
00590
00591 Class clazz = clientClassloader.loadClass(mainClass);
00592 Class[] argList = new Class[] {args.getClass()};
00593 Method meth = clazz.getMethod("main", argList);
00594
00595
00596 String[] newArgs = new String[appArgs.size() - 1];
00597 String txtArgs = "";
00598
00599 for (int i = 0; i < newArgs.length; i++) {
00600 newArgs[i] = (String) appArgs.get(i + 1);
00601 txtArgs += (newArgs[i] + " ");
00602 }
00603
00604 if (logger.isLoggable(BasicLevel.DEBUG)) {
00605 logger.log(BasicLevel.DEBUG, "Starting the application client with the arguments '" + txtArgs + "'.");
00606 }
00607
00608 info("Starting client...");
00609
00610 meth.invoke(null, new Object[] {newArgs});
00611
00612 if (logger.isLoggable(BasicLevel.DEBUG)) {
00613 logger.log(BasicLevel.DEBUG, "End of main method");
00614 }
00615
00616 }
00617
00623 private void setClientEnvironment(ClientContainerDeploymentDesc clientDD) throws NamingException {
00624 if (logger.isLoggable(BasicLevel.DEBUG)) {
00625 logger.log(BasicLevel.DEBUG, "");
00626 }
00627
00628
00629 try {
00630 naming = NamingManager.getInstance();
00631 } catch (NamingException e) {
00632 throw new ClientContainerException("Error when getting the reference to the Naming manager", e);
00633 }
00634
00635 Context javaCtx = naming.createEnvironmentContext("ClientContainer");
00636 naming.setClientContainerComponentContext(javaCtx);
00637
00638 Context envCtx = javaCtx.createSubcontext("comp/env");
00639
00640
00641 EnvEntryDesc[] envt = clientDD.getEnvEntryDesc();
00642
00643 for (int i = 0; i < envt.length; i++) {
00644
00645 String name = envt[i].getName();
00646 Object obj = envt[i].getValue();
00647
00648
00649 if (logger.isLoggable(BasicLevel.DEBUG)) {
00650 logger.log(BasicLevel.DEBUG, "Binding object " + name + " -> " + obj);
00651 }
00652
00653 envCtx.rebind(name, obj);
00654 }
00655
00656
00657 ResourceRefDesc[] resref = clientDD.getResourceRefDesc();
00658
00659 for (int i = 0; i < resref.length; i++) {
00660
00661 String name = resref[i].getName();
00662 String resname = resref[i].getJndiName();
00663 String type = resref[i].getTypeName();
00664
00665
00666
00667
00668 if (logger.isLoggable(BasicLevel.DEBUG)) {
00669 logger.log(BasicLevel.DEBUG, "Linking resource " + name + " -> " + resname);
00670 }
00671
00672 if (type.equalsIgnoreCase("java.net.URL")) {
00673
00674 Reference ref = new Reference("java.net.URL", "org.objectweb.jonas_lib.naming.factory.URLFactory", null);
00675 StringRefAddr refAddr = new StringRefAddr("url", resname);
00676 ref.add(refAddr);
00677 envCtx.rebind(name, ref);
00678 } else {
00679 LinkRef lref = new LinkRef(resname);
00680 envCtx.rebind(name, lref);
00681 }
00682 }
00683
00684
00685 ResourceEnvRefDesc[] resEnvref = clientDD.getResourceEnvRefDesc();
00686
00687 for (int i = 0; i < resEnvref.length; i++) {
00688
00689 String name = resEnvref[i].getName();
00690 String resname = resEnvref[i].getJndiName();
00691 LinkRef lref = new LinkRef(resname);
00692
00693 if (logger.isLoggable(BasicLevel.DEBUG)) {
00694 logger.log(BasicLevel.DEBUG, "Linking resource environment " + name + " -> " + resname);
00695 }
00696
00697 envCtx.rebind(name, lref);
00698 }
00699
00700
00701 EjbRefDesc[] ejbref = clientDD.getEjbRefDesc();
00702
00703 for (int i = 0; i < ejbref.length; i++) {
00704
00705 String name = ejbref[i].getEjbRefName();
00706 String ejbname = null;
00707 ejbname = ejbref[i].getJndiName();
00708
00709 LinkRef lref = new LinkRef(ejbname);
00710
00711 if (logger.isLoggable(BasicLevel.DEBUG)) {
00712 logger.log(BasicLevel.DEBUG, "Linking ejb " + name + " -> " + ejbname);
00713 }
00714
00715 envCtx.rebind(name, lref);
00716 }
00717
00718
00719 ServiceRefDesc[] serviceRefs = clientDD.getServiceRefDesc();
00720 if (serviceRefs.length != 0) {
00721
00722
00723 ClassLoader loader = Thread.currentThread().getContextClassLoader();
00724
00725
00726 JServiceFactory factory = ClientJServiceFactoryFinder.getJOnASServiceFactory();
00727
00728 for (int i = 0; i < serviceRefs.length; i++) {
00729
00730 String refname = serviceRefs[i].getServiceRefName();
00731
00732 Reference ref = factory.getServiceReference(serviceRefs[i], loader);
00733 envCtx.rebind(refname, ref);
00734
00735 if (logger.isLoggable(BasicLevel.DEBUG)) {
00736 logger.log(BasicLevel.DEBUG, "Adding service-ref 'java:comp/env/" + refname + "'");
00737 }
00738 }
00739 }
00740
00741
00742 MessageDestinationRefDesc[] mdref = clientDD.getMessageDestinationRefDesc();
00743
00744 for (int i = 0; i < mdref.length; i++) {
00745
00746 String name = mdref[i].getMessageDestinationRefName();
00747 String mdname = null;
00748 mdname = mdref[i].getJndiName();
00749
00750 LinkRef lref = new LinkRef(mdname);
00751
00752 if (logger.isLoggable(BasicLevel.DEBUG)) {
00753 logger.log(BasicLevel.DEBUG, "Linking message-destination-ref " + name + " -> " + mdname);
00754 }
00755
00756 envCtx.rebind(name, lref);
00757 }
00758 }
00759
00764 private void analyzeArgs() throws Exception {
00765 for (int argn = 0; argn < args.length; argn++) {
00766 String arg = args[argn];
00767
00768 try {
00769 if (arg.equals("-tmpDir")) {
00770 tmpDir = args[++argn];
00771
00772 continue;
00773 }
00774
00775 if (arg.equals("-jarClient")) {
00776 jarClient = args[++argn];
00777
00778 continue;
00779 }
00780
00781 if (arg.equals("-traceFile")) {
00782 clientTraceFile = args[++argn];
00783
00784 continue;
00785 }
00786
00787 if (arg.equals("-carolFile")) {
00788 carolFile = args[++argn];
00789
00790 continue;
00791 }
00792
00793 if (arg.equals("-cp")) {
00794 classpath = args[++argn];
00795 continue;
00796 }
00797
00798 if (arg.equals("--help") || arg.equals("-help") || arg.equals("-h") || arg.equals("-?")) {
00799 usage();
00800 System.exit(1);
00801 }
00802
00803
00804 appArgs.add(arg);
00805 } catch (ArrayIndexOutOfBoundsException aioobe) {
00806
00807 throw new ClientContainerException("A required parameter was missing after the argument" + arg);
00808 }
00809 }
00810 }
00811
00815 private void usage() {
00816 System.out.println("Usage of this client :");
00817 System.out.println("-------------------------------------------------------------------");
00818 System.out.println("java -jar client.jar <client.jar|app.ear|className> [options]");
00819 System.out.println("-------------------------------------------------------------------");
00820 System.out.println(" -jarClient : Specify the client jar to use of the ear if many.");
00821 System.out.println(" -traceFile : Specify the configuration file to use for the traces\n"
00822 + " of this client instead of the default file\n"
00823 + " (traceclient.properties) present in client.jar.");
00824 System.out.println(" -carolFile : Specify the carol.properties file to use instead of \n"
00825 + " the default carol.properties file of the client.jar");
00826 System.out.println(" -tmpDir : Specify the temp directory where unpack the ear.");
00827 System.out.println(" -cp : Specify the classpath to use for the jar client.");
00828 System.out.println("-------------------------------------------------------------------");
00829 System.out.println(" --help : Display this help.");
00830 System.out.println(" -help : Display this help.");
00831 System.out.println(" -h : Display this help.");
00832 System.out.println(" -? : Display this help.");
00833 System.out.println("-------------------------------------------------------------------");
00834 }
00835
00842 private File extractAndAnalyzeEar(File earFile) throws Exception {
00843 if (logger.isLoggable(BasicLevel.DEBUG)) {
00844 logger.log(BasicLevel.DEBUG, "");
00845 }
00846
00847 URL earUrl = null;
00848
00849 try {
00850 earUrl = earFile.toURL();
00851 } catch (MalformedURLException mue) {
00852 throw new ClientContainerException("Can not build an url with the filename '" + earFile + "'.");
00853 }
00854
00855
00856 URL[] arrURL = new URL[1];
00857 arrURL[0] = earUrl;
00858
00859
00860 ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
00861 URLClassLoader loaderCls = new URLClassLoader(arrURL, currentLoader);
00862
00863 EarDeploymentDesc earDD = null;
00864
00865 if (logger.isLoggable(BasicLevel.DEBUG)) {
00866 logger.log(BasicLevel.DEBUG, "Getting the deployment descriptor of the file" + earFile.getPath());
00867 }
00868
00869 try {
00870 earDD = EarDeploymentDescManager.getDeploymentDesc(earFile.getPath(), loaderCls);
00871 } catch (EarDeploymentDescException e) {
00872 String err = "Error in the Deployment descriptor '" + earFile + "': " + e;
00873
00874
00875 throw new ClientContainerException(err, e);
00876 }
00877
00878 Map userToRoleMapping = earDD.getUserToRoleMapping();
00879
00880 if (userToRoleMapping != null) {
00881 for (Iterator itMapping = userToRoleMapping.keySet().iterator(); itMapping.hasNext();) {
00882 String principalName = (String) itMapping.next();
00883 List roles = (List) userToRoleMapping.get(principalName);
00884 String[] roleNames = (String[]) roles.toArray(new String[roles.size()]);
00885 JPolicyUserRoleMapping.addGlobalUserToRoleMapping(principalName, roleNames);
00886 }
00887 }
00888
00889
00890
00891 String[] ejbTags = earDD.getEjbTags();
00892 Web[] webTags = earDD.getWebTags();
00893 String[] clientTags = earDD.getClientTags();
00894 String[] altDDEjbs = earDD.getAltDDEjbs();
00895 String[] altDDWebs = earDD.getAltDDWebs();
00896 String[] altDDClients = earDD.getAltDDClients();
00897
00898
00899
00900 File fEar = null;
00901 File tmpFile = null;
00902
00903 try {
00904 fEar = earFile.getCanonicalFile();
00905 } catch (IOException ioe) {
00906 String err = "Error : Can not get canonical file for the file '" + earFile + "'.";
00907 throw new ClientContainerException(err);
00908 }
00909
00910 try {
00911 for (int i = 0; i < ejbTags.length; i++) {
00912 tmpFile = new File(fEar, ejbTags[i]);
00913 tmpFile = tmpFile.getCanonicalFile();
00914 if (!tmpFile.getPath().startsWith(fEar.getPath())) {
00915 String err = "Error : The ejb-jar file " + ejbTags[i] + " is not inside the ear file " + fEar;
00916 throw new ClientContainerException(err);
00917 }
00918 }
00919
00920 for (int i = 0; i < webTags.length; i++) {
00921 tmpFile = new File(fEar, webTags[i].getWebUri());
00922 tmpFile = tmpFile.getCanonicalFile();
00923 if (!tmpFile.getPath().startsWith(fEar.getPath())) {
00924 String err = "Error : The webapp file " + webTags[i] + " is not inside the ear file " + fEar;
00925 throw new ClientContainerException(err);
00926 }
00927 }
00928
00929 for (int i = 0; i < clientTags.length; i++) {
00930 tmpFile = new File(fEar, clientTags[i]);
00931 tmpFile = tmpFile.getCanonicalFile();
00932
00933 if (!tmpFile.getPath().startsWith(fEar.getPath())) {
00934 String err = "Error : The client jar file " + clientTags[i] + " is not inside the ear file " + fEar;
00935 throw new ClientContainerException(err);
00936 }
00937 }
00938 } catch (IOException ioe) {
00939 String err = "Error while trying to get the canonical file of " + tmpFile;
00940 throw new ClientContainerException(err, ioe);
00941 }
00942
00943
00944 JarList ejbsList = new JarList(ejbTags);
00945 JarList websList = new JarList(webTags);
00946 JarList clientsList = new JarList(clientTags);
00947
00948
00949 String tempDir = null;
00950
00951 if (tmpDir != null) {
00952
00953 tempDir = tmpDir;
00954 info("Use your specified temp directory '" + tempDir + "'.");
00955 } else {
00956
00957 tempDir = System.getProperty("java.io.tmpdir");
00958 }
00959
00960 if (logger.isLoggable(BasicLevel.DEBUG)) {
00961 logger.log(BasicLevel.DEBUG, "Using temp directory '" + tempDir + "'.");
00962 }
00963
00964
00965 File tmpFileDir = new File(tempDir);
00966
00967 if (!tmpFileDir.exists() || !tmpFileDir.isDirectory()) {
00968 throw new ClientContainerException("The temp directory '" + tempDir
00969 + "' doesn't exist or is not a directory.");
00970 }
00971
00972 if (!tmpFileDir.canWrite()) {
00973 throw new ClientContainerException("Can not write to the temporary directory '" + tempDir + "'.");
00974 }
00975
00976
00977 URL dirUnpackURL = null;
00978
00979 try {
00980 dirUnpackURL = EarFileManager.unpackEar(earUrl, tmpFileDir.toURL(), false);
00981 } catch (Exception e) {
00982 String err = "Error while unpacking the file '" + earUrl + "'";
00983 throw new ClientContainerException(err, e);
00984 }
00985
00986
00987 EarClassPathManager earCPManager = null;
00988
00989 try {
00990 earCPManager = new EarClassPathManager(clientsList, dirUnpackURL);
00991 } catch (EarClassPathManagerException e) {
00992 String err = "Error while creating the Ear class path manager of the ear : '" + earUrl + "'";
00993 error(err + " : " + e.getMessage());
00994 throw new ClientContainerException(err, e);
00995 }
00996
00997 URL[] classpathURLs = null;
00998
00999
01000 try {
01001 classpathURLs = earCPManager.getResolvedClassPath();
01002 } catch (EarClassPathManagerException e) {
01003 String err = "Error while trying to resolve the classpath of the ejbjars and wars of the ear : '" + earUrl
01004 + "'";
01005 error(err + " : " + e.getMessage());
01006 throw new ClientContainerException(err, e);
01007 }
01008
01009 if (logger.isLoggable(BasicLevel.DEBUG)) {
01010 logger.log(BasicLevel.DEBUG, "EAR : ejbs = " + ejbsList);
01011 logger.log(BasicLevel.DEBUG, "EAR : clientUrls = " + clientsList);
01012 }
01013
01014 currentLoader = Thread.currentThread().getContextClassLoader();
01015 earClassLoader = new URLClassLoader(new URL[0], currentLoader);
01016
01017
01018 URL[] jarUrls = null;
01019 URL[] warUrls = null;
01020 URL[] clientUrls = null;
01021
01022 try {
01023 jarUrls = ejbsList.getURLs(dirUnpackURL.toExternalForm());
01024 warUrls = websList.getURLs(dirUnpackURL.toExternalForm());
01025 clientUrls = clientsList.getURLs(dirUnpackURL.toExternalForm());
01026 } catch (JarListException e) {
01027 String err = "Error while geting the Urls from jarlist of the ear : '" + earUrl + "'";
01028 throw new ClientContainerException(err, e);
01029 }
01030
01031
01032 String altdd = null;
01033 File fAltDD = null;
01034
01035
01036
01037 URL[] clientsAltDDs = new URL[altDDClients.length];
01038
01039 for (int i = 0; i < altDDClients.length; i++) {
01040 if (altDDClients[i] != null) {
01041 altdd = altDDClients[i];
01042
01043 if (altdd != null) {
01044 try {
01045 fAltDD = new File(new URL(dirUnpackURL.toExternalForm() + File.separator + altdd).getFile());
01046 clientsAltDDs[i] = fAltDD.getCanonicalFile().toURL();
01047 } catch (MalformedURLException e) {
01048 String err = "Can't build URL for alt-dd '" + altdd;
01049 error(err + "': " + e.getMessage());
01050 throw new ClientContainerException(err, e);
01051 } catch (IOException ioe) {
01052 String err = "Can't get canonicalFile() for the file '" + fAltDD;
01053 error(err + "': " + ioe.getMessage());
01054 throw new ClientContainerException(err, ioe);
01055 }
01056 }
01057 }
01058 }
01059
01060 URL[] ejbsAltDDs = new URL[altDDEjbs.length];
01061
01062 for (int i = 0; i < altDDEjbs.length; i++) {
01063 if (altDDEjbs[i] != null) {
01064 altdd = altDDEjbs[i];
01065
01066 if (altdd != null) {
01067 try {
01068 fAltDD = new File(new URL(dirUnpackURL.toExternalForm() + File.separator + altdd).getFile());
01069 ejbsAltDDs[i] = fAltDD.getCanonicalFile().toURL();
01070 } catch (MalformedURLException e) {
01071 String err = "Can't build URL for alt-dd '" + altdd;
01072 error(err + "': " + e.getMessage());
01073 throw new ClientContainerException(err, e);
01074 } catch (IOException ioe) {
01075 String err = "Can't get canonicalFile() for the file '" + fAltDD;
01076 error(err + "': " + ioe.getMessage());
01077 throw new ClientContainerException(err, ioe);
01078 }
01079 }
01080 }
01081 }
01082
01083 URL[] websAltDDs = new URL[altDDWebs.length];
01084
01085 for (int i = 0; i < altDDWebs.length; i++) {
01086 if (altDDWebs[i] != null) {
01087 altdd = altDDWebs[i];
01088
01089 if (altdd != null) {
01090 try {
01091 fAltDD = new File(new URL(dirUnpackURL.toExternalForm() + File.separator + altdd).getFile());
01092 websAltDDs[i] = fAltDD.getCanonicalFile().toURL();
01093 } catch (MalformedURLException e) {
01094 String err = "Can't build URL for alt-dd '" + altdd;
01095 error(err + "': " + e.getMessage());
01096 throw new ClientContainerException(err, e);
01097 } catch (IOException ioe) {
01098 String err = "Can't get canonicalFile() for the file '" + fAltDD;
01099 error(err + "': " + ioe.getMessage());
01100 throw new ClientContainerException(err, ioe);
01101 }
01102 }
01103 }
01104 }
01105
01106 EjbDeploymentDescManager.getInstance().setAvailableEjbJarsAndAltDDs(earClassLoader, jarUrls, ejbsAltDDs);
01107 WebDeploymentDescManager.getInstance().setAltDD(earClassLoader, warUrls, websAltDDs);
01108 ClientDeploymentDescManager.getInstance().setAltDD(earClassLoader, clientUrls, clientsAltDDs);
01109
01110
01111
01112
01113 URL[] userURLs = getUserClasspathUrls();
01114 extensionsURLs = new URL[jarUrls.length + classpathURLs.length + userURLs.length];
01115
01116 System.arraycopy(jarUrls, 0, extensionsURLs, 0, jarUrls.length);
01117 System.arraycopy(classpathURLs, 0, extensionsURLs, jarUrls.length, classpathURLs.length);
01118 System.arraycopy(userURLs, 0, extensionsURLs, jarUrls.length + classpathURLs.length, userURLs.length);
01119
01120 if (logger.isLoggable(BasicLevel.DEBUG)) {
01121 logger.log(BasicLevel.DEBUG, "Extensions urls :");
01122
01123 for (int ii = 0; ii < extensionsURLs.length; ii++) {
01124 logger.log(BasicLevel.DEBUG, "url[" + ii + "] = " + extensionsURLs[ii]);
01125 }
01126 }
01127
01128
01129 if (clientUrls.length == 0) {
01130 throw new ClientContainerException("No java client was found in the application.xml file of the Ear '"
01131 + earUrl + "'.");
01132 }
01133
01134 File fClient = null;
01135
01136
01137
01138 if (jarClient != null) {
01139 int f = 0;
01140 File ff = null;
01141 boolean found = false;
01142
01143 while (f < clientUrls.length && !found) {
01144 ff = new File(clientUrls[f].getFile());
01145
01146 if (ff.getPath().endsWith(jarClient)) {
01147 found = true;
01148 fClient = ff;
01149
01150 if (logger.isLoggable(BasicLevel.DEBUG)) {
01151 logger.log(BasicLevel.DEBUG, "Found a matching client with the name " + ff);
01152 }
01153 }
01154
01155 f++;
01156 }
01157
01158 if (!found) {
01159 throw new ClientContainerException("No client with the name '" + jarClient
01160 + "' was found in this Ear file");
01161 }
01162 } else {
01163
01164 fClient = new File(clientUrls[0].getFile());
01165
01166
01167 if (clientUrls.length > 1) {
01168 warn("There are " + clientUrls.length + " clients in this ear, choosing the first one : "
01169 + fClient.getName());
01170 }
01171 }
01172
01173 info("Use the application client '" + fClient + "' of the Ear '" + earUrl + "'.");
01174
01175 return fClient;
01176 }
01177
01182 private URL[] getUserClasspathUrls() {
01183 if (classpath == null) {
01184 return new URL[0];
01185 }
01186 String sep = File.pathSeparator;
01187 List clUser = new ArrayList();
01188 StringTokenizer tokenizer = new StringTokenizer(classpath, sep);
01189 while (tokenizer.hasMoreTokens()) {
01190 File file = new File(tokenizer.nextToken());
01191 try {
01192 clUser.add(file.toURL());
01193 } catch (MalformedURLException mue) {
01194 warn("Cannot transform to URL the file : '" + file + "'");
01195 }
01196 }
01197 return (URL[]) clUser.toArray(new URL[0]);
01198 }
01199
01203 private ArrayList getSystemClassPath() {
01204 String cpValue = System.getProperty("java.class.path");
01205
01206 if (logger.isLoggable(BasicLevel.DEBUG)) {
01207 logger.log(BasicLevel.DEBUG, "java.class.path = " + cpValue);
01208 }
01209
01210 String sep = File.pathSeparator;
01211 ArrayList h = new ArrayList();
01212 StringTokenizer st = new StringTokenizer(cpValue, sep);
01213
01214 while (st.hasMoreTokens()) {
01215 h.add(st.nextToken());
01216 }
01217
01218 return h;
01219 }
01220
01225 private void info(String s) {
01226 logger.log(BasicLevel.INFO, s);
01227 }
01228
01233 private void error(String s) {
01234 logger.log(BasicLevel.ERROR, s);
01235 }
01236
01241 private void warn(String s) {
01242 logger.log(BasicLevel.WARN, s);
01243 }
01244 }