ProjectClassLoaderpublic final class ProjectClassLoader extends ClassLoader ClassLoader able to load class from output of an Eclipse project. |
Fields Summary |
---|
private final org.eclipse.jdt.core.IJavaProject | mJavaProject | private URLClassLoader | mJarClassLoader | private boolean | mInsideJarClassLoader |
Methods Summary |
---|
protected java.lang.Class | findClass(java.lang.String name)
try {
// get the project output folder.
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IPath outputLocation = mJavaProject.getOutputLocation();
IResource outRes = root.findMember(outputLocation);
if (outRes == null) {
throw new ClassNotFoundException(name);
}
File outFolder = new File(outRes.getLocation().toOSString());
// get the class name segments
String[] segments = name.split("\\."); //$NON-NLS-1$
File classFile = getFile(outFolder, segments, 0);
if (classFile == null) {
if (mInsideJarClassLoader == false) {
// if no file matching the class name was found, look in the 3rd party jars
return loadClassFromJar(name);
} else {
throw new ClassNotFoundException(name);
}
}
// load the content of the file and create the class.
FileInputStream fis = new FileInputStream(classFile);
byte[] data = new byte[(int)classFile.length()];
int read = 0;
try {
read = fis.read(data);
} catch (IOException e) {
data = null;
}
fis.close();
if (data != null) {
Class<?> clazz = defineClass(null, data, 0, read);
if (clazz != null) {
return clazz;
}
}
} catch (Exception e) {
throw new ClassNotFoundException(e.getMessage());
}
throw new ClassNotFoundException(name);
| private final java.net.URL[] | getExternalJars()Returns an array of external jar files used by the project.
// get a java project from it
IJavaProject javaProject = JavaCore.create(mJavaProject.getProject());
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
ArrayList<URL> oslibraryList = new ArrayList<URL>();
IClasspathEntry[] classpaths = javaProject.readRawClasspath();
if (classpaths != null) {
for (IClasspathEntry e : classpaths) {
if (e.getEntryKind() == IClasspathEntry.CPE_LIBRARY ||
e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
// if this is a classpath variable reference, we resolve it.
if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
e = JavaCore.getResolvedClasspathEntry(e);
}
// get the IPath
IPath path = e.getPath();
// check the name ends with .jar
if (AndroidConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
boolean local = false;
IResource resource = wsRoot.findMember(path);
if (resource != null && resource.exists() &&
resource.getType() == IResource.FILE) {
local = true;
try {
oslibraryList.add(
new File(resource.getLocation().toOSString()).toURL());
} catch (MalformedURLException mue) {
// pass
}
}
if (local == false) {
// if the jar path doesn't match a workspace resource,
// then we get an OSString and check if this links to a valid file.
String osFullPath = path.toOSString();
File f = new File(osFullPath);
if (f.exists()) {
try {
oslibraryList.add(f.toURL());
} catch (MalformedURLException mue) {
// pass
}
}
}
}
}
}
}
return oslibraryList.toArray(new URL[oslibraryList.size()]);
| private java.io.File | getFile(java.io.File parent, java.lang.String[] segments, int index)Returns the File matching the a certain path from a root {@link File}.
The methods checks that the file ends in .class even though the last segment
does not.
// reached the end with no match?
if (index == segments.length) {
throw new FileNotFoundException();
}
String toMatch = segments[index];
File[] files = parent.listFiles();
// we're at the last segments. we look for a matching <file>.class
if (index == segments.length - 1) {
toMatch = toMatch + ".class";
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().equals(toMatch)) {
return file;
}
}
}
// no match? abort.
throw new FileNotFoundException();
}
String innerClassName = null;
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
if (toMatch.equals(file.getName())) {
return getFile(file, segments, index+1);
}
} else if (file.getName().startsWith(toMatch)) {
if (innerClassName == null) {
StringBuilder sb = new StringBuilder(segments[index]);
for (int i = index + 1 ; i < segments.length ; i++) {
sb.append('$");
sb.append(segments[i]);
}
sb.append(".class");
innerClassName = sb.toString();
}
if (file.getName().equals(innerClassName)) {
return file;
}
}
}
}
return null;
| private java.lang.Class | loadClassFromJar(java.lang.String name)Loads a class from the 3rd party jar present in the project
if (mJarClassLoader == null) {
// get the OS path to all the external jars
URL[] jars = getExternalJars();
mJarClassLoader = new URLClassLoader(jars, this /* parent */);
}
try {
// because a class loader always look in its parent loader first, we need to know
// that we are querying the jar classloader. This will let us know to not query
// it again for classes we don't find, or this would create an infinite loop.
mInsideJarClassLoader = true;
return mJarClassLoader.loadClass(name);
} finally {
mInsideJarClassLoader = false;
}
|
|