How to get list of classes from a package
Ulf Zibis
Ulf.Zibis at gmx.de
Mon Feb 16 21:30:31 UTC 2009
Am 16.02.2009 21:35, Rémi Forax schrieb:
> Tom Hawtin a écrit :
>> David M. Lloyd wrote:
>>> On 02/16/2009 10:22 AM, Ulf Zibis wrote:
>>>>
>>>> can anybody tell me, how I could get al list or enumeration of the
>>>> classes, which belong to a package.
>>>> I can't see any appropriate method in java.lang.Package :-(
>>>
>>> This isn't really possible at run time, since one doesn't know
>>> whether a class exists until one tries to load it. The classloader
>>> might not even know. Also, a package can span classloaders, adding
>>> more complexity to the problem.
>>
>> IIRC, you will get a different Package for each class loader, for a
>> given package name. Certainly classes with the same package name will
>> not have Java access to default/protected
>> members/classes/interface/constructors from different class loaders.
>>
>> But yes, a list of classes is not necessarily complete. Also, IIRC,
>> Proxy dynamically inserts classes into packages as well.
>>
>> Tom Hawtin
> Ulf, if you can create an agent, you can get all loaded classes:
> http://download.java.net/jdk7/docs/api/java/lang/instrument/Instrumentation.html#getAllLoadedClasses()
>
>
> But if you want thoses classes to find some that implement an interface,
> java.util.ServiceLoader is your friend:
> http://download.java.net/jdk7/docs/api/java/util/ServiceLoader.html
>
> cheers,
> Rémi
>
Hi David, Tom and Rémi,
very much thanks for your hints. They were really valuable. :-)
I just finished to code a tricky solution:
package sun.nio.cs;
import java.io.*;
import java.net.*;
import java.nio.charset.*;
import java.util.*;
import java.util.jar.*;
/**
*
* @author Ulf Zibis <Ulf.Zibis at CoSoCo.de>
*/
public class LegacyCharsets {
private static StandardCharsets standChars = new StandardCharsets();
// Maps lowered canonical names to legacy class names
static final Map<String,String> legacyClassNameMap;
static {
legacyClassNameMap = new HashMap(256);
collectLegacyClassNames("StandardCharsets.class");
collectLegacyClassNames("ext/DelegatableDecoder.class");
}
@SuppressWarnings("static-access")
private static void collectLegacyClassNames(String searchAnchor) {
String[] paths =
LegacyCharsets.class.getResource(searchAnchor).getPath().split("!");
paths[1] = paths[1].substring(paths[1].indexOf('/')+1,
paths[1].lastIndexOf('/'));
try {
Enumeration<JarEntry> en = new JarFile(new File(new
URI(paths[0]))).entries();
while (en.hasMoreElements()) {
String name = en.nextElement().getName();
int extPos;
if (name.indexOf('$') < 0 && name.startsWith(paths[1])
&& (extPos = name.indexOf(".class")) > 0) {
Class c = Class.forName(name.substring(0,
extPos).replace('/', '.'),
true,
LegacyCharsets.class.getClassLoader());
if (Charset.class.isAssignableFrom(c)) try {
legacyClassNameMap.put(standChars.toLower(((Charset)c.newInstance()).name()),
c.getName().substring("sun.nio.cs.".length()));
} catch (IllegalAccessException iae) {
} catch (InstantiationException ie) {}
}
}
} catch (Exception ex) {
System.err.println(ex);
}
}
@SuppressWarnings("static-access")
static Charset legacyCharset(String canonicalName) {
return
standChars.newCharsetForClassName(legacyClassNameMap.get(standChars.toLower(canonicalName)));
}
}
More information about the core-libs-dev
mailing list