Dotkliwy brak refleksji w GWT (+MVP4G)

45 views
Skip to first unread message

Krzysztof Nielepkowicz

unread,
Feb 15, 2012, 9:49:46 AM2/15/12
to warsza...@googlegroups.com
Witam,

Mam drobny problem z rozwiązaniem problemu dynamicznego tworzenia obiektów na podstawie klasy. Ale zacznijmy od początku.


mam klasę :
public class CustomTable<T extends BasicBean> extends CellTable<T>
{
//1)
    private Class<T> genericTypeClass;
//2)
    ListDataProvider<T> f_pro;
    ...
    ...

    /**
     * Dodaje do do tabelki wiersz - wiersz to gotowa tablica stringów do wyświetlenia,
     * metoda zmienia tą tablicę na obiekt klasy, której instancje są przechowywane w tabelce
     * a następnie dodaje go do listy
     * @param <U> pomocniczy typ obiektu - rozszerza BasicBean
     * @param row tablica stringów z której jest tworzony obiekt - każdy element tablicy to pole obiektu, kolejność
     *         musi być zgodna z kolejnością pól
     */
    @SuppressWarnings("unchecked")
    public <U extends BasicBean>void addRow(String row[]) //3
    {
        try
        {    
//4)                  
            //ClassType<T> typ = TypeOracle.Instance.getClassType(genericTypeClass);
            //Constructor<T> con = typ.findConstructor(new String[]{});
            //U ob = (U)con.newInstance();           
           
            U ob = (U) GWT.create(genericTypeClass);    //5)
            (ob).setFields(row);
            f_pro.getList().add((T)ob);
           
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
....
....
}

Opis :

1) genericTypeClass - zmienna przechowywująca Class<T> , ustawiam ją podczas inicjalizacji tabelki
2) f_pro - dataProvider dla tabelki
3) BasicBean - hierarchia beanów z danymi (użycie MyBatisa było również jednym z czynników dla zastosowania idei beanów) ma wspólny korzeń - ta klasa jest podstawowa - jak łatwo się z nazwy domyślić ;)
4) próba użycia GWT-ENT - dodaje refleksję dla GWT, jednak wygląda na to że MVP4G nie toleruje tej biblioteki. Przez chwilę rozważalem użycie GWT-REFLECTION , jednak projekt jest słabo udokumentowany i wygląda na to że zarzucony.
5) GWT.create(genericTypeClass) powoduje błąd "Only class literals may be used as arguments to GWT.create()" , w hosted mode działa :] ale kod js tworzony podczas kompilacji GWT jest statyczny i stąd to ograniczenie...

Nowy wiersz tabeli tworzę z tablicy Stringów (jedna kontrolka do tworzenia wielu rodzajów obiektów - zawsze zwraca tablicę wartości. ) .  Możliwe że pomysł na hierarchię dziedziczenia beanów jest chybiony, ale dobrze pokazuje dotkliwość braku konstrukcji typu clazz.newInstance(). Obecnie zastosowałem to po przez zdefiniowanie w klasie opisującej bean'a metody tworzącej nowego - coś na kształt clone ale zwracającego niewypełniony obiekt.

Mam nadzieję że udało mi się w miarę obrazowi i zwięźle przedstawić problem.

P.S. miałem napisać kolejnego posta na blogu o użyciu refleksji ale póki co żadnych sukcesów nie osiągnąłem :(


--
Serdecznie Pozdrawiam,
Krzysztof Nielepkowicz
fotografia : fotomilo.pl
mój programistyczny blog : http://kyniek.blogspot.com/

Maciej Jaśkowski

unread,
Feb 15, 2012, 1:56:24 PM2/15/12
to warsza...@googlegroups.com
Temat ważny, niedawno rozbiliśmy się z Michałem na tym samym, więc
jeśli znajdziesz rozwiązanie do piątku do koniecznie daj znać, a jak
nie, to może w sobotę rano dostaniesz na tacy coś, co upichcimy w
piątek :)

MJ

On 15 February 2012 15:49, Krzysztof Nielepkowicz

> --
> Wiadomość z grupy Warszawa Java User Group (Warszawa JUG).
> Więcej informacji na stronie
> http://groups.google.com/group/warszawa-jug?hl=pl
> Zachęcamy do odwiedzenia naszej strony domowej http://warszawa.jug.pl
> Oferty pracy dozwolone zgodnie z zasadami na
> http://sites.google.com/site/warszawajug/oferty-pracy-na-grupie

Piotr Ostrowski

unread,
Feb 15, 2012, 4:12:19 PM2/15/12
to warsza...@googlegroups.com
W pracy robiliśmy to tak, że przesyłaliśmy jeden obiekt jakiegoś typu do
strony serwera i na jego podstawie tworzyliśmy nowy, który odsyłaliśmy z
powrotem do części klienckiej. Nie da się przesłać niestety samej nazwy
klasy, bo po skompilowaniu jest ona inna (w development mode zadziała).
Wadą takiego rozwiązania jest na pewno to, że musimy mieć jakiś obiekt
wzorcowy. No ale da się z tym żyć i całość nawet działała :)

Dnia 15-02-2012 o 19:56:24 Maciej Jaśkowski <maciej.j...@gmail.com>
napisał(a):


--
Używam klienta poczty Opera Mail: http://www.opera.com/mail/

Paweł Cesar Sanjuan Szklarz

unread,
Feb 16, 2012, 1:21:41 AM2/16/12
to warsza...@googlegroups.com
Czesc

Mysle, ze warto zastanowic sie nad stosowaniem AutoBean:
http://code.google.com/p/google-web-toolkit/wiki/AutoBean

Tam masz cos ala-reflection, no i to czesc GWT.

Porzadny przyklad uzycie Autobean znajdziesz w implementacji RequestFactory.

Pawel Szklarz.

2012/2/15 Krzysztof Nielepkowicz <k.p.niel...@gmail.com>:

Michał Golichowski

unread,
Feb 16, 2012, 3:48:05 AM2/16/12
to warsza...@googlegroups.com
Rozwiązaniem działającym, acz być może niezbyt ładnym i niekoniecznie pasującym akurat do Twojego rozwiązania (z tego co kojarze jest wykorzystywane m.in. w GWT-Ext) jest użycie interfejsu tagującego (lub adnotacji na poziomie klasy) wszystkie możliwe klasy, które możesz chcieć utworzyć. Następnie tworzysz klasę fabryki, generowaną via GWT.create. Klasa fabryki generowana jest poprzez zeskanowanie Twojego kodu, znalezienie wszystkich klas implementujących interfejs tagujący i utworzenie metod-fabryk dla każdej z nich, oraz jednej metody przyjmującej string z nazwą klasy jako argument i wołającej już odpowiednią metodę-fabrykę.

Zaletą tego rozwiązania jest to, że działa :-) oraz że nie jest zbyt trudne do zaimplementowania i raczej nie cechuje się specjalnie wysokim performance hitem (jeśli użyjesz jakiejś sensownej struktury do mapowania string -> odpowiednia metoda-fabryka, np. mapy). Wadą jest oczywiście to, że to "hack" i że musisz wcześniej zmienić wszystkie swoje klasy (które mają być generowane) tak, aby implementowały wybrany interfejs.

Jeśli zmiana klas tak, aby ten interfejs implementowały/zawierały adnotację, nie jest możliwa (bo np. to są klasy do których kodu nie masz dostępu), zawsze możesz spróbować innego rozwiązania (np. przygotować listę klas które mogą być tworzone w jakimś pliku konfiguracyjnym).
--
Michał Golichowski

Krzysztof Nielepkowicz

unread,
Feb 17, 2012, 4:43:23 AM2/17/12
to warsza...@googlegroups.com
Tak te� zrobi�em ;) dzi�ki za rad�. Pom�g� mi troch� te� temat na stackoverflow : http://stackoverflow.com/questions/451658/gwt-dynamic-loading-using-gwt-create-with-string-literals-instead-of-class-lit z tym �e zamiast nazwy klasy-stringa u�ywam zmiennej class. Zastosowanie AutoBean troch� mi nie pasowa�o do problemu aczkolwiek warto mie� na uwadze istnienie prostej serializacji obiekt�w do json i odwrotnie co jednak w przysz�o�ci moze si� przyda�. Przyjemna te� jest opcja tworzenia obiekt�w na podstawie interfejs�w.
�� Wracaj�c do rozwi�zania - niekoniecznie jest ono eleganckie, ale po napisaniu generatora (przypomnia�em sobie �e tak mo�na :P ) wiele nie trzeba si� napisa� by osi�gn�� cel. Sam generator przypomina mi troch� styl pisania w oraclu i jak to do�wiadczony kolega mnie podsumowa� "O, Kyniek ju� zauwa�y� �e w pl//sql si� nie pisze, tylko si� generuje" :P Chyba a� napisz� posta o hakowaniu GWT :P


Pozdrawiam i dzi�ki wszystkim :)
Rozwi�zaniem dzia�aj�cym, acz by� mo�e niezbyt �adnym i niekoniecznie pasuj�cym akurat do Twojego rozwi�zania (z tego co kojarze jest wykorzystywane m.in. w GWT-Ext) jest u�ycie interfejsu taguj�cego (lub adnotacji na poziomie klasy) wszystkie mo�liwe klasy, kt�re mo�esz chcie� utworzy�. Nast�pnie tworzysz klas� fabryki, generowan� via GWT.create. Klasa fabryki generowana jest poprzez zeskanowanie Twojego kodu, znalezienie wszystkich klas implementuj�cych interfejs taguj�cy i utworzenie metod-fabryk dla ka�dej z nich, oraz jednej metody przyjmuj�cej string z nazw� klasy jako argument i wo�aj�cej ju� odpowiedni� metod�-fabryk�.

Zalet� tego rozwi�zania jest to, �e dzia�a :-) oraz �e nie jest zbyt trudne do zaimplementowania i raczej nie cechuje si� specjalnie wysokim performance hitem (je�li u�yjesz jakiej� sensownej struktury do mapowania string -> odpowiednia metoda-fabryka, np. mapy). Wad� jest oczywi�cie to, �e to "hack" i �e musisz wcze�niej zmieni� wszystkie swoje klasy (kt�re maj� by� generowane) tak, aby implementowa�y wybrany interfejs.

Je�li zmiana klas tak, aby ten interfejs implementowa�y/zawiera�y adnotacj�, nie jest mo�liwa (bo np. to s� klasy do kt�rych kodu nie masz dost�pu), zawsze mo�esz spr�bowa� innego rozwi�zania (np. przygotowa� list� klas kt�re mog� by� tworzone w jakim� pliku konfiguracyjnym).

On Thu, Feb 16, 2012 at 7:21 AM, Paweďż˝ Cesar Sanjuan Szklarz <paw...@gmail.com> wrote:
Czesc

Mysle, ze warto zastanowic sie nad stosowaniem AutoBean:
http://code.google.com/p/google-web-toolkit/wiki/AutoBean

Tam masz cos ala-reflection, no i to czesc GWT.

Porzadny przyklad uzycie Autobean znajdziesz w implementacji RequestFactory.

Pawel Szklarz.

2012/2/15 Krzysztof Nielepkowicz <k.p.niel...@gmail.com>:
> Witam,
>
> Mam drobny problem z rozwi�zaniem problemu dynamicznego tworzenia obiekt�w
> na podstawie klasy. Ale zacznijmy od pocz�tku.
>
>
> mam klasďż˝ :

> public class CustomTable<T extends BasicBean> extends CellTable<T>
> {
> //1)
> ��� private Class<T> genericTypeClass;
> //2)
> ��� ListDataProvider<T> f_pro;
> ��� ...
> ��� ...
>
> ��� /**
> ��� �* Dodaje do do tabelki wiersz - wiersz to gotowa tablica string�w do
> wy�wietlenia,
> ��� �* metoda zmienia t� tablic� na obiekt klasy, kt�rej instancje s�
> przechowywane w tabelce
> ��� �* a nast�pnie dodaje go do listy
> ��� �* @param <U> pomocniczy typ obiektu - rozszerza BasicBean
> ��� �* @param row tablica string�w z kt�rej jest tworzony obiekt - ka�dy
> element tablicy to pole obiektu, kolejno��
> ��� �* ��� ��� musi by� zgodna z kolejno�ci� p�l
> ��� �*/
> ��� @SuppressWarnings("unchecked")
> ��� public <U extends BasicBean>void addRow(String row[]) //3
> ��� {
> ��� ��� try
> ��� ��� {
> //4)
> ��� ��� ��� //ClassType<T> typ =
> TypeOracle.Instance.getClassType(genericTypeClass);
> ��� ��� ��� //Constructor<T> con = typ.findConstructor(new String[]{});
> ��� ��� ��� //U ob = (U)con.newInstance();
>
> ��� ��� ��� U ob = (U) GWT.create(genericTypeClass);��� //5)
> ��� ��� ��� (ob).setFields(row);
> ��� ��� ��� f_pro.getList().add((T)ob);
>
> ��� ��� } catch (Exception e)
> ��� ��� {
> ��� ��� ��� e.printStackTrace();
> ��� ��� }
> ��� }
> ....
> ....
> }
>
> Opis :
>
> 1) genericTypeClass - zmienna przechowywuj�ca Class<T> , ustawiam j� podczas

> inicjalizacji tabelki
> 2) f_pro - dataProvider dla tabelki
> 3) BasicBean - hierarchia bean�w z danymi (u�ycie MyBatisa by�o r�wnie�
> jednym z czynnik�w dla zastosowania idei bean�w) ma wsp�lny korze� - ta
> klasa jest podstawowa - jak �atwo si� z nazwy domy�li� ;)
> 4) pr�ba u�ycia GWT-ENT - dodaje refleksj� dla GWT, jednak wygl�da na to �e
> MVP4G nie toleruje tej biblioteki. Przez chwil� rozwa�alem u�ycie
> GWT-REFLECTION , jednak projekt jest s�abo udokumentowany i wygl�da na to �e
> zarzucony.
> 5) GWT.create(genericTypeClass) powoduje b��d "Only class literals may be
> used as arguments to GWT.create()" , w hosted mode dzia�a :] ale kod js
> tworzony podczas kompilacji GWT jest statyczny i st�d to ograniczenie...
>
> Nowy wiersz tabeli tworz� z tablicy String�w (jedna kontrolka do tworzenia
> wielu rodzaj�w obiekt�w - zawsze zwraca tablic� warto�ci. ) .� Mo�liwe �e
> pomys� na hierarchi� dziedziczenia bean�w jest chybiony, ale dobrze pokazuje
> dotkliwo�� braku konstrukcji typu clazz.newInstance(). Obecnie zastosowa�em
> to po przez zdefiniowanie w klasie opisuj�cej bean'a metody tworz�cej nowego
> - co� na kszta�t clone ale zwracaj�cego niewype�niony obiekt.
>
> Mam nadziej� �e uda�o mi si� w miar� obrazowi i zwi�le przedstawi� problem.
>
> P.S. mia�em napisa� kolejnego posta na blogu o u�yciu refleksji ale p�ki co
> �adnych sukces�w nie osi�gn��em :(

>
>
> --
> Serdecznie Pozdrawiam,
> Krzysztof Nielepkowicz
> fotografia : fotomilo.pl
> m�j programistyczny blog : http://kyniek.blogspot.com/
>
> --
> Wiadomo�� z grupy Warszawa Java User Group (Warszawa JUG).
> Wi�cej informacji na stronie
> http://groups.google.com/group/warszawa-jug?hl=pl
> Zach�camy do odwiedzenia naszej strony domowej http://warszawa.jug.pl

> Oferty pracy dozwolone zgodnie z zasadami na
> http://sites.google.com/site/warszawajug/oferty-pracy-na-grupie

--
Wiadomo�� z grupy Warszawa Java User Group (Warszawa JUG).
Wi�cej informacji na stronie http://groups.google.com/group/warszawa-jug?hl=pl
Zach�camy do odwiedzenia naszej strony domowej http://warszawa.jug.pl

Oferty pracy dozwolone zgodnie z zasadami na http://sites.google.com/site/warszawajug/oferty-pracy-na-grupie



--
Michaďż˝ Golichowski

--
Wiadomo�� z grupy Warszawa Java User Group (Warszawa JUG).
Wi�cej informacji na stronie http://groups.google.com/group/warszawa-jug?hl=pl
Zach�camy do odwiedzenia naszej strony domowej http://warszawa.jug.pl

Oferty pracy dozwolone zgodnie z zasadami na http://sites.google.com/site/warszawajug/oferty-pracy-na-grupie


--
Serdecznie Pozdrawiam,
Krzysztof Nielepkowicz
fotografia : fotomilo.pl
m�j programistyczny blog : http://kyniek.blogspot.com/

Jacek Laskowski

unread,
Feb 17, 2012, 4:53:55 AM2/17/12
to warsza...@googlegroups.com
2012/2/17 Krzysztof Nielepkowicz <k.p.niel...@gmail.com>:

>    Wracając do rozwiązania - niekoniecznie jest ono eleganckie, ale po
> napisaniu generatora (przypomniałem sobie że tak można :P ) wiele nie trzeba
> się napisać by osiągnąć cel. Sam generator przypomina mi trochę styl pisania
> w oraclu i jak to doświadczony kolega mnie podsumował "O, Kyniek już
> zauważył że w pl//sql się nie pisze, tylko się generuje" :P Chyba aż napiszę


> posta o hakowaniu GWT :P

Bardzo bym prosił, bo coś mi tu pachnie możliwością
włączenia...Clojure z jego makrami :) Na kanwie tego problemu możnaby
zaprezentować możliwości narzędzi, które być może są bardziej
dopasowane do niego. Tak tylko gdybam głośno.

Jacek

--
Jacek Laskowski
Java EE, functional languages and IBM WebSphere - http://blog.japila.pl
Warszawa JUG conference = Confitura (formerly Javarsovia) :: http://confitura.pl
"Hoping to save time by spending it" by David Blevins (Apache OpenEJB)

Krzysztof Nielepkowicz

unread,
Feb 20, 2012, 7:06:21 PM2/20/12
to warsza...@googlegroups.com
On 2012-02-17 10:53, Jacek Laskowski wrote:
> 2012/2/17 Krzysztof Nielepkowicz<k.p.niel...@gmail.com>:
>
>> Wracaj�c do rozwi�zania - niekoniecznie jest ono eleganckie, ale po
>> napisaniu generatora (przypomnia�em sobie �e tak mo�na :P ) wiele nie trzeba
>> si� napisa� by osi�gn�� cel. Sam generator przypomina mi troch� styl pisania

>> w oraclu i jak to do�wiadczony kolega mnie podsumowa� "O, Kyniek ju�
>> zauwa�y� �e w pl//sql si� nie pisze, tylko si� generuje" :P Chyba a� napisz�
>> posta o hakowaniu GWT :P
> Bardzo bym prosi�, bo co� mi tu pachnie mo�liwo�ci�
> w��czenia...Clojure z jego makrami :) Na kanwie tego problemu mo�naby
> zaprezentowa� mo�liwo�ci narz�dzi, kt�re by� mo�e s� bardziej
> dopasowane do niego. Tak tylko gdybam g�o�no.
>
> Jacek
>
Hey,

co prawda, jeszcze nie doko�czony post (pochorowa�em si� i tak sprawnie
nie pisz� jak bym m�g�) ale dobrze obja�nia ide� :
http://kyniek.blogspot.com/2012/02/dynamiczne-tworzenie-obiektow-w-gwt.html
jutro doko�cz�, ale postanowi�em opublikowa� by� mia� mo�liwo��
zerkni�cia przed prezentacj�. Mam nadziej� �e dotr� na spotkanie jugowe :?

P.S. idďż˝ spaďż˝ :E

Michał Golichowski

unread,
Feb 21, 2012, 3:43:51 AM2/21/12
to warsza...@googlegroups.com
Hej,

To i ja się pochwalę wpisem blogowym na ten sam temat. :-) Post jest co prawda po angielsku, ale mam nadzieję że dodatkowy punkt widzenia zawsze jest mile widziany:  http://jdevmike.blogspot.com/2012/02/gwt-and-its-lack-of-reflection-support.html 

Pierwsza część to ogólne wprowadzenie do generatorów, opis takiego konkretnie przypadku (użycie generatora do dynamicznego tworzenia obiektów) opisany jest w części "Reflecting on GWT".

Pozdrawiam,
 Michał

On Tue, Feb 21, 2012 at 1:06 AM, Krzysztof Nielepkowicz <k.p.niel...@gmail.com> wrote:
On 2012-02-17 10:53, Jacek Laskowski wrote:
2012/2/17 Krzysztof Nielepkowicz<k.p.nielepkowicz@gmail.com>:

   Wracając do rozwiązania - niekoniecznie jest ono eleganckie, ale po
napisaniu generatora (przypomniałem sobie że tak można :P ) wiele nie trzeba
się napisać by osiągnąć cel. Sam generator przypomina mi trochę styl pisania
w oraclu i jak to doświadczony kolega mnie podsumował "O, Kyniek już
zauważył że w pl//sql się nie pisze, tylko się generuje" :P Chyba aż napiszę
posta o hakowaniu GWT :P
Bardzo bym prosił, bo coś mi tu pachnie możliwością

włączenia...Clojure z jego makrami :) Na kanwie tego problemu możnaby
zaprezentować możliwości narzędzi, które być może są bardziej
dopasowane do niego. Tak tylko gdybam głośno.

Jacek

Hey,

co prawda, jeszcze nie dokończony post (pochorowałem się i tak sprawnie nie piszę jak bym mógł) ale dobrze objaśnia ideę :
http://kyniek.blogspot.com/2012/02/dynamiczne-tworzenie-obiektow-w-gwt.html
jutro dokończę, ale postanowiłem opublikować byś miał możliwość zerknięcia przed prezentacją. Mam nadzieję że dotrę na spotkanie jugowe :?

P.S. idę spać :E


--
Serdecznie Pozdrawiam,
Krzysztof Nielepkowicz
fotografia : fotomilo.pl
mój programistyczny blog : http://kyniek.blogspot.com/

--
Wiadomość z grupy Warszawa Java User Group (Warszawa JUG).
Więcej informacji na stronie http://groups.google.com/group/warszawa-jug?hl=pl
Zachęcamy do odwiedzenia naszej strony domowej http://warszawa.jug.pl

Oferty pracy dozwolone zgodnie z zasadami na http://sites.google.com/site/warszawajug/oferty-pracy-na-grupie



--
Michał Golichowski

Reply all
Reply to author
Forward
0 new messages