Refleksja - problem z dostępem do metody

0

Dobry wieczór:)

Zmagań z kodem ciąg dalszy.

Piszę właśnie program który ma umożliwić użytkownikowi wpisanie w polu tekstowym własnego fragment kodu, który program ma potem skompilować i uruchomić.

Zastosowałem do tego mechanizm refleksji, własny classloader i klasę javacompiler. Mechanizm refleksji również uruchamia jedną z klas zaimplementowanych w programie w przypadku braku wprowadzenia kodu użytkownika - taka funkcjonalność domyślna. Program uruchamia mi się z pliku *.jar. Jeżeli użytkownik nie wprowadzi własnego kodu, to mechanizm refleksji uruchamia odpowiednią klasę z pliku *.jar i na niej poprawnie wszystko działa. Gdy jednak wprowadzi swój kod, zaimplementowany kompilator tworzy plik *.class na podstawie kodu źródłowego użytkownika i umieszcza go w miejscu uruchomienia programu, poza plikiem *.jar. Za pomocą classloadera i mechanizmu refleksji ładuję tak powstałą klasę do programu i od tej pory mogę spokojnie pracować na wszystkich metodach, które korzystają wyłącznie z typów prostych i klas predefiniowanych przez standard javy, gdy jednak chcę uruchomić metodę wykorzystującą jako argument wywołania obiekt będący instancją napisanej przeze mnie klasy otrzymuję NullPointerException (To samo gdy metoda zwraca obiekt mojej klasy, bądź korzysta z niej w trakcie wykonania)

Wcześniej miałem ten problem przy kompilacji kodu, jednak umieszczenie go w tym samym package co wykorzystywane klasy (dopisałem po prostu w źródle "package odpowiednia_paczka", co spowodowało przeniesienie wynikowego pliku *.class poziom niżej do katalogu o nazwie tej paczki, w którym nie było nic poza nim) rozwiązało problem i pozwoliło skompilować się danemu plikowi, mimo, że nie znajdował się fizycznie w tym samym miejscu co plik *.jar.

próba pobrania metody - działa.

_rateMoveMethod=_rateMoveClass.getMethod("rateMove",AIBoard.class);

wadliwa linia - próba jej wykonania rzuca wyjątkami - tak przekazywany obiekt jest zainicjalizowany. Ta linia działa gdy uruchamiam klasę wewnętrzną (która w tym momencie de facto wygląda identycznie z tą ładowaną za pomocą refleksji, rózni je tylko lokalizacja i nazwa klasy)

_rateMoveMethod.invoke(null,myAIBoard);

wyjątki:

sty 19, 2013 2:29:57 AM checkers.GUI actionPerformed
SEVERE: null
java.lang.NullPointerException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at checkers.PlayerAI.<init>(PlayerAI.java:100)
0

Czy ty sobie robisz jaja?
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object, java.lang.Object...)
Pierwszym argumentem invoke ma być OBIEKT na którym chcesz wywołać metodę. A ty tam dajesz nulla. To co się niby ma dziać?

0

Otóż to ma działać - daję nulla, ze względu na to, że uruchamiam metodę statyczną. Nie, nie robię sobie jaj.

1

Nadal robisz sobie jaja, bo metody statyczne też są wywoływane na obiektach. A ze są to obiekty klasy Class to jest inna sprawa.

0
Shalom napisał(a):

Nadal robisz sobie jaja, bo metody statyczne też są wywoływane na obiektach. A ze są to obiekty klasy Class to jest inna sprawa.

  1. Do wywołania metody statycznej, nie potrzebujesz obiektu - może nie istnieć żaden, a i tak jesteś w stanie ją wywołać.
  2. Sprawdzałem tą konstrukcję na tej samej klasie, gdy była w źródłach aplikacji - w pliku jar - i działało bez zarzutu.
  3. Link który mi podesłałeś zawiera szczegółowy opis metody invoke, w którym znajdujemy taki napis: "If the underlying method is static, then the specified obj argument is ignored. It may be null. " Co po mojemu znaczy, że jeżeli metoda jest statyczna to może być null.
  4. Nie, nie robię sobie jaj.
1

W takim razie proponuje upewnić się że metoda którą chcesz wołać jest faktycznie statyczna. Bo ten nullpointer nie bierze się z powietrza. Albo metoda nie jest statyczna albo jest jakiś problem z zainstancjonowaniem obiektu klasy z którego chcesz wołać tą metodę. Proponuje odpalić to sobie pod debuggerem i sprawdzić gdzie ten null jest :)

0

@Shalom - metody statyczne biora wlasnie nulla jako pierwszy parametr do invoke. Metody statyczne nie sa metodami klasy, takie cos (no ok, podobne) to w pythonie ;d
@autor - za malo kodu, pokaz wiecej.

0

Ok - widać pora mi nie służyła przy kodzeniu - nie wpisałem słówka 'static'. Temat uważam za zamknięty

0
mućka napisał(a):

Metody statyczne nie sa metodami klasy

Chyba nieco się pomyliłeś.
Metody statyczne są metodami klasy. To metody niestatyczne są de facto przypisane do obiektów danej klasy, a nie do klasy samej w sobie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1