This blog is no longer being maintained, please go to The missing link of Agile instead

Sunday, May 25, 2008

Psucie XML'a

Reader discretion is advised. (1)

Na wiki u Jacka Laskowskiego pojawił się artykuł o JAXB, co pozwoliło mi po raz drugi w życiu na szybkie przyjrzenie się tej technologii. Kwestią, która przyciągnęła moja uwagę jest nazewnictwo elementów przy marshallingu kolekcji. Nazwa elementów XML odpowiada nazwie kolekcji w Javie, co daje dość śmieszny efekt w postaci:

<opakowanie>
<listaElementow>
..
</listaElementow>

<listaElementow>
..
</listaElementow>
</opakowanie>


Wydaje się, że po raz kolejny czkawką odbija się sposób implementacji generyków w Javie. Zdecydowanie lepiej, gdyby nazwy elementów były wnioskowane na podstawie typu generycznego - jeśli byłoby to możliwe :P. W jednym z projektów, w których uczestniczyłem, używano właśnie JAXB i pamiętam, że taki sposób implementacji nazw powodował niejednokrotnie zakłopotanie programistów (klientów) korzystających z tworzonego XML'a.

Posunę się do stwierdzenia, że takie traktowanie formatu XML jest niszczeniem intencji jego istnienia, a przynajmniej ważnej części jakim jest semantyka XML. Ponoć XML jest formatem samo-opisującym. Jeśli jednak będziemy go "wykrzywiać" i dopasowywać do ułomności technologicznych nie jestem pewien czy po pewnym czasie XML wciąż będzie zdatny do użytku..

1) Wyolbrzymienie problemu jest celowe.

Wednesday, May 14, 2008

Facet to świnia ?!

Podczas przygotowywania się do dzisiejszego seminarium - jak każdy porządny student zacząłem 6h przed wydarzeniem ;) - potrzebowałem dokładnie sprawdzić jak brzmi poprawna nazwa zasady Liskova. Mnie osobiście najbardziej podoba się nazwa 'zasada substytucji', ale jak to w nauce nie liczy się to co się komu podoba ale jak jest :]. Jakież było moje zdziwienie gdy natrafiłem na ten post: http://www.3jane.pl/2006/10/11/jestem-niezyciowa/.

Otóż okazuje się, że 'Zasada substytucji' nie jest Liskova, ale Liskovej ! Autorem elementarnej dla programowania obiektowego zasady jest bowiem pani Barbara Liskov, dla potwierdzenia: http://en.wikipedia.org/wiki/Barbara_Liskov. Muszę się w tym momencie uderzyć w pierś, ponieważ i ja niejednokrotnie zawiniłem cytując źródła, zawsze zakładając że autorem jest jakiś Pan.

A potem dziwią się wszyscy, że wśród inżynierów informatyków tak mało kobiet. Wstyd panowie, wstyd !

Friday, May 02, 2008

Blog - reaktywacja

Ostatni post ukazał się w listopadzie zeszłego roku, tak więc trudno mówić o jakiejkolwiek ciągłości :P Tamten okres był jednak stosunkowo pracowity, więc mam nadzieję że kilka miesięcy po jego zakończeniu będę w stanie "zmusić się" do regularnego pisania :) Co więcej odkryłem w tym czasie, że ostatnio zaprezentowany pomysł okazał się reifikacją (hehe Holub rox ;) ) wzorca projektowego State (z domieszką Special Case'a).

A co natchnęło mnie do powrotu na bloga - otóż znalazłem buga w Javie :), a dokładniej w implementacji introspekcji (java.beans.*). Na problem natknąłem się rozwijając aplikację webową, co tylko utrudniło wyodrębnienie go, ale w końcu się udało ! Na początek trochę kodu:

public interface ITest<T> {
public T getDelta();
}

public class Foo implements ITest<String> {
private List<String> alfa;
private String beta;
private String gamma;

public List<String> getAlfa() {
return alfa;
}

public void setAlfa(final List<String> alfa) {
this.alfa = alfa;
}

public String getBeta() {
return beta;
}

public void setBeta(final String beta) {
this.beta = beta;
}

public String getDelta() {
return gamma;
}

public void setDelta(final String gamma) {
this.gamma = gamma;
}
}

public class Bar implements ITest<String> {
private List<String> alfa;
private String beta;
private String gamma;

public List<String> getAlfa() {
return alfa;
}

public void setAlfa(final List<String> alfa) {
this.alfa = alfa;
}

public String getGamma() {
return gamma;
}

public void setGamma(final String gamma) {
this.gamma = gamma;
}

public String getBeta() {
return beta;
}

public void setBeta(final String beta) {
this.beta = beta;
}

public String getDelta() {
return gamma;
}

public void setDelta(String gamma) {
this.gamma = gamma;
}
}


I najważniejsza część - kod testujący. Pobiera deskryptory pól dla każdej z klas, a następnie wypisuje metody zapisu dla poszczególnych deskryptorów. Mowiąc prościej kod wyświetla settery zgodne ze specyfikacją JavaBeans (jeśli nie ma - wypisze 'null'):

Dla ułatwienia będę podawał wartości tylko dla property: "delta".

Po wywołaniu kodu powyżej otrzymamy wynik:

"delta null" (dla Foo)
"delta null" (dla Bar)

Po zamianie wywołań dostaniemy:

"delta public void pl.test.Bar.setDelta(java.lang.String)"
"delta null"

Po zakomentowaniu części "Dla Foo" wynik będzie:

"delta public void pl.test.Bar.setDelta(java.lang.String)"

Natomiast po zakomentowaniu części "Dla Bar" na konsoli pojawi się znowu:

"delta null"

Szczerze mówiąc powyższe wyniki są dla mnie kompletnie niedeterministyczne ;D. Mogę jedynie domniemywać, że ma to jakiś związek z typami generycznymi i cache'owaniem przy introspekcji. Strzelałbym nawet, że w tym przypadku łączy się więcej niż jeden bug, stąd dość "ciekawe" rezultaty". Biorąc nawet pod uwagę, że są znane problemy na styku JavaBeans i generyków1 powyższe wyniki wydają się definitywnie zbyt "pseudo-losowe" ;).

Wszystko będzie ok jeśli:
  • zarówno 'getter' i 'setter' jest generyczny i dziedziczony,
  • i co ciekawe ... 'setter' jest generyczny i dziedziczony
Potencjalny work-around - unikać rozwiązania jak powyżej :P.

1. Warto popatrzeć na następujące zgłoszenia:
http://bugs.sun.com/view_bug.do?bug_id=6422403
http://bugs.sun.com/view_bug.do?bug_id=6473468
http://bugs.sun.com/view_bug.do?bug_id=5098163