diff options
-rw-r--r-- | src/main/javassist/ClassClassPath.java | 41 | ||||
-rw-r--r-- | src/main/javassist/ClassPool.java | 4 | ||||
-rw-r--r-- | src/main/javassist/ClassPoolTail.java | 5 | ||||
-rw-r--r-- | src/main/javassist/LoaderClassPath.java | 5 | ||||
-rw-r--r-- | src/main/javassist/ModuleClassPath.java | 126 |
5 files changed, 149 insertions, 32 deletions
diff --git a/src/main/javassist/ClassClassPath.java b/src/main/javassist/ClassClassPath.java index 334d61e0..86029630 100644 --- a/src/main/javassist/ClassClassPath.java +++ b/src/main/javassist/ClassClassPath.java @@ -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); } /** diff --git a/src/main/javassist/ClassPool.java b/src/main/javassist/ClassPool.java index c90c2c74..11f226f1 100644 --- a/src/main/javassist/ClassPool.java +++ b/src/main/javassist/ClassPool.java @@ -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) { diff --git a/src/main/javassist/ClassPoolTail.java b/src/main/javassist/ClassPoolTail.java index e2ace76e..7e62a861 100644 --- a/src/main/javassist/ClassPoolTail.java +++ b/src/main/javassist/ClassPoolTail.java @@ -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) diff --git a/src/main/javassist/LoaderClassPath.java b/src/main/javassist/LoaderClassPath.java index a1580537..d516323e 100644 --- a/src/main/javassist/LoaderClassPath.java +++ b/src/main/javassist/LoaderClassPath.java @@ -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; diff --git a/src/main/javassist/ModuleClassPath.java b/src/main/javassist/ModuleClassPath.java new file mode 100644 index 00000000..c41161f8 --- /dev/null +++ b/src/main/javassist/ModuleClassPath.java @@ -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() {} +} |