Zagadkowy java.lang.IllegalAccessError

Zagadkowy java.lang.IllegalAccessError
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Zgodnie z dokumetcją

public class IllegalAccessError
extends IncompatibleClassChangeError

Thrown if an application attempts to access or modify a field, or to call a method that it does not have access to.

Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.

U mnie kompilacja przebiegała bez zarzutu, ale podczas wykonywania wiersz

Kopiuj
InputText input = new InputText(this,"Tytuł:",title.getTex`code> rzucał wyjątkiem` 
Exception in thread "AWT-EventQueue-0" java.lang.IllegalAccessError: tried to access class InputText from class Creator

(Klasa InputText to moja klasa narzędziowa dziedzicząca po JDialog). Po zmianie nazwy klasy na InputingText wszystko działa.
Ma ktoś hipotezę wyjaśniającą to zjawisko?


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Zgaduje: w runtime masz dostępną inną klasę o nazwie InputText a tutaj masz jakiś import z * więc automatycznie jest brana pod uwagę. Jeśli w runtime zostanie załadowana wcześniej niż ta twoja to się posypie. Anyway, uruchom to pod debugerem i zobacz co się tam dokładnie dzieje.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Też miałem taki pomysł. Przejrzałem wszystkie jary z .../lib/ext, tylko jeden zawiera klasę InputText (tę właściwą). Kopiowałem też plik InputText.class do katalogu z projektem i uruchamiałem program poleceniem java -cp . ..., nie pomagało.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

A jesteś pewien że uruchamiasz z tym samym z czym kompilowałeś? Bo może klasę masz tylko jedną ale skompilowałeś jara z nią a teraz kompilujesz swój kod używając zmienionej wersji jako zależności a potem odpalasz korzystajac z tego starego jara?


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Jara z klasą InputText zmieniłem już dzisiaj z 6 razy.
Skopiowałem klasę InputText do projektu, uruchomiłem program z debuggerem, program nie wszedł do konstruktora tej klasy, w zamian rzucił wyjątkiem. JRE wyraźnie korzysta z jakiejś innej wersji tej klasy. Jak ją wytropić.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 2 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4709
1

Strzelam...

Masz smieci w plikach .class - wyczyść projekt. (clean - albo recznie je usun). Potem jeszcze raz kompilacja. A aak nie pomoze to może wrzuc zrodla.


jeden i pół terabajta powinno wystarczyć każdemu
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Nie mam śmieci. Po skopiowaniu plików na inny komputer program (z InputText) poszedł. Na pierwszym komputerze program uruchomiony poleceniem javaw ... też poszedł (polecenie java ... nadal generuje błąd).


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Dzisiaj (po restarcie komputera i JVM) objawy takie same: javaw ... działa, java ... rzuca wyjątkiem, uruchomienie w IDE (Eclipse) rzuca wyjątkiem.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
0

Odpal na debugu:

Class.forName("twoj.pakiet.InputText").getProtectionDomain().getCodeSource().getLocation()

Wynikiem będzie URL do klasy, która rzeczywiście została wybrana z classpathu przez JVM.

Otwórz teraz znaleziony plik w jakimś dekompilatorze (np. JDecompiler) i sprawdź czy kod który tam widzisz pokrywa się z Twoim w edytorze, czy może jednak w runtimie używasz czegoś nieaktualnego.

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Zaraz sprawdzę. Ale jak pisałem wcześniej

  • przeszukałem wszystkie jary na dysku i znalazłem tylko jedną klasę InputText,
  • sugerujesz, że polecenia java i javaw korzystają z innego runtimu?

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Aktualnie kod wygląda tak:

Kopiuj
mi.addActionListener(e -> changeTitle()); //mi jest typu JMenuItem
...
    private void changeTitle()
    {
        try
        {
            System.out.println(Class.forName("InputText").getProtectionDomain().getCodeSource().getLocation());
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
        InputText input = new InputText(this,"Tytuł:",title.getText());
        input.setVisible(true);
        title.setText(input.getText());        
    }

Po uruchomieniu programu poleceniem java ... na konsoli pojawia się nazwa oczekiwanego przeze mnie jara, a po poleceniu javaw ... nie pojawia się nic - kolejna zagadka. Wie ktoś jak namówić debugger w IDE (Eclipse lub IntelliJ) by skorzystał z polecenia javaw? W ostateczności przemianuję tymczasowo javaw.exe' na java.exe`.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
0

javaw nie ma "przypisanej" do siebie konsoli więc nie widzisz tego co jest wrzucane do System.out.

Wywołaj sobie na początku metody changeTitle:

Kopiuj
System.setOut(new PrintStream(new FileOutputStream("log.txt",true)));

i sprawdź swój output w pliku.

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Raczysz żartować. Skoro uruchamiam program poleceniem javaw ... tzn. że wpisuję to polecenie w konsoli i żadna zmiana strumienia wyjściowego nie jest potrzebna.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
0

Nie żartuję.

javaw forkuje nowy proces i jego standardowe wyjście nijak nie jest powiązane z Twoją konsolą.

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

W obu przypadkach (java ... i javaw ...) jest ta sama nazwa klasy.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
airborn
  • Rejestracja:prawie 16 lat
  • Ostatnio:około 7 lat
  • Postów:274
0

Miałem kiedyś podobny przypadek, java ewidentnie widziała klasę pomimo tego, ta była usunięta z projektu. Żadne cleany i rekompilacje nie pomagały. Nie pomagało też ubijanie wszystkich działających JVM, tylko, że w moim przypadku restart OS pomógł.

bogdans
U mnie nie dość, że nie pomógł ani restart OS ani update Javy, to jeszcze java i javaw widzą co innego.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.