Weryfikacja Statyczna w J2EE
Thu, 22 Feb 2007 21:27:57 +0000
J2EE to w uproszczeniu zbiór technologii opartych o Javę służących do tworzenia aplikacji dostępnych przez sieć. Elastyczność i możliwość konfiguracji, oparta w głównej mierze na plikach XML, prowadzi do tego, że coraz więcej błędów znajduje się poza kontrolą kompilatora.
W systemach starszego typu większość konfiguracji interakcji pomiędzy poszczególnymi fragmentami systemu była opisana w kodzie i jako taka mogła byś sprawdzona (przynajmniej częściowo) w fazie kompilacji. Tendencja wyrzucenia części informacji poza kod Javy powoduje niestety, że uzyskując elastyczność i pozorną łatwość wprowadzania zmian wypychamy błędy do fazy uruchomienia (run time).
Złożoność architektury J2EE powoduje, że cykl pracy (rekompilacja, instalacja, testowanie w przeglądarce) jest długi. Utrudnia to znacznie usuwanie błędów metodą "popraw i przeklikaj". Co można zrobić aby przyspieszyć proces usuwania błędów w J2EE?
Weryfikacja Statyczna
Większości z nas weryfikacja statyczna oprogramowania kojarzy się z wspomaganymi komputerowo systemami dowodzenia poprawności oprogramowania. Idea jest taka, by bez uruchamiania programu wychwycić wszystkie błędy, które mogą wystąpić w systemie. Dzięki temu (teoretycznie) faza testowania tylko potwierdza, że program jest napisany prawidłowo. Jednak kryje się w tym pomyśle kilka poważnych trudności z którymi jak do tej pory nie udało się informatyce uporać:- W praktyce napisanie formalnej specyfikacji funkcjonalności jest trudne i pracochłonne
- Narzędzia służące do weryfikacji są trudne w użyciu i wymagają długiej praktyki przez produktywnym wykorzystaniem
- Nie zawsze da się automatycznie sprawdzić formalną specyfikację względem programu automatycznie (wymagana jest interwencja człowieka)
Zasoby w J2EE
Przez pojęcie zasób na potrzeby niniejszego artykułu rozumiem elementy aplikacji J2EE, które można niezależnie analizować, a które są wiązane ze sobą po instalacji w serwerze aplikacyjnym. Jednym z zasobów jest np. kod Javy, analiza jest przeprowadzana przez kompilator podczas kompilacji. Poniżej wymieniam kilka wybranych "zasobów":- Kod Javy (możliwy dostęp: wyrażenia regularne, mechanizm refleksji)
- Konfiguracja Struts (możliwy dostęp: parser SAX)
- Pliki JSP (możliwy dostęp: parser SGML)
- Konfiguracja Tiles (możliwy dostęp: parser SAX)
- Tłumaczenie w ApplicationResources_*.properties (biblioteka standardowa Javy)
- ...
- Wyjątek na stronie spowodowany użyciem tagu html:text z wartością atrybutu property, które nie istnieje jako atrybut w form beanie
- Literówka w atrybucie action w tagu html:form, która powoduje błąd braku strony pod danym URL
- Brak tłumaczenia dla tekstu statycznego występującego na stronie w tagu bean:message
- Użycie nieprawidłowego atrybutu name w którymś ze strutsowych tagów powoduje wyjątek
- Test jednostkowy, który na podstawie tagu html:text (parser SGML-a) znajdzie form beana użytego w danym tagu i sprawdzi, czy w tym beanie istnieje atrybut określony przez property
- Poprawność użytych atrybutów action można sprawdzić porównując je ze zdefiniowanymi akcjami w pliku konfiguracyjnym Struts
- Dla każdego wystąpienia bean:message sprawdzić, czy istnieje wpis w pliku z tłumaczeniami
- Zły name oznacza odwoływanie się do beana pod nieistniejącą nazwą
Implementacje
Udało mi się zastosować powyższe techniki dla następujących konfiguracji J2EE:- JSF: parsowanie Java i JSP w oparciu o wyrażenia regularne, parser i weryfikator w języku AWK
- Struts: parser SGML do JSP, Beany Javy dostępne poprzez mechanizm refleksji
- Hibernate: statyczna analiza parametrów zapytania w HQL-u względem beana, który zawiera parametry