Get classes from package

T

Tomasso

Hello ive been doing some research on this topic, i read everywhere
people saying it is not actually posible. I believe it should be
posible, people who develop development tools may want to require this
behaviour. I would like to know those people who asked, how did they
solve that problem, and what alternatives did they chose. Ive been
thinking for a while and decided would be nice to have a thing like

Classes[] getClases(String regexPattern);

so it returns all clases whose names match the given pattern.. it
should be posible since classes have fully qualified names, so when i
wanna get all classes from a package, lets suppose java.lang ;) i write

Package.getClasses("java.lang*");

I dont know what to think and what to do. This problem should be
computable, dont understend why is not posible, and there should be any
alternative. I need this behaviour. If any of you found a way to mimic
it, please help me ;)

Thanks!
 
C

Chris Smith

Tomasso said:
Hello ive been doing some research on this topic, i read everywhere
people saying it is not actually posible. I believe it should be
posible, people who develop development tools may want to require this
behaviour.

You can believe that it should be possible all you want. That doesn't
make it possible. Once again, getting any kind of list of classes in a
package is impossible in the general case. The list of classes in a
package may not even be finite, much less accessible! More likely, it
is finite but may be inaccessible because of security restrictions on
web servers and the like.

If you know something about the classloader, then it may become
possible. It's still ugly and not really what you want to do, in
addition to being fragile because you are making assumptions about the
classloader.
I would like to know those people who asked, how did they
solve that problem, and what alternatives did they chose.

The general solution is to specify some specific resource name
(generally in the META-INF logical directory), and ask service providers
to write a simple properties file with that resource name to describe
what they are offering. You would then use ClassLoader.getResources
(note the plural) to get a list of all resources visible to a
ClassLoader with that name. By parsing all of them, you get back a list
of the RELEVANT classes which have been identified in that resource.

This is both possible (which is generally a nice property for something
to have) and cleaner than searching through all classes and trying to
load them and test if they are relevant to what you're trying to do.
Ive been
thinking for a while and decided would be nice to have a thing like

Classes[] getClases(String regexPattern);

so it returns all clases whose names match the given pattern.. it
should be posible since classes have fully qualified names, so when i
wanna get all classes from a package, lets suppose java.lang ;) i write

Package.getClasses("java.lang*");

1. A package is not just a package name. It is actually the unique
combination of a package name and a classloader. Therefore, your
interface would really need to be getClasses(ClassLoader, String).

2. It's still impossible in the general case. The list you want may
still be infinitely long (well, okay, in real-life implementations
that's 2^2^16 long, which is a 1 followed by 19,728 zeros; you would
need 8 KB just to store the arbitrary precision INDEX into the resulting
sequence) or it may only be known by a remote web server which isn't
willing to tell you. This has nothing to do with computability. It has
to do with whether the answer exists, and whether you have the necessary
information to determine that answer.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
O

Oliver Wong

Tomasso said:
Hello ive been doing some research on this topic, i read everywhere
people saying it is not actually posible. I believe it should be
posible, people who develop development tools may want to require this
behaviour. I would like to know those people who asked, how did they
solve that problem, and what alternatives did they chose. Ive been
thinking for a while and decided would be nice to have a thing like

Classes[] getClases(String regexPattern);

so it returns all clases whose names match the given pattern.. it
should be posible since classes have fully qualified names, so when i
wanna get all classes from a package, lets suppose java.lang ;) i write

Package.getClasses("java.lang*");

I dont know what to think and what to do. This problem should be
computable, dont understend why is not posible, and there should be any
alternative. I need this behaviour. If any of you found a way to mimic
it, please help me ;)

Here's an example showing why it's impossible.

Let's say you want to get all classes in the "foo" package. Well, I
wrote a class in the "Foo" package, and then immediately took my computer
and threw it into a blackhole. Now how are you going to gain access to that
class?

Usually when someone says "I want all classes in a package.", they
really mean "I want all classes in a given set of directories which happen
to be in a given package."

- Oliver
 
O

Oliver Wong

Oliver Wong said:
Let's say you want to get all classes in the "foo" package. Well, I
wrote a class in the "Foo" package, and then immediately took my computer
and threw it into a blackhole.

Obviously, I meant I had written a class in the "foo" package, not the
"Foo" package. Darn case sensitivity.

- Oliver
 
F

Furious George

Oliver said:
Obviously, I meant I had written a class in the "foo" package, not the
"Foo" package. Darn case sensitivity.

The black hole issue is not a problem. The getClasses method can
simply generate all possible classes in the Foo package. It is trivial
to see that the list of all possible Foo package classes is finite and
would include your black hole class.

The OP probably meant every Foo package class that is accessible to the
class loader. I don't see why the OP could not write his own class
loader with a getClasses method, if he wants it.
 
C

Chris Uppal

Furious said:
It is trivial
to see that the list of all possible Foo package classes is finite and
would include your black hole class.

You're right. The classfile format imposes a hard limit of 2**16 on the length
of a fully qualified class name. In practise some names are be subject to a
tighter limit since 2**16 is actually the limit on the name when expressed as
bytes using Sun's peculiar not-really-UTF-8 character encoding.

So there's definitely a limit to how many different classes can be in the same
package. For instance if our package name is 12 chars long, and we restrict
ourselves to the 64 legal ASCII classname characters, then the limit is about
1.35e118348. If that is too small, then we can enlarge it considerably by
allowing the full range of Unicode characters in the class names; I can't
bothered to work out exactly how many names we end up with, but it's on the
order of 1e650000.

(Obviously the list of all possible /classes/ is a bit longer, but they can't
all be members of the same package/classloader combination at the same time.)

Since these are moderately large numbers, the OP's desired:
Package.getClasses("java.lang.*");
method would have to return an Iterator<Class<?>> rather than an actual array
or List of class objects, but that's only a minor technical hurdle.

;-)

-- chris
 
O

Oliver Wong

Chris Uppal said:
You're right. The classfile format imposes a hard limit of 2**16 on the
length
of a fully qualified class name. In practise some names are be subject to
a
tighter limit since 2**16 is actually the limit on the name when expressed
as
bytes using Sun's peculiar not-really-UTF-8 character encoding.

Hmm... I had considered that two classes are "the same" not merely if
they had the same name, but if they had the same bytecode.

That is, I had made a class "foo.Bar" and threw it into a black hole,
and someone else wrote a "foo.Bar" class and kept it around, I would not say
that these are the same classes, unless they had the same implementation.

So let's say further that I didn't actually write my foo.Bar class, but
rather, I wrote a program to generate the foo.Bar class for me. The program
uses a random number generator to generate a random (but legal!) sequence of
bytecodes, saves that to the disk, and throw the whole computer into the
black hole. Obviously, there was a USB dongle that somehow generates "true"
random numbers (perhaps via measuring of radioactive decay of some
substance), and just for the heck of it, that was thrown into the black hole
as well. So even if you tortured me, or injected me with truth serum, I
could not tell you the sequence of bytecodes that made up my foo.Bar class.
So there's definitely a limit to how many different classes can be in the
same
package. For instance if our package name is 12 chars long, and we
restrict
ourselves to the 64 legal ASCII classname characters, then the limit is
about
1.35e118348. If that is too small, then we can enlarge it considerably
by
allowing the full range of Unicode characters in the class names; I can't
bothered to work out exactly how many names we end up with, but it's on
the
order of 1e650000.

I know there's a limit on the length of the methods, and on the number
of methods itself, so that would imply there's a limit to the list of all
possible classes (not merely all possible class names). But if we accept
that maybe the question was loosely phrased, we might allow say that if
foo.Bar contains a nested inner class foo.Bar.Buntz, then that is "part of"
the foo.Bar class as well. If we do allow this, then unless there's a limit
to the levels of nesting and the number of allowed nested classes, then we
have an infinte number of possibilities.
(Obviously the list of all possible /classes/ is a bit longer, but they
can't
all be members of the same package/classloader combination at the same
time.)

Right, this makes it *difficult* to get all possible classes within a
package, but not nescessarily impossible: You'd just have to use more than 1
classloader per package.
Since these are moderately large numbers, the OP's desired:
Package.getClasses("java.lang.*");
method would have to return an Iterator<Class<?>> rather than an actual
array
or List of class objects, but that's only a minor technical hurdle.

In this sense, actually, you could conceptually be returning an
"infinite" number of classes. The iterator just never returns "false" for
hasNext(). So maybe this whole project is possible after all. The next()
method of the iterator would just need to return every possible bytecode
sequence that yields a valid class file, probably in lexigraphical order of
the bytecode sequence. The only tricky part is coordinating this so that if
classes have the same name, they claim to have been loaded by different
class loaders.

- Oliver
 
F

Furious George

Oliver said:
Hmm... I had considered that two classes are "the same" not merely if
they had the same name, but if they had the same bytecode.

That is, I had made a class "foo.Bar" and threw it into a black hole,
and someone else wrote a "foo.Bar" class and kept it around, I would not say
that these are the same classes, unless they had the same implementation.

So let's say further that I didn't actually write my foo.Bar class, but
rather, I wrote a program to generate the foo.Bar class for me. The program
uses a random number generator to generate a random (but legal!) sequence of
bytecodes, saves that to the disk, and throw the whole computer into the
black hole. Obviously, there was a USB dongle that somehow generates "true"
random numbers (perhaps via measuring of radioactive decay of some
substance), and just for the heck of it, that was thrown into the black hole
as well. So even if you tortured me, or injected me with truth serum, I
could not tell you the sequence of bytecodes that made up my foo.Bar class.


I know there's a limit on the length of the methods, and on the number
of methods itself, so that would imply there's a limit to the list of all
possible classes (not merely all possible class names). But if we accept
that maybe the question was loosely phrased, we might allow say that if
foo.Bar contains a nested inner class foo.Bar.Buntz, then that is "part of"
the foo.Bar class as well. If we do allow this, then unless there's a limit
to the levels of nesting and the number of allowed nested classes, then we
have an infinte number of possibilities.

The classfile format imposes a hard limit of 2**16 on the length of the
fully qualified class file name. Unless I am mistaken, that does
impose a limit on both the levels of nesting and the number of allowed
nested classes. Thus there exists only a finite number of
possibilities. But as you later point out, it does not really matter
if the list is finite or infinite.
Right, this makes it *difficult* to get all possible classes within a
package, but not nescessarily impossible: You'd just have to use more than 1
classloader per package.


In this sense, actually, you could conceptually be returning an
"infinite" number of classes. The iterator just never returns "false" for
hasNext(). So maybe this whole project is possible after all. The next()
method of the iterator would just need to return every possible bytecode
sequence that yields a valid class file, probably in lexigraphical order of
the bytecode sequence. The only tricky part is coordinating this so that if
classes have the same name, they claim to have been loaded by different
class loaders.

This is easy. Every class gets its own classloader.
 
O

Oliver Wong

Furious George said:
This is easy. Every class gets its own classloader.

Pure genius! So I guess everyone who told the OP that this was
impossible (which includes myself) were in fact wrong.

- Oliver
 
F

Furious George

Oliver said:
Pure genius! So I guess everyone who told the OP that this was
impossible (which includes myself) were in fact wrong.


Actually pure idiocy, but you are right everyone who told the OP this
was impossible was wrong.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top