Finding all Classes of a Package

  • Thread starter Wolfgang Heintz
  • Start date
W

Wolfgang Heintz

Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?
 
M

Michael Borgwardt

Wolfgang said:
Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?

Sure, look through all the folders and JAR files. No, there's no API
method, because the classloader mechanism is not restricted to folders
and JAR files; in fact, it would be easy to write a classloader that
generates an infinite number of classes.
 
S

Sajjad Lateef

Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?

Which OS?
Are you looking for a command to type in?
Are you looking for a API to the JAR file?
Are you looking for an API to the file system?

Sorry, your question is not clear. Can you give an example?
 
B

Brad BARCLAY

Wolfgang said:
Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?

The answer to your question is no -- there isn't.

The Package class _will_ allow you to get a listing of all classes in a
package that have been loaded, mind you -- but a Classloader will have
had to have loaded them before this will be of much use (which means
your application will already need to know about them).

You could try reading the users CLASSPATH and parsing it to find all of
the directories and JAR file, and search them yourself -- but this is
tedious, and won't work with either network accessible classes or with
classes stored in a DBMS.

Brad BARCLAY
 
N

Neal Gafter

Wolfgang said:
Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?

Yes, using the javadoc tool and writing a small custom doclet.
 
C

Chris Uppal

Wolfgang said:
Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?

(I'm not criticising you here, Wolfgang, this is just a general question)

This question comes up rather often on this group; what puzzles me is why. Why
do so many people *want* to find out what classes are in a package (presumably
as part of some program) ?

I've been trying to imagine applications for the information, but can't think
of anything that seems like it would explain why so many programmers want to
get it.

-- chris
 
W

Wolfgang Heintz

Is it possible to find all Classes defined in a Package placed in
differend Sourcefolders or JAR-Files?

Yes, it is possible. You only have to combine different techniques to
solve the problem.

Here is a short Test-Application which finds all Classes placed in a
Package. It runs in eclipse-IDE and under normal OS-Shell as JAR-File.

Thanks to all who replied my Question.


TestApplication:

package de.ghs-software.whe.test;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/**
* Testklasse zum Auffinden aller Class-Files eines Packages.
*
* @author Wolfgang Heintz
*/
public class Test
{
/**
* Ermittelt anhand des ClassPath ob die Anwendung in einer IDE
ausgeführt
* wird.
* @param aClassPath Über Systemproperties ermittelter ClassPath
* @return true wenn die Anwendung in einer IDE gestartet wurde
*/
protected static boolean isAppRunningInIde(String aClassPath)
{
boolean result = false;

StringTokenizer tokenizer =
new StringTokenizer(aClassPath, File.pathSeparator);

while (tokenizer.hasMoreTokens())
{
String classPathEntry = (String) tokenizer.nextToken();

if (!classPathEntry.endsWith(".jar"))
{
result = true;
break;
}
}

return result;
}

/**
* Ermittelt anhand des ClassPath ob die Anwendung in einer
JAR-Datei
* ausgeführt wird. In diesem Fall enthält der ClassPath nur einen
Eintrag
* (= JAR-Datei der ausgeführten Klasse).
* @param aClassPath Über Systemproperties ermittelter ClassPath
* @return true wenn die Anwendung in einer JAR-Datei gestartet
wurde
*/
protected static boolean isAppRunningInJar(String aClassPath)
{
boolean result = false;

StringTokenizer tokenizer =
new StringTokenizer(aClassPath, File.pathSeparator);

if (tokenizer.countTokens() == 1 && aClassPath.endsWith(".jar"))
{
result = true;
}

return result;
}

/**
* Ermittelt alle Klassen des angegebenen Packages aus den Binary-
* Verzeichnissen des übergebenen ClassPath. Auch evtl. enthaltene
JAR-Dateien
* werden ausgewertet.
* @param aClassPath Über Systemproperties ermittelter ClassPath
* @param aPackage Package dessen Klassen gesucht werden
* @return Liste alle Klassen des angegebenen Packages innerhalb des
ClassPath
* @throws IOException wenn eine JAR-Datei nicht geöffnet werden
kann
*/
protected static List getAllClassesAppRunningIde(String aClassPath,
String aPackage) throws IOException
{
List ideClasses = new LinkedList();
String packagename = aPackage.replace('/', '.').replace('\\',
'.');
StringTokenizer tokenizer =
new StringTokenizer(aClassPath, File.pathSeparator);

while (tokenizer.hasMoreTokens())
{
String nextClassPathDir = tokenizer.nextToken();

if (nextClassPathDir.endsWith(".jar"))
{
ideClasses.addAll(
getAllClassesInJarFile(new JarFile(nextClassPathDir),
packagename));
}
else
{
String directoryName = nextClassPathDir
+ File.separator
+ packagename.replace('.', File.separatorChar);

File directory = new File(directoryName);
String[] classnames = directory.list();

if (classnames != null)
{
for (int i = 0; i < classnames.length; i++)
{
if (!classnames.endsWith(".class"))
{
continue;
}

String classname = packagename
+ "."
+ classnames.ubstring(
0, classnames.indexOf('.'));

ideClasses.add(classname);
}
}
}
}

return ideClasses;
}

/**
* Ermittelt alle Klassen des angegebenen Packages aus der JAR-Datei
in der
* die aktuelle Klasse steht und allen JAR-Dateien die im ClassPath
der
* Manifest-Datei stehen.
* @param aClassPath Über Systemproperties ermittelter ClassPath
* @param aPackage Package dessen Klassen gesucht werden
* @return Liste alle Klassen des angegebenen Packages innerhalb des
ClassPath
* @throws IOException wenn eine JAR-Datei nicht geöffnet werden
kann
*/
protected static List getAllClassesAppRunningJar(String aClassPath,
String aPackage) throws IOException
{
List jarClasses = new LinkedList();
String packagename = aPackage.replace('/', '.').replace('\\',
'.');
JarFile jarFile = new JarFile(aClassPath);
Manifest manifest = jarFile.getManifest();

jarClasses.addAll(getAllClassesInJarFile(jarFile, packagename));

if (manifest != null)
{
String jarClassPath =
manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
StringTokenizer tokenizer = new StringTokenizer(jarClassPath, " ");

while (tokenizer.hasMoreTokens())
{
String jarFileName = (String) tokenizer.nextToken();

jarClasses.addAll(
getAllClassesInJarFile(new JarFile(jarFileName), packagename));
}
}

return jarClasses;
}

/**
* Ermittelt alle Klassen einer JAR-Datei, die dem übergebenen
Package
* angehören.
* @param aJarFile auszuwertende JAR-Datei.
* @param aPackage Package der gesuchten Klassen.
* @return Liste aller Klassen des übergebenen Packages
*/
private static List getAllClassesInJarFile(JarFile aJarFile, String
aPackage)
{
LinkedList jarClasses = new LinkedList();
Enumeration jarEntries = aJarFile.entries();

while (jarEntries.hasMoreElements())
{
String classname = ((JarEntry) jarEntries.nextElement()).getName();
int idxClass = classname.indexOf(".class");

if (idxClass == -1)
{
continue;
}

classname =
classname.substring(0, idxClass).replace('/', '.').replace('\\',
'.');

if (!extractPackageName(classname).equalsIgnoreCase(aPackage))
{
continue;
}

jarClasses.add(classname);
}

return jarClasses;
}

/**
* Extrahiert aus einem vollständigen Klassennamen mit Packageangabe
den
* reinen Packagenamen. Als Trennzeichen zwischen den einzelnen
Elementen
* des Klassennamens sind '/', '\\' und '.' zulässig.
* @param aClassname vollständiger Klassenname mit Packageangabe
* @return Packagenamen getrennt durch '.'
*/
private static String extractPackageName(String aClassname)
{
String packagename = "";
String classname = aClassname.replace('/', '.').replace('\\',
'.');
int posClassname = classname.lastIndexOf('.');

if (posClassname != -1)
{
packagename = classname.substring(0, posClassname);
}

return packagename;
}

/**
* Main-Methode der Klasse Test.
* @param args Startparameter
*/
public static void main(String[] args)
{
String packagename = Test.class.getPackage().getName();
String classPath = System.getProperty("java.class.path");
List classes = null;

try
{
if (isAppRunningInIde(classPath))
{
classes = getAllClassesAppRunningIde(classPath, packagename);
}
else
{
classes = getAllClassesAppRunningJar(classPath, packagename);
}

if (classes != null)
{
Iterator itrClasses = classes.iterator();

while (itrClasses.hasNext())
{
System.out.println(itrClasses.next().toString());
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
 
W

Wolfgang Heintz

Chris Uppal said:
(I'm not criticising you here, Wolfgang, this is just a general question)

This question comes up rather often on this group; what puzzles me is why. Why
do so many people *want* to find out what classes are in a package (presumably
as part of some program) ?

I've been trying to imagine applications for the information, but can't think
of anything that seems like it would explain why so many programmers want to
get it.

-- chris

The plan is to implemtent JUnit-Tests for Design-Patterns.
JUnit-TestCase and JUnit-TestSuite are (normally) placed in the same
Package as the Classes to be tested. To avoid changing the
Test-Classes on each new implementation I want to search for all
Classes implemtenting a specific Interface.

Wolfgang
 

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,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top