Ładowanie klas w Javie ME

0

Implementuję obecnie własną bibliotekę, pozwalającą na serializację obiektów w Javie ME.
Natrafiłem na spory problem, mianowicie przeprowadzam deserializację obiektów w następujący sposób:

//...
else if (type == ObjectOutputStream.T_SERIALIZED_OBJECT) {
            String name = readString();     // pobierz string z nazwą klasy, np com.mystuff.Class1
            Class c = Class.forName(name); // ładujemy klasę
            Serializable so = (Serializable) (c.newInstance()); // tu błąd, nie można utworzyć instancji klasy
            Object o = so.readObject(this);
            return o;
}

Opisany wyżej sposób nie działa, ponieważ Java ME nie pozwala na ładowanie klas przez Class.forName()
( nie ma w niej dostępu do ClassLoader'a ). Poszukuję sposobu na ominięcie tej niedogodności - mechanizmu
który pozwoli mi załadować klasę, której nazwa jest znana i stworzyć jej instancję.

0
            //...
            Class c = Class.forName(name); // ładujemy klasę
            Serializable so = (Serializable) (c.newInstance()); // tu błąd, nie można utworzyć instancji klasy
            //...

A mozesz podrzucic stack trace, albo powiedziec co nie dziala? Class.forName(String) oczekuje kompletnej (fully qualified) nazwy klasy. Dalej, musisz miec odpowiedni konstruktor, z odpowiednim kwalifikatorem dostepu. Poza tym, nie wiem, jakich konkretnie API uzywasz, ale java.io.Serializable nie ma w MIDP 2.0.

Cokolwiek planujesz zrobic w J2ME, jestes pewny, ze nie daloby sie tego rozwiazac w prostszy sposob?

0

Zostaje wyrzucony IllegalAccessException, co oznacza, jak możemy przeczytać w javadoc: the class or initializer is not accessible.
Klasa Settings posiada bezargumentowy konstruktor. Nie wiem czy to prawda, ale gdzieś czytałem, że za pomocą Class.forName() nie można w J2ME załadować 'third-party classes'. Podaję pełną nazwę klasy, np. 'gps.Settings'. Serializable, to interface, jaki sam sobie stworzyłem.

Oczywiście mogę zrobić to prościej, np.

 else if (type == ObjectOutputStream.T_SERIALIZED_OBJECT) {
            String name = readString();
            Object o = null;
            if(name.equals("gps.Settings")){
                o = new Settings();
            }
            else if(name.equals("gps.GPSProvider")){
                o = new GPSProvider();
            }
            // else ... instrukcje dla innych serializowanych klas
            Serializable so = (Serializable) (o);
            o = so.readObject(this);
            return o;
        }

Powyższy sposób działa, chciałbym jednak, żebym mój mechanizm serializacji był bardziej uniwersalny a do tego jest mi potrzebne
narzędzie, które pozwala na tworzenie instancji klas o zadanej nazwie.

0
RJM napisał(a)

Zostaje wyrzucony IllegalAccessException, co oznacza, jak możemy przeczytać w javadoc: the class or initializer is not accessible.
Klasa Settings posiada bezargumentowy konstruktor.

Jestes pewny, ze bezargumentowe konstruktory w Twoich klasach (gps.Settings, gps.GPSProvider, itd.) sa publiczne (widoczne dla klasy, z ktorej wolasz Class.newInstance()? Class Loader laduje klase prawidlowo, ale ma problem z konstruktorem.

RJM napisał(a)

Nie wiem czy to prawda, ale gdzieś czytałem, że za pomocą Class.forName() nie można w J2ME załadować 'third-party classes'.

Mozna, jesli dana klasa znajduje sie w tym samym MIDlet suite (plik *.jar). Class loader w KVM (bootstrap class loader) nie pozwoli natomiast zaladowac zadnych zewnetrznych klas.

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