Restored dependencies (removed "provided"), added lib-directory parameter, added...
authorMichael Jumper <zhangmaike@users.sourceforge.net>
Fri, 26 Aug 2011 20:20:26 +0000 (13:20 -0700)
committerMichael Jumper <zhangmaike@users.sourceforge.net>
Fri, 26 Aug 2011 20:20:26 +0000 (13:20 -0700)
pom.xml
src/main/java/net/sourceforge/guacamole/net/basic/GuacamoleClassLoader.java [new file with mode: 0644]
src/main/java/net/sourceforge/guacamole/net/basic/properties/AuthenticationProviderProperty.java
src/main/java/net/sourceforge/guacamole/net/basic/properties/BasicGuacamoleProperties.java

diff --git a/pom.xml b/pom.xml
index 86f9ac2..34be37d 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -69,7 +69,6 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.6.1</version>
-            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
@@ -83,7 +82,6 @@
             <groupId>net.sourceforge.guacamole</groupId>
             <artifactId>guacamole-common</artifactId>
             <version>0.4.0</version>
-            <scope>provided</scope>
         </dependency>
 
         <!-- Guacamole Authentication API -->
@@ -91,7 +89,6 @@
             <groupId>net.sourceforge.guacamole</groupId>
             <artifactId>guacamole-common-auth</artifactId>
             <version>0.5.0</version>
-            <scope>provided</scope>
         </dependency>
 
         <!-- Guacamole JavaScript API -->
diff --git a/src/main/java/net/sourceforge/guacamole/net/basic/GuacamoleClassLoader.java b/src/main/java/net/sourceforge/guacamole/net/basic/GuacamoleClassLoader.java
new file mode 100644 (file)
index 0000000..b1a398a
--- /dev/null
@@ -0,0 +1,125 @@
+
+package net.sourceforge.guacamole.net.basic;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import net.sourceforge.guacamole.GuacamoleException;
+import net.sourceforge.guacamole.net.basic.properties.BasicGuacamoleProperties;
+import net.sourceforge.guacamole.properties.GuacamoleProperties;
+
+/*
+ *  Guacamole - Clientless Remote Desktop
+ *  Copyright (C) 2010  Michael Jumper
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class GuacamoleClassLoader extends ClassLoader {
+    
+    private URLClassLoader classLoader = null;
+
+    private static GuacamoleException exception = null;
+    private static GuacamoleClassLoader instance = null;
+    
+    static {
+        
+        try {
+            // Attempt to create singleton classloader which loads classes from
+            // all .jar's in the lib directory defined in guacamole.properties
+            instance = new GuacamoleClassLoader(
+                GuacamoleProperties.getProperty(BasicGuacamoleProperties.LIB_DIRECTORY)
+            );
+        }
+        
+        catch (GuacamoleException e) {
+            // On error, record exception
+            exception = e;
+        }
+        
+    }
+
+    private GuacamoleClassLoader(File libDirectory) throws GuacamoleException {
+
+        // If no directory provided, just direct requests to parent classloader
+        if (libDirectory == null)
+            return;
+        
+        // Validate directory is indeed a directory
+        if (!libDirectory.isDirectory())
+            throw new GuacamoleException(libDirectory + " is not a directory.");
+        
+        // Get list of URLs for all .jar's in the lib directory
+        Collection<URL> jarURLs = new ArrayList<URL>();
+        for (File file : libDirectory.listFiles(new FilenameFilter() {
+
+            @Override
+            public boolean accept(File dir, String name) {
+                
+                // If it ends with .jar, accept the file
+                return name.endsWith(".jar");
+                
+            }
+
+        })) {
+
+            try {
+                
+                // Add URL for the .jar to the jar URL list
+                jarURLs.add(file.toURI().toURL());
+                
+            }
+            catch (MalformedURLException e) {
+                throw new GuacamoleException(e);
+            }
+                
+        }
+        
+        // Set delegate classloader to new URLClassLoader which loads from the
+        // .jars found above.
+
+        URL[] urls = new URL[jarURLs.size()];
+        classLoader = new URLClassLoader(
+            jarURLs.toArray(urls),
+            getClass().getClassLoader()
+        );
+        
+    }
+
+    public static GuacamoleClassLoader getInstance() throws GuacamoleException {
+        
+        // If instance could not be created, rethrow original exception
+        if (exception != null) throw exception;
+        
+        return instance;
+
+    }
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+
+        // If no classloader, use super
+        if (classLoader == null)
+            return super.findClass(name);
+        
+        // Otherwise, delegate
+        return classLoader.loadClass(name);
+
+    }
+
+}
index 2b0ce0d..90e982e 100644 (file)
@@ -21,6 +21,7 @@ package net.sourceforge.guacamole.net.basic.properties;
 import java.lang.reflect.InvocationTargetException;
 import net.sourceforge.guacamole.GuacamoleException;
 import net.sourceforge.guacamole.net.auth.AuthenticationProvider;
+import net.sourceforge.guacamole.net.basic.GuacamoleClassLoader;
 import net.sourceforge.guacamole.properties.GuacamoleProperty;
 
 public abstract class AuthenticationProviderProperty implements GuacamoleProperty<AuthenticationProvider> {
@@ -31,7 +32,9 @@ public abstract class AuthenticationProviderProperty implements GuacamolePropert
         // Get auth provider instance
         try {
 
-            Object obj = Class.forName(authProviderClassName).getConstructor().newInstance();
+            Object obj = GuacamoleClassLoader.getInstance().loadClass(authProviderClassName)
+                            .getConstructor().newInstance();
+
             if (!(obj instanceof AuthenticationProvider))
                 throw new GuacamoleException("Specified authentication provider class is not a AuthenticationProvider.");
 
index ecaacba..cb9430e 100644 (file)
@@ -39,4 +39,11 @@ public class BasicGuacamoleProperties {
 
     };
 
+    public static final FileGuacamoleProperty LIB_DIRECTORY = new FileGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "lib-directory"; }
+
+    };
+
 }