@@ -40,15 +40,20 @@ import javassist.bytecode.ClassFile; | |||
* <code>ClassClassPath</code> uses a class object representing | |||
* the class including the code snippet above. | |||
* | |||
* <p>Class files in a named module are private to that module. | |||
* This method cannot obtain class files in named modules. | |||
* </p> | |||
* | |||
* @see ClassPool#insertClassPath(ClassPath) | |||
* @see ClassPool#appendClassPath(ClassPath) | |||
* @see LoaderClassPath | |||
* @see ModuleClassPath | |||
*/ | |||
public class ClassClassPath implements ClassPath { | |||
private static final boolean useJigsaw | |||
= ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9; | |||
private static final boolean useJigsaw | |||
= ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9; | |||
private Class thisClass; | |||
private Class thisClass; | |||
/** Creates a search path. | |||
* | |||
@@ -76,16 +81,8 @@ public class ClassClassPath implements ClassPath { | |||
* Obtains a class file by <code>getResourceAsStream()</code>. | |||
*/ | |||
public InputStream openClassfile(String classname) throws NotFoundException { | |||
String jarname = classname.replace('.', '/') + ".class"; | |||
if (useJigsaw) | |||
try { | |||
return thisClass.getModule().getResourceAsStream(jarname); | |||
} | |||
catch (java.io.IOException e) { | |||
throw new NotFoundException(classname, e); | |||
} | |||
else | |||
return thisClass.getResourceAsStream('/' + jarname); | |||
String filename = '/' + classname.replace('.', '/') + ".class"; | |||
return thisClass.getResourceAsStream('/' + filename); | |||
} | |||
/** | |||
@@ -94,22 +91,8 @@ public class ClassClassPath implements ClassPath { | |||
* @return null if the class file could not be found. | |||
*/ | |||
public URL find(String classname) { | |||
String jarname = classname.replace('.', '/') + ".class"; | |||
if (useJigsaw) | |||
try { | |||
InputStream is = thisClass.getModule().getResourceAsStream(jarname); | |||
if (is == null) | |||
return null; | |||
else { | |||
is.close(); | |||
return new URL("jar:file:unknown.jar!/" + jarname); | |||
} | |||
} | |||
catch (java.io.IOException e) { | |||
return null; | |||
} | |||
else | |||
return thisClass.getResource('/' + jarname); | |||
String filename = '/' + classname.replace('.', '/') + ".class"; | |||
return thisClass.getResource(filename); | |||
} | |||
/** |
@@ -220,10 +220,12 @@ public class ClassPool { | |||
* </pre> | |||
* | |||
* <p>If the default class pool cannot find any class files, | |||
* try <code>ClassClassPath</code> and <code>LoaderClassPath</code>. | |||
* try <code>ClassClassPath</code>, <code>ModuleClassPath</code>, | |||
* or <code>LoaderClassPath</code>. | |||
* | |||
* @see ClassClassPath | |||
* @see LoaderClassPath | |||
* @see ModuleClassPath | |||
*/ | |||
public static synchronized ClassPool getDefault() { | |||
if (defaultPool == null) { |
@@ -234,8 +234,9 @@ final class ClassPoolTail { | |||
} | |||
public ClassPath appendSystemPath() { | |||
appendClassPath(new ClassClassPath()); | |||
return appendClassPath(new ClassClassPath(CtClass.class)); | |||
ClassLoader cl = Thread.currentThread().getContextClassLoader(); | |||
appendClassPath(new LoaderClassPath(cl)); | |||
return appendClassPath(new ModuleClassPath()); | |||
} | |||
public ClassPath insertClassPath(String pathname) |
@@ -31,6 +31,10 @@ import java.lang.ref.WeakReference; | |||
* | |||
* <p>The given class loader must have both <code>getResourceAsStream()</code> | |||
* and <code>getResource()</code>. | |||
* | |||
* <p>Class files in a named module are private to that module. | |||
* This method cannot obtain class files in named modules. | |||
* </p> | |||
* | |||
* @author <a href="mailto:bill@jboss.org">Bill Burke</a> | |||
* @author Shigeru Chiba | |||
@@ -38,6 +42,7 @@ import java.lang.ref.WeakReference; | |||
* @see ClassPool#insertClassPath(ClassPath) | |||
* @see ClassPool#appendClassPath(ClassPath) | |||
* @see ClassClassPath | |||
* @see ModuleClassPath | |||
*/ | |||
public class LoaderClassPath implements ClassPath { | |||
private WeakReference clref; |
@@ -0,0 +1,126 @@ | |||
/* | |||
* Javassist, a Java-bytecode translator toolkit. | |||
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. | |||
* | |||
* The contents of this file are subject to the Mozilla Public License Version | |||
* 1.1 (the "License"); you may not use this file except in compliance with | |||
* the License. Alternatively, the contents of this file may be used under | |||
* the terms of the GNU Lesser General Public License Version 2.1 or later, | |||
* or the Apache License Version 2.0. | |||
* | |||
* Software distributed under the License is distributed on an "AS IS" basis, | |||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||
* for the specific language governing rights and limitations under the | |||
* License. | |||
*/ | |||
package javassist; | |||
import java.io.InputStream; | |||
import java.lang.reflect.Layer; | |||
import java.lang.reflect.Module; | |||
import java.net.URL; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.Set; | |||
/** | |||
* A search-path for obtaining a class file | |||
* by <code>getResourceAsStream()</code> in <code>java.lang.reflect.Module</code>. | |||
* | |||
* @see ClassPool#insertClassPath(ClassPath) | |||
* @see ClassPool#appendClassPath(ClassPath) | |||
* @see LoaderClassPath | |||
* @see ClassClassPath | |||
*/ | |||
public class ModuleClassPath implements ClassPath { | |||
private HashMap packages = new HashMap(); | |||
ModuleClassPath() { this(Layer.boot()); } | |||
/** | |||
* Constructs a search path. | |||
* | |||
* @param layer the layer used to obtain a class file. | |||
*/ | |||
public ModuleClassPath(Layer layer) { | |||
while (layer != null) { | |||
Set modules = layer.modules(); | |||
Iterator it = modules.iterator(); | |||
while (it.hasNext()) | |||
addPackages((Module)it.next()); | |||
layer = layer.parent().orElse(null); | |||
} | |||
} | |||
/** | |||
* Constructs a search path. | |||
* | |||
* @param m the module used to obtain a class file. | |||
*/ | |||
public ModuleClassPath(Module m) { | |||
addPackages(m); | |||
} | |||
private void addPackages(Module m) { | |||
String[] names = m.getPackages(); | |||
for (int i = 0; i < names.length; i++) | |||
packages.put(names[i], m); | |||
} | |||
/** | |||
* Obtains a class file by <code>getResourceAsStream()</code>. | |||
*/ | |||
public InputStream openClassfile(String classname) throws NotFoundException { | |||
String filename = classname.replace('.', '/') + ".class"; | |||
Module m = (Module)packages.get(getPackageName(classname)); | |||
if (m == null) | |||
return null; | |||
else | |||
try { | |||
return m.getResourceAsStream(filename); | |||
} | |||
catch (java.io.IOException e) { | |||
throw new NotFoundException(classname, e); | |||
} | |||
} | |||
/** | |||
* Obtains the URL of the specified class file. | |||
* | |||
* @return null if the class file could not be found. | |||
*/ | |||
public URL find(String classname) { | |||
String filename = classname.replace('.', '/') + ".class"; | |||
Module m = (Module)packages.get(getPackageName(classname)); | |||
if (m == null) | |||
return null; | |||
else | |||
try { | |||
InputStream is = m.getResourceAsStream(filename); | |||
if (is == null) | |||
return null; | |||
else { | |||
is.close(); | |||
return new URL("jar:file:unknown.jar!/" + filename); | |||
} | |||
} | |||
catch (java.io.IOException e) { | |||
return null; | |||
} | |||
} | |||
private static String getPackageName(String name) { | |||
int i = name.lastIndexOf('.'); | |||
if (i > 0) | |||
return name.substring(0, i); | |||
else | |||
return ""; | |||
} | |||
/** | |||
* Does nothing. | |||
*/ | |||
public void close() {} | |||
} |