1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* $RCSfile$
* $Revision: 2993 $
* $Date: 2005-10-24 18:11:33 -0300 (Mon, 24 Oct 2005) $
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.openfire.container;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.Log;
import java.io.File;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* ClassLoader for plugins. It searches the plugin directory for classes
* and JAR files, then constructs a class loader for the resources found.
* Resources are loaded as follows:<ul>
* <p/>
* <li>Any JAR files in the <tt>lib</tt> will be added to the classpath.
* <li>Any files in the classes directory will be added to the classpath.
* </ul>
*
* @author Derek DeMoro
*/
public class PluginClassLoader extends URLClassLoader {
public PluginClassLoader() {
super(new URL[] {}, findParentClassLoader());
}
/**
* Adds a directory to the class loader.
*
* @param directory the directory.
* @param developmentMode true if the plugin is running in development mode. This
* resolves classloader conflicts between the deployed plugin
* and development classes.
*/
public void addDirectory(File directory, boolean developmentMode) {
try {
// Add classes directory to classpath.
File classesDir = new File(directory, "classes");
if (classesDir.exists()) {
addURL(classesDir.toURL());
}
// Add i18n directory to classpath.
File databaseDir = new File(directory, "database");
if(databaseDir.exists()){
addURL(databaseDir.toURL());
}
// Add i18n directory to classpath.
File i18nDir = new File(directory, "i18n");
if(i18nDir.exists()){
addURL(i18nDir.toURL());
}
// Add web directory to classpath.
File webDir = new File(directory, "web");
if(webDir.exists()){
addURL(webDir.toURL());
}
// Add lib directory to classpath.
File libDir = new File(directory, "lib");
File[] jars = libDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar") || name.endsWith(".zip");
}
});
if (jars != null) {
for (int i = 0; i < jars.length; i++) {
if (jars[i] != null && jars[i].isFile()) {
if (developmentMode) {
// Do not add plugin-pluginName.jar to classpath.
if (!jars[i].getName().equals("plugin-" + directory.getName() + ".jar")) {
addURL(jars[i].toURL());
}
}
else {
addURL(jars[i].toURL());
}
}
}
}
}
catch (MalformedURLException mue) {
Log.error(mue);
}
}
public void addURLFile(URL file) {
addURL(file);
}
/**
* Locates the best parent class loader based on context.
*
* @return the best parent classloader to use.
*/
private static ClassLoader findParentClassLoader() {
ClassLoader parent = XMPPServer.class.getClassLoader();
if (parent == null) {
parent = PluginClassLoader.class.getClassLoader();
}
if (parent == null) {
parent = ClassLoader.getSystemClassLoader();
}
return parent;
}
}