Class.forName gegen Enum


  • Administrator

    Hallo zusammen,

    Arbeite gerade an einer Client/Server Architektur in Java. Es kommt nun vor, dass der Client von einer Klasse ein neues Objekt erstellen will, dies aber zuerst beim Server überprüfen lassen muss, ob es überhaupt erlaubt ist.
    Die Frage ist nun, wie übermittle ich dem Server, welche Klasse ich erstellen will. Sollte ich ein Enum machen, wo alle möglichen erstellbaren Klassen aufgelistet sind, als Zahl? Oder sollte ich über Class.forName(...) vorgehen und dem Server somit den Klassennamen übermitteln? Class.forName wäre praktisch, da man es sehr einfach erweitern könnte ohne z.B. das Enum anzupassen. Allerdings frag ich mich auch, wie schnell ist dieses Class.forName? Und ich müsste ja auch mehrere bytes mehr übermitteln und nicht nur z.B. 4 für einen Integer.

    Weiss jemand hier, wie hoch die Kosten für ein Class.forName sind? Kennt jemand noch eine weitere Lösung?

    Danke für die Hilfe!

    Grüssli



  • Handelt es sich um ein J2EE-Projekt (alias setzt du EJBs ein?)

    MfG SideWinder


  • Administrator

    EJBs? J2EE? Ich benutze SE ... also denke nicht ^^
    Wieso, was hat es damit auf sich?

    Grüssli



  • Du kannst kaum verhindern, dass Klassen die beim Client liegen instanziert werden. Er kann das JAR-File in ein anderes Projekt einbinden und ein Objekt dieser Klasse instanzieren.

    Wenn es nur innerhalb des Programms überprüft werden soll gehts natürlich einfach:

    //Client:
    Object newInstance (final String className) throws ...
    {
        // Check
        if( !isAllowed(className) )
            return null;
    
        return Class.forName(className).newInstance();
    }
    
    boolean isAllowed (final String className)
    {
        // Kommuniziere mit Server
    }
    
    //Server:
    boolean isAllowed (final String className)
    {
        for(String cn : allowedClasses)
            if(cn.equals(className))
                return true;
    
        return false;
    }
    

    Wesentlich schwieriger wird es wenn du auf jeden Fall verhindern möchtest, dass dein Client eine solche Klasse instanziert. Dann muss der Code serverseitig lagern und du musst die Klasse zum Client deployen. In einem solchen Fall wird es wohl besser sein, dass du den Code überhaupt serverseitig lagerst und dem Benutzer ein Interface anbietest weitere Klasse nauf den Server zu laden.

    MfG SideWinder


  • Administrator

    @SideWinder, dir ist schon klar, dass du überhaupt nicht auf meine Frage antwortest? ^^
    Es geht nicht darum, dass der Sever es blockieren muss, sondern dass der Client beim Server nachfragt, ob er dies darf. Und ich habe gefragt, wie man dieses Nachfragen tun kann. Und wie die Kosten für das Class.forName aussehen.

    Inzwischen löse ich es allerdings wohl über das Class. Ich setze eine Nachfrage hin. Der Client will ein Objekt erstellen, er übermittelt dem Server den genauen Klassennamen. Der Server hat das ganze Klassenpaket auch, kann somit die Klasse über Class.forName holen und dann über eine Methode, welche immer gleich lautet, einen static final Wert abfragen, also Method.invoke. Wenn er das OK gibt, sendet der Server an alle angeschlossenen Clients, den vollständigen Klassenname und alle Clients erstellen eine Instanz davon und speichern sie korrekt ab.

    Jedenfalls trotzdem danke für die versuchte Hilfe ^^

    Grüssli



  • Du könntest dir ja auch einfach einen eigenen ClassLoader schreiben.



  • Kann man mit Enums Klassen erzeugen? Wie ersetzt das Class.forName?


  • Administrator

    Enum im Client und Server, wo die definierten Werte sind. Jeder Wert repräsentiert eine Klasse. Wenn der Client eine Klasse erstellen will, sendet der Client den Wert zum Server. Der Server kann dann über eine Switch-Anweisung rausbekommen, was der Client für ein Objekttyp will. Erstellt einen für sich und sendet an alle Client auch wieder das Enum, wo die Client dann alle auch das gleiche machen, wie der Server, also switch und dann erstellen.

    Aber das war mir wie gesagt zu umständlich für die Erweiterung, wenn zusätzliche Klassen dazukommen. Deshalb habe ich nun das ganze mit Class.forName gelöst, welches ja über einen ClassLoader geht 😉

    Grüssli


Anmelden zum Antworten