Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #31694 > unrolled thread
| Started by | Philipp Kraus <philipp.kraus@flashpixx.de> |
|---|---|
| First post | 2015-05-13 14:47 +0200 |
| Last post | 2015-05-17 19:09 -0400 |
| Articles | 12 — 8 participants |
Back to article view | Back to comp.lang.java.programmer
get a list of classes at runtime Philipp Kraus <philipp.kraus@flashpixx.de> - 2015-05-13 14:47 +0200
Re: get a list of classes at runtime Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-05-13 10:06 -0400
Re: get a list of classes at runtime Philipp Kraus <philipp.kraus@flashpixx.de> - 2015-05-13 16:14 +0200
Re: get a list of classes at runtime Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-05-13 11:23 -0400
Re: get a list of classes at runtime Arne Vajhøj <arne@vajhoej.dk> - 2015-05-17 19:29 -0400
Re: get a list of classes at runtime Joshua Cranmer 🐧 <Pidgeot18@verizon.invalid> - 2015-05-13 22:15 -0500
Re: get a list of classes at runtime e.d.programmer@gmail.com - 2015-05-13 08:59 -0700
Re: get a list of classes at runtime Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-05-13 16:05 -0400
Re: get a list of classes at runtime Martin Gregorie <martin@address-in-sig.invalid> - 2015-05-13 22:43 +0000
Re: get a list of classes at runtime Joerg Meier <joergmmeier@arcor.de> - 2015-05-13 16:20 +0200
Re: get a list of classes at runtime j4n bur53 <janburse@fastmail.fm> - 2015-05-13 17:47 +0200
Re: get a list of classes at runtime Arne Vajhøj <arne@vajhoej.dk> - 2015-05-17 19:09 -0400
| From | Philipp Kraus <philipp.kraus@flashpixx.de> |
|---|---|
| Date | 2015-05-13 14:47 +0200 |
| Subject | get a list of classes at runtime |
| Message-ID | <mivd25$2m28$1@ariadne.rz.tu-clausthal.de> |
[Multipart message — attachments visible in raw view] — view raw
Hello, I would like to get a list of all loadable classes, because I create an UI which should be list on the user input, which classes are existst e.g. the user types ABC and I will get the full class name with packages, e.g. package1.subpackage.ABC and package2.ABC I have taken a look into https://github.com/ronmamo/reflections but I don't find a call to filter all class names. How I can get the full class name list during runtime (all my classes are stored within a Jar file and the search should be also add the Java base classes e.g. String) Thanks a lot Phil
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-05-13 10:06 -0400 |
| Message-ID | <mivlo4$83v$1@dont-email.me> |
| In reply to | #31694 |
On 5/13/2015 8:47 AM, Philipp Kraus wrote:
> Hello,
>
>
> I would like to get a list of all loadable classes, because I create an
> UI which should be list on the user input, which classes are existst
> e.g. the user types ABC and I will get the full class name with
> packages, e.g. package1.subpackage.ABC and package2.ABC
"All loadable classes" is a potentially infinite set, since a class
loader might look almost anywhere to find a class -- it might even
synthesize a class by filling a byte[] array with bytecodes and then
loading it. But perhaps your goal is not quite so ambitious ...
> I have taken a look into https://github.com/ronmamo/reflections but I
> don't find a call to filter all class names. How I can get the full
> class name list during runtime (all my classes are stored within a Jar
> file and the search should be also add the Java base classes e.g. String)
AFAIK, the JVM has no record of potentially loadable classes that
have not been loaded (there are probably some special-case exceptions
like String and Class and Throwable, but they'll all have been loaded
well before your code runs). If I'm right, it means the only way you
can find the not-yet-loaded classes is to rummage through the JAR's (or
other sources) for yourself. You presumably know where to find your
own JAR's and things; I believe all "base classes" reside in rt.jar.
I don't know of a convenient way to find "the" rt.jar that your JVM
happens to be using; the best I can think of is to read the java.home
System property and search from there. (Or from sun.boot.class.path,
but I'm not certain that's a property all JVM's will define.)
Anyhow: Once you've found the JAR's, you'll read their directories,
do a little reformatting, and filter as you please.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Philipp Kraus <philipp.kraus@flashpixx.de> |
|---|---|
| Date | 2015-05-13 16:14 +0200 |
| Message-ID | <mivi58$2n3g$1@ariadne.rz.tu-clausthal.de> |
| In reply to | #31695 |
On 2015-05-13 14:06:53 +0000, Eric Sosman said: > On 5/13/2015 8:47 AM, Philipp Kraus wrote: > > AFAIK, the JVM has no record of potentially loadable classes that > have not been loaded (there are probably some special-case exceptions > like String and Class and Throwable, but they'll all have been loaded > well before your code runs). If I'm right, it means the only way you > can find the not-yet-loaded classes is to rummage through the JAR's (or > other sources) for yourself. You presumably know where to find your > own JAR's and things; I believe all "base classes" reside in rt.jar. > I don't know of a convenient way to find "the" rt.jar that your JVM > happens to be using; the best I can think of is to read the java.home > System property and search from there. (Or from sun.boot.class.path, > but I'm not certain that's a property all JVM's will define.) > > Anyhow: Once you've found the JAR's, you'll read their directories, > do a little reformatting, and filter as you please. I think so, but how do IDEs like IntelliJ or Eclipse this call? If I write into the code editor something a dialog is show, which lists all possibility classes. So imho I need to run over the Jar, create an index of all class files and use a pattern structure to match the names. Phil
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-05-13 11:23 -0400 |
| Message-ID | <mivq6r$ptd$1@dont-email.me> |
| In reply to | #31696 |
On 5/13/2015 10:14 AM, Philipp Kraus wrote:
> On 2015-05-13 14:06:53 +0000, Eric Sosman said:
>
>> On 5/13/2015 8:47 AM, Philipp Kraus wrote:
>>
>> AFAIK, the JVM has no record of potentially loadable classes that
>> have not been loaded (there are probably some special-case exceptions
>> like String and Class and Throwable, but they'll all have been loaded
>> well before your code runs). If I'm right, it means the only way you
>> can find the not-yet-loaded classes is to rummage through the JAR's (or
>> other sources) for yourself. You presumably know where to find your
>> own JAR's and things; I believe all "base classes" reside in rt.jar.
>> I don't know of a convenient way to find "the" rt.jar that your JVM
>> happens to be using; the best I can think of is to read the java.home
>> System property and search from there. (Or from sun.boot.class.path,
>> but I'm not certain that's a property all JVM's will define.)
>>
>> Anyhow: Once you've found the JAR's, you'll read their directories,
>> do a little reformatting, and filter as you please.
>
> I think so, but how do IDEs like IntelliJ or Eclipse this call? If I
> write into the code editor
> something a dialog is show, which lists all possibility classes.
> So imho I need to run over the Jar, create an index of all class files
> and use a pattern structure to
> match the names.
That's what I would do. Note that a JAR will have directory entries
for *all* its classes, including nested classes, private classes, and
package-private classes. You can filter out the nested classes by their
funny-looking names, but if you also want to filter based on access I
can think of only two ways:
- Read the class file (the format is described in the JVM spec).
- Load the class (use the three-argument form of Class.forName()
if you don't want to initialize it) and use getModifiers().
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-05-17 19:29 -0400 |
| Message-ID | <55592458$0$292$14726298@news.sunsite.dk> |
| In reply to | #31698 |
On 5/13/2015 11:23 AM, Eric Sosman wrote: > On 5/13/2015 10:14 AM, Philipp Kraus wrote: >> On 2015-05-13 14:06:53 +0000, Eric Sosman said: >>> On 5/13/2015 8:47 AM, Philipp Kraus wrote: >>> AFAIK, the JVM has no record of potentially loadable classes that >>> have not been loaded (there are probably some special-case exceptions >>> like String and Class and Throwable, but they'll all have been loaded >>> well before your code runs). If I'm right, it means the only way you >>> can find the not-yet-loaded classes is to rummage through the JAR's (or >>> other sources) for yourself. You presumably know where to find your >>> own JAR's and things; I believe all "base classes" reside in rt.jar. >>> I don't know of a convenient way to find "the" rt.jar that your JVM >>> happens to be using; the best I can think of is to read the java.home >>> System property and search from there. (Or from sun.boot.class.path, >>> but I'm not certain that's a property all JVM's will define.) >>> >>> Anyhow: Once you've found the JAR's, you'll read their directories, >>> do a little reformatting, and filter as you please. >> >> I think so, but how do IDEs like IntelliJ or Eclipse this call? If I >> write into the code editor >> something a dialog is show, which lists all possibility classes. >> So imho I need to run over the Jar, create an index of all class files >> and use a pattern structure to >> match the names. > > That's what I would do. Note that a JAR will have directory entries > for *all* its classes, including nested classes, private classes, and > package-private classes. You can filter out the nested classes by their > funny-looking names, but if you also want to filter based on access I > can think of only two ways: > > - Read the class file (the format is described in the JVM spec). Or reuse that somebody else has read the class file format spec. Aka using a byte code manipulation library. Like BCEL or ASM. > - Load the class (use the three-argument form of Class.forName() > if you don't want to initialize it) and use getModifiers(). Arne
[toc] | [prev] | [next] | [standalone]
| From | Joshua Cranmer 🐧 <Pidgeot18@verizon.invalid> |
|---|---|
| Date | 2015-05-13 22:15 -0500 |
| Message-ID | <mj13ug$epc$1@dont-email.me> |
| In reply to | #31696 |
On 5/13/2015 9:14 AM, Philipp Kraus wrote:
> I think so, but how do IDEs like IntelliJ or Eclipse this call? If I
> write into the code editor
> something a dialog is show, which lists all possibility classes.
> So imho I need to run over the Jar, create an index of all class files
> and use a pattern structure to
> match the names.
For Eclipse at least, the location of used jar files (including the main
rt.jar) is configured in the project settings. I recall Eclipse having
settings to let you choose which of the available JDK/JREs to use. I
imagine this is found in part by searching for well-known install
locations, and letting a developer switch between multiple installed
JDKs is useful for a Java IDE.
It is possible in a running Java program to find the directory of the
current JRE (System.getProperty("java.home")), as well as the class path
in use (System.getProperty("java.class.path")).
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
[toc] | [prev] | [next] | [standalone]
| From | e.d.programmer@gmail.com |
|---|---|
| Date | 2015-05-13 08:59 -0700 |
| Message-ID | <4b9ec70b-28f1-488f-9945-ec6ebf8ebda8@googlegroups.com> |
| In reply to | #31695 |
On Wednesday, May 13, 2015 at 10:07:19 AM UTC-4, Eric Sosman wrote: > On 5/13/2015 8:47 AM, Philipp Kraus wrote: > > Hello, > > > > > > I would like to get a list of all loadable classes, because I create an > > UI which should be list on the user input, which classes are existst > > e.g. the user types ABC and I will get the full class name with > > packages, e.g. package1.subpackage.ABC and package2.ABC > > "All loadable classes" is a potentially infinite set, since a class > loader might look almost anywhere to find a class -- it might even > synthesize a class by filling a byte[] array with bytecodes and then > loading it. But perhaps your goal is not quite so ambitious ... > > > I have taken a look into https://github.com/ronmamo/reflections but I > > don't find a call to filter all class names. How I can get the full > > class name list during runtime (all my classes are stored within a Jar > > file and the search should be also add the Java base classes e.g. String) > > AFAIK, the JVM has no record of potentially loadable classes that > have not been loaded (there are probably some special-case exceptions > like String and Class and Throwable, but they'll all have been loaded > well before your code runs). If I'm right, it means the only way you > can find the not-yet-loaded classes is to rummage through the JAR's (or > other sources) for yourself. You presumably know where to find your > own JAR's and things; I believe all "base classes" reside in rt.jar. > I don't know of a convenient way to find "the" rt.jar that your JVM > happens to be using; the best I can think of is to read the java.home > System property and search from there. (Or from sun.boot.class.path, > but I'm not certain that's a property all JVM's will define.) > > Anyhow: Once you've found the JAR's, you'll read their directories, > do a little reformatting, and filter as you please. > > -- > esosman@comcast-dot-net.invalid > "Don't be afraid of work. Make work afraid of you." -- TLM To find the rt.jar your IDE would just have to specify where the rt.jar is. Normally to build a project in Eclipse you add "JRE System Library" to the build path. You'll see that as a folder in the Package Explorer. You can expand that folder. I don't know if Oracle/Sun publishes a list of which jars to include or where they get it but my Eclipse project using Java 8 update 40 has 18 jars listed there.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-05-13 16:05 -0400 |
| Message-ID | <mj0ao4$t8u$1@dont-email.me> |
| In reply to | #31700 |
On 5/13/2015 11:59 AM, e.d.programmer@gmail.com wrote:
>[...]
> To find the rt.jar your IDE would just have to specify where the rt.jar is.
> Normally to build a project in Eclipse you add "JRE System Library" to the build path. You'll see that as a folder in the Package Explorer. You can expand that folder. I don't know if Oracle/Sun publishes a list of which jars to include or where they get it but my Eclipse project using Java 8 update 40 has 18 jars listed there.
I could be wrong, but I don't think that's the O.P.'s problem.
He wrote "I create an UI" that finds and lists classes (sounds like
a sort of auto-completion thing), in somewhat the manner of an IDE.
So I think the issue isn't "How do I tell my IDE where rt.jar is?"
but "How does a piece of executing code find the rt.jar its JVM is
using?"
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2015-05-13 22:43 +0000 |
| Message-ID | <mj0k1n$4rb$1@dont-email.me> |
| In reply to | #31702 |
On Wed, 13 May 2015 16:05:17 -0400, Eric Sosman wrote: > On 5/13/2015 11:59 AM, e.d.programmer@gmail.com wrote: >>[...] >> To find the rt.jar your IDE would just have to specify where the rt.jar >> is. >> Normally to build a project in Eclipse you add "JRE System Library" to >> the build path. You'll see that as a folder in the Package Explorer. >> You can expand that folder. I don't know if Oracle/Sun publishes a >> list of which jars to include or where they get it but my Eclipse >> project using Java 8 update 40 has 18 jars listed there. > > I could be wrong, but I don't think that's the O.P.'s problem. > He wrote "I create an UI" that finds and lists classes (sounds like a > sort of auto-completion thing), in somewhat the manner of an IDE. > So I think the issue isn't "How do I tell my IDE where rt.jar is?" but > "How does a piece of executing code find the rt.jar its JVM is using?" Since, IIRC, Eclipse is FOSS, I suppose the OP could always download its source and see how the class list is handled there. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [next] | [standalone]
| From | Joerg Meier <joergmmeier@arcor.de> |
|---|---|
| Date | 2015-05-13 16:20 +0200 |
| Message-ID | <1qnrqm0fz132l$.1tzazpkevh5wo.dlg@40tude.net> |
| In reply to | #31694 |
On Wed, 13 May 2015 14:47:40 +0200, Philipp Kraus wrote: > I would like to get a list of all loadable classes, because I create an > UI which should be list on the user input, which classes are existst > e.g. the user types ABC and I will get the full class name with > packages, e.g. package1.subpackage.ABC and package2.ABC What you want is not quite possible. Since class loaders load on demand (and some even from remote sources over the internet or out of a database), there is no list of "possible loadable classes". You could write a loop that attempts to load "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" and so on, but that is unlikely to produce an outcome you will be happy with. Your question is akin to saying "I would like a list of all available URLs". It just doesn't work like that. There are of course many ways to get all loaded classes, but that again is probably not what you want. Your best bet is something that scans all the jars on the classpath, which will not give you an exhaustive list, but a reasonable approximation. This library may be helpful: <https://code.google.com/p/reflections/> Spring also has something helpful: <http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.html> Good luck. Liebe Gruesse, Joerg -- Ich lese meine Emails nicht, replies to Email bleiben also leider ungelesen.
[toc] | [prev] | [next] | [standalone]
| From | j4n bur53 <janburse@fastmail.fm> |
|---|---|
| Date | 2015-05-13 17:47 +0200 |
| Message-ID | <mivrmb$o2d$1@news.albasani.net> |
| In reply to | #31694 |
Hi, You can skim the class paths for entries of the form *.class. A class path is either a directory or an archive. If its a directory, you have to recursively traverse the directory. If its an archive you basically have to read a zip file and skim its entries. The most annoying thing is getting the class paths in the first place. Bye Philipp Kraus schrieb: > Hello, > > > I would like to get a list of all loadable classes, because I create an > UI which should be list on the user input, which classes are existst > e.g. the user types ABC and I will get the full class name with > packages, e.g. package1.subpackage.ABC and package2.ABC > > > I have taken a look into https://github.com/ronmamo/reflections but I > don't find a call to filter all class names. How I can get the full > class name list during runtime (all my classes are stored within a Jar > file and the search should be also add the Java base classes e.g. String) > > > Thanks a lot > > > Phil >
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-05-17 19:09 -0400 |
| Message-ID | <55591fc4$0$292$14726298@news.sunsite.dk> |
| In reply to | #31694 |
On 5/13/2015 8:47 AM, Philipp Kraus wrote:
> I would like to get a list of all loadable classes, because I create an
> UI which should be list on the user input, which classes are existst
> e.g. the user types ABC and I will get the full class name with
> packages, e.g. package1.subpackage.ABC and package2.ABC
>
> I have taken a look into https://github.com/ronmamo/reflections but I
> don't find a call to filter all class names. How I can get the full
> class name list during runtime (all my classes are stored within a Jar
> file and the search should be also add the Java base classes e.g. String)
The general problem is difficult as described in several replies.
But assuming:
- only classes that can be loaded by class loader hierarchy for context
- only class loaders that are based on URLClassLoader
- only local directories and jar files
then it becomes a much simpler problem.
See below for inspiration.
Arne
====
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ClassFinder {
private static final String CLASS_EXT = ".class";
private static final String FILE_PROTOCOL = "file:/";
private static String fileNameToClassName(String filename, String base) {
if(filename.startsWith(base)) {
return filename.substring(base.length() + 1, filename.length() -
CLASS_EXT.length()).replace(File.separatorChar, '.');
} else {
throw new IllegalArgumentException("Filename not in base: " + filename);
}
}
private static void processDirectory(File f, List<String> res, String
base) {
for(File cf : f.listFiles()) {
if(cf.isDirectory()) {
processDirectory(cf, res, base);
} else {
String cfnam = cf.getAbsolutePath();
if(cfnam.endsWith(CLASS_EXT)) {
String clznam = fileNameToClassName(cfnam, base);
res.add(clznam);
}
}
}
}
private static void processJarFile(File f, List<String> res) throws
IOException {
try(JarFile jf = new JarFile(f.getAbsolutePath())) {
Enumeration<JarEntry> jes = jf.entries();
while(jes.hasMoreElements()) {
JarEntry je = jes.nextElement();
String jenam = je.getName();
if(jenam.endsWith(CLASS_EXT)) {
String clznam = jenam.substring(0, jenam.length() -
CLASS_EXT.length()).replace('/', '.');
res.add(clznam);
}
}
}
}
private static void processURL(URL url, List<String> res) throws
IOException {
if(url.getProtocol().equals("file")) {
String path = URLDecoder.decode(url.toString(),
"UTF-8").substring(FILE_PROTOCOL.length());
File f = new File(path);
if(f.isDirectory()) {
processDirectory(f, res, f.getAbsolutePath());
} else {
processJarFile(f, res);
}
} else {
throw new IllegalArgumentException("Unsupported protocol for URL: " +
url.toString());
}
}
private static void processClassLoader(ClassLoader cl, List<String>
res) throws IOException {
if(cl instanceof URLClassLoader) {
URLClassLoader urlcl = (URLClassLoader)cl;
for(URL url : urlcl.getURLs()) {
processURL(url, res);
}
} else {
throw new IllegalArgumentException("Unsupported ClassLoader: " +
cl.getClass().getName());
}
}
public static List<String> search() throws IOException {
List<String> res = new ArrayList<String>();
ClassLoader cl = ClassFinder.class.getClassLoader();
while(cl != null) {
processClassLoader(cl, res);
cl = cl.getParent();
}
return res;
}
public static void main(String[] args) throws Exception {
List<String> clzs = ClassFinder.search();
for(String clz : clzs) {
System.out.println(clz);
}
}
}
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web