How to get list of classes from a package
Ulf Zibis
Ulf.Zibis at gmx.de
Mon Feb 16 22:35:37 UTC 2009
Martin,
thanks for your additional hints.
I'm aware, that my solution is not suitable for general cases, but it
solves my needs perfectly. For my enhancement of charsets I need to
compare my new coders against the legacy coders from rt.jar +
charsets.jar from JDK 6 for testing equality.
-Ulf
Am 16.02.2009 23:08, Martin Buchholz schrieb:
> Ulf,
>
> This kind of solution is likely to be brittle.
> For example, you appear to assume that the code
> you are looking for is in a jar file. But it might not be;
> in jdk "developer mode", they are likely to be in
> a "classes" directory.
>
> Martin
>
> On Mon, Feb 16, 2009 at 13:30, Ulf Zibis <Ulf.Zibis at gmx.de> wrote:
>
>> 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