Ultrakompakter HTTP Server
ulrich
2024-12-01 c103a86ecd93d30dccab63479ad527ec7cbf0ead
src/de/uhilger/neon/Factory.java
@@ -109,6 +109,7 @@
  /**
   * Einen Neon-Server gemaess einem Serverbeschreibungsobjekt herstellen und starten
   *
   * @param starter  die Klasse, mit der Neon durch Aufruf dieser Methode gestartet wird
   * @param d das Object mit der Serverbeschreibung
   * @param packageNames Namen der Packages, aus der rekursiv vorgefundene Actors eingebaut werden
   * sollen
@@ -121,9 +122,12 @@
   * @throws InvocationTargetException
   * @throws IOException
   */
  public void runInstance(Class c, NeonDescriptor d, List<String> packageNames, List<DataProvider> sdp)
  public void runInstance(Class starter, NeonDescriptor d, List<String> packageNames, List<DataProvider> sdp)
          throws ClassNotFoundException, NoSuchMethodException, InstantiationException, 
          IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
    Logger.getLogger(Factory.class.getName()).log(Level.FINER, System.getProperty("java.class.path"));
    List serverList = d.server;
    Iterator<ServerDescriptor> serverIterator = serverList.iterator();
    while (serverIterator.hasNext()) {
@@ -134,7 +138,7 @@
      if(packageNames == null) {
        packageNames = d.actorPackages;
      }
      addContexts(c, d, server, sd.contexts, packageNames, sdp);
      addContexts(starter, d, server, sd.contexts, packageNames, sdp);
      server.setExecutor(Executors.newFixedThreadPool(10));
      server.start();
@@ -291,11 +295,73 @@
        ClassLoader cl = js.getUrlClassLoader(c);
        js.processZipContent(cl, new File(path), packageName, this, h, contextName);
      }
      //listClasses(c, packageName);
    } catch (URISyntaxException ex) {
      Logger.getLogger(Factory.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
    }
  }
  
  /**
   * Diese Testmethode zeigt, dass die Methode getResourceAsStream nicht funktioniert wie
   * dokumentiert.
   *
   * 1. Sie liefert den Inhalt einer gegebenen Package mitsamt Unterpackages als
   * Stream, wenn sie auf eine Packagestruktur angewendet wird, die unverpackt in einem
   * Verzeichnis des Dateisystems liegt.
   *
   * 2. Sie liefert - faelschlicherweise - null bzw. einen leeren Stream, wenn die Packagestruktur
   * in einem Jar verpackt ist.
   *
   * Saemtliche Versuche, ueber den ClassPath oder die Pfadangabe der Package das Verhalten zu
   * aendern, gehen bislang fehl (z.B. / oder . als Separator,
   * / oder . zu Beginn enthalten oder nicht, realative oder absolute packagepfadangabe).
   * Es ist auch unerheblich, ob
   * Class.getResourceAsStream oder Class.getClassLoader().getResourceAsStream verwendet wird.
   *
   * Unabhaengig davon, ob und wie letztlich im Fall 2. oben die Methode getResourceAsStream
   * dazu zu bringen waere, eine Inhaltsliste fuer eine Package zu liefern ist allein die
   * Tatsache, dass sich die Methode unterschiedlich verhaelt bereits ein
   * schwerer Bug.
   *
   * @param c
   * @param packageName
   */
  private void listClasses(Class c, String packageName) {
        Logger.getLogger(Factory.class.getName()).log(Level.FINER, "packageName: " + packageName);
        //ClassLoader cl = c.getClassLoader();
        String newPackageName = packageName.replaceAll("[.]", "/");
        Logger.getLogger(Factory.class.getName()).log(Level.FINER, "newPackageName: " + newPackageName);
        InputStream stream = c
                .getResourceAsStream(newPackageName);
        if(stream != null) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
        Iterator i = reader.lines().iterator();
        Logger.getLogger(Factory.class.getName()).log(Level.FINER, Long.toString(reader.lines().count()));
        while (i.hasNext()) {
          String line = i.next().toString();
          Logger.getLogger(Factory.class.getName()).log(Level.FINER, "class to inspect: " + line);
          if (line.endsWith(".class")) {
            try {
              Class actorClass = c.getClassLoader().loadClass(packageName + "."
                      + line.substring(0, line.lastIndexOf('.')));
              if (actorClass != null && actorClass.isAnnotationPresent(Actor.class)) {
                Logger.getLogger(Factory.class.getName()).log(Level.FINER, "ACTOR");
              } else {
                Logger.getLogger(Factory.class.getName()).log(Level.FINER, "no actor");
              }
            } catch (ClassNotFoundException ex) {
              Logger.getLogger(Factory.class.getName()).log(Level.FINER, "Klasse nicht gefunden");
            }
          } else {
            listClasses(c, packageName + "." + line);
          }
        }
        } else {
         Logger.getLogger(Factory.class.getName()).log(Level.FINER, "stream ist null");
        }
  }
  /*
    Eine Action-Annotation enthaelt gewoehnlich die Route, 
    die 'unterhalb' des Kontextpfades als 'Ausloeser' zur