Klasse dynamisch nachladen: Fehler

  • Themenstarter Themenstarter Gast123
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Gast123

Gast
Hallo,



ich habe 1 Programm, nennen wir es Klasse "A".
Dieses Programm lädt Klasse B.class nach über
den Aufruf
Code:
clazz = class.forname("B");

Nun klappere ich über
Code:
getMethods()
alle Methoden der Klasse B ab,
um die richtige zu finden, nämlich:
Code:
runme()
Habe ich sie gefunden, will ich sie aufrufen mit:

Code:
Method MyMethod;  
MyMethod=findrunme(clazz); //suche
MyMethod.invoke(null); //runme ausfuehren

Doch hier passiert nun der Fehler:

Class A can not access a member of class B with modifiers "public static".

Class B's sourcecode sieht so aus:

Code:
import A.*; 
class B {  

public static void runme() {  
System.out.println("A="+5);
}
 
}

Was muss ich im Sourcecode der Klasse B ändern, damit ich die Funktion runme()
ohne weiteres aus A aufrufen kann? Es hat wohl was mit dem "public static void" zu tun.

Vielen Dank!

Jawas
 
Ich denke mal du bist in deiner Klasse A in einem nicht statischen "Bereich" und willst von da eine statische Methode ausführen... sweit ich weiss geht das nicht! probiert mal einfach mit public void!
 
Hat leider nicht geklappt, da erhält man dann:

java.lang.IllegalAccessException: Class A can not access a member of class B with modifiers "public" :-(

Was aber geht (was ich nicht will) ist:

Code:
class B {  
 static { 
   System.out.println("A="+5);
        } 
        }

und man ruft dann halt keine Funktion runme auf sondern macht nur ein
Code:
class.forname("B", true, myClassLoader);

Aber ich hätte halt gerne ein "Methoden-Handle" zur Funktion "runme", um diese Funktion
dann schnell wiederholt aufrufen zu können (halt wie eine ganz normale Funktion), denn jedesmal
ein class.forname ist irgendwie sehr langsam, weil immer wieder der ClassLoader anspringt, was
(vieel zu) viel Zeit kostet.
 
> denn jedesmal ein class.forname ist irgendwie sehr langsam

vielleicht wird auch gar nicht mehrfach initialisiert?

----------


du willst also eine statische Operation aufrufen,
5 kleine Worte, die man in deinen Postings lange suchen muss..


allgemein funktioniert das, warum bei dir nicht, das ist bisher noch nicht erkennbar,
poste vollständigen Code..
Code:
public class Test
{
    public static void main(String[] args)
        throws Exception
    {
        Class clazz = Class.forName("B");
        Method m = clazz.getDeclaredMethod("runme", new Class[0]);
        m.invoke(null, null);
    }
}


class B
{
    public static void runme()
    {
        System.out.println("A=" + 5);
    }
}
 
@SlaterB

Gegeben ist die Datei: B.class, welche nur Deine gepostete compilierte Klasse "class B" enthält.
Dann mache ich folgendes in Klasse A:

Code:
private void jButton13ActionPerformed(java.awt.event.ActionEvent evt) {                                          
try{        
 URLClassLoader classLoader = new URLClassLoader(new URL[] { new File( "c:/" ).toURI().toURL() } );
    
 Class clazz =  Class.forName( "B", true, classLoader );    

 Method m = clazz.getDeclaredMethod("runme", new Class[0]); 
 m.invoke(null, null); //Java-Compile-Warnung bei 2x null

 }catch(Exception e) {System.out.println("EXCEPT: "+e.toString());}
}

Das endet dann in:

EXCEPT: java.lang.IllegalAccessException: Class A can not access a member of class B with modifiers "public static"
 
an einer solchen Stelle bei Reflection immer folgenden goldenen Tipp beachten:
probiere erst den nicht-reflektierenden Weg aus,
also
B.runme();

das wird bei dir genausowenig laufen, stimmts?

um deine Fehlermeldung nachzustellen habe ich nämlich die AufruferKlasse in ein package gelegt,
B aber im Default-package gelassen,
eine Klasse in einem package darf auf Klassen im Default-package nicht zugreifen,

die Fehlermeldung ist da etwas irreführend 😉
 
Danke für die Antwort, wie schaffe ich es jedoch nun, die Sache zum laufen zu bringen?

Idee: ich schreibe als absoluter Java-Anfänger einfach vor:
"class B;" noch ein "package B;", denn dann ist es ja nicht mehr im Default-Packege? Doch dann schlägt das copmilieren fehl...
 
die Datei muss dann natürlich in ein Unterverzeichnis B,
am besten b, Package-Namen klein
 
Also es ist mir völlig schleierhaft, doch plötzlich funktioniert alles so wie es soll, sogar ohne "package a;".
Zuerst kam eine reflection-Exception und dann geht plötzlich alles, ohne Änderung. Warum? Das frage ich mich ehrlich gesagt
auch. Einerseits toll, andererseits mag ich solche "huch, plötzlich gehts"-Erlebnisse nicht.
Vielen Dank für die Hilfe und das war mir neu: für den Trick hier:

Method m = clazz.getDeclaredMethod("runme", new Class[0]);
 
also die Regel 'aus anderem package kannst du nicht aufs Default-package zugreifen'
wird sicherlich nicht von heut auf morgen in deinem Programm außer Kraft gesetzt,

ist deine Aufrufer-Klasse vielleicht selber ins Default-package gewandert?
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben