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)