A la base, je pensais pouvoir m'en sortir facilement grâce à la classe Package. Mais celle-ci ne dispose pas de méthode permettant de lister son contenu.

Du coup, on en revient à la bonne vieille méthode : celle qui consiste à aller parcourir bêtement le répertoire qui contient les fichiers class :

// ciblage du package voulu
String targetPackage = "ch.capi.mypackage";
String targetPackagePath = targetPackage.replace('.', '/');
String targetPath = "/"+targetPackagePath;
 
// récupération du chemin 'réel' du package
URL resourceURL = MaClass.class.getResource(targetPath);
String packageRealPath = resourceURL.getFile();
File packageFile = new File(packageRealPath);

Grâce à l'objet File ainsi trouvé, il ne reste plus qu'à récupérer le nom de la classe et obtenir une instance de Class :

//...
 
for (File classFile : packageFile.listFiles())
{
   String fileName = classFile.getName();
   if (fileName.endsWith(".class")) // ne traite que les fichiers '.class'
   {
      String className = fileName.substring(0, fileName.lastIndexOf(".")); // enlève le '.class'
      String fullClassName = targetPackage+"."+className;
 
      Class clazz = Class.forName(fullClassName);
      //...
   }
}

Cela permet de résoudre quelques soucis, mais pas tous : cela ne marche pas si les classes sont dans un fichier jar ! Pour contourner ce problème, il faut utiliser une autre méthode pour parcourir les fichiers :

JarFile jf = new JarFile(packageRealPath);
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements())
{
   JarEntry entry = entries.nextElement();
   String entryName = entry.getName();
 
   if (entryName.startsWith(targetPackagePath) && entryName.endsWith(".class"))
   {
      // récupération vie Class.forName(...)
   }
}

Je suis tombé sur ce problème en Java EE puisque lorsqu'une application est déployée sous GlassFish, les classes se retrouvent dans un dossier, tandis que sous Weblogic tout est dans un jar.

J'ai mis en annexe la classe complète pour ceux qui en auraient l'utilité !