View Javadoc

1   /*
2    * $Id: MuleBootstrapUtils.java 9403 2007-10-26 18:45:53Z aguenther $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.modules.boot;
12  
13  import java.io.File;
14  import java.lang.reflect.InvocationTargetException;
15  import java.lang.reflect.Method;
16  import java.net.URL;
17  import java.net.URLClassLoader;
18  import java.util.Iterator;
19  import java.util.List;
20  
21  public final class MuleBootstrapUtils
22  {
23      private static final String MULE_LIB_FILENAME = "lib" + File.separator + "mule";
24      private static final String MULE_HOME = System.getProperty("mule.home");
25      
26      public static final String MULE_LOCAL_JAR_FILENAME = "mule-local-install.jar";
27  
28      private MuleBootstrapUtils()
29      {
30          // utility class only
31      }
32      
33      public static File getMuleHomeFile()
34      {
35          return new File(MULE_HOME);
36      }
37      
38      public static File getMuleLibDir()
39      {   
40          return new File(MULE_HOME + File.separator + MULE_LIB_FILENAME);
41      }
42      
43      public static File getMuleLocalJarFile()
44      {
45          return new File(getMuleLibDir(), MULE_LOCAL_JAR_FILENAME);
46      }
47      
48      public static void addLocalJarFilesToClasspath(File muleHome, File muleBase) throws Exception
49      {
50          DefaultMuleClassPathConfig classPath = new DefaultMuleClassPathConfig(muleHome, muleBase);
51          addLibrariesToClasspath(classPath.getURLs());
52      }    
53      
54      public static void addExternalJarFilesToClasspath(File muleHome, ProxyInfo proxyInfo) throws Exception
55      {
56          LibraryDownloader downloader = null;
57          if (proxyInfo != null)
58          {
59              downloader = new LibraryDownloader(muleHome, proxyInfo.host, proxyInfo.port, proxyInfo.username, proxyInfo.password);
60          }
61          else 
62          {
63              downloader = new LibraryDownloader(muleHome);
64          }
65          addLibrariesToClasspath(downloader.downloadLibraries());
66      }
67      
68      public static void addLibrariesToClasspath(List urls) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
69      {
70          ClassLoader sys = ClassLoader.getSystemClassLoader();
71          if (!(sys instanceof URLClassLoader))
72          {
73              throw new IllegalArgumentException(
74                  "PANIC: Mule has been started with an unsupported classloader: " + sys.getClass().getName()
75                                  + ". " + "Please report this error to user<at>mule<dot>codehaus<dot>org");
76          }
77      
78          // system classloader is in this case the one that launched the application,
79          // which is usually something like a JDK-vendor proprietary AppClassLoader
80          URLClassLoader sysCl = (URLClassLoader) sys;
81      
82          /*
83           * IMPORTANT NOTE: The more 'natural' way would be to create a custom
84           * URLClassLoader and configure it, but then there's a chicken-and-egg
85           * problem, as all classes MuleBootstrap depends on would have been loaded by
86           * a parent classloader, and not ours. There's no straightforward way to
87           * change this, and is documented in a Sun's classloader guide. The solution
88           * would've involved overriding the ClassLoader.findClass() method and
89           * modifying the semantics to be child-first, but that way we are calling for
90           * trouble. Hacking the primordial classloader is a bit brutal, but works
91           * perfectly in case of running from the command-line as a standalone app.
92           * All Mule embedding options then delegate the classpath config to the
93           * embedder (a developer embedding Mule in the app), thus classloaders are
94           * not modified in those scenarios.
95           */
96      
97          // get a Method ref from the normal class, but invoke on a proprietary parent
98          // object,
99          // as this method is usually protected in those classloaders
100         Class refClass = URLClassLoader.class;
101         Method methodAddUrl = refClass.getDeclaredMethod("addURL", new Class[]{URL.class});
102         methodAddUrl.setAccessible(true);
103         for (Iterator it = urls.iterator(); it.hasNext();)
104         {
105             URL url = (URL) it.next();
106             methodAddUrl.invoke(sysCl, new Object[]{url});
107         }
108     }
109     
110     public static class ProxyInfo
111     {
112         String host;
113         String port;
114         String username;
115         String password;
116         
117         public ProxyInfo(String host, String port)
118         {
119             this(host, port, null, null);
120         }
121         
122         public ProxyInfo(String host, String port, String username, String password)
123         {
124             this.host = host;
125             this.port = port;
126             this.username = username;
127             this.password = password;
128         }
129     }
130 }