Archiwum

Posts Tagged ‘NetBeans’

NetBeans + Maven: Integracja Spring Framework 3 z Struts2

11 października 2010 23 komentarze

W dzisiejszym poście zaprezentuję jak rozpocząć pracę z Spring Framework 3 oraz Struts2, wykorzystując do tego środowisko NetBeans (u mnie 6.9.1) oraz Maven 2. Jak zwykle zaprezentuję całą ścieżkę, łącznie z problemami jakie napotkałem 😛

Aby utworzyć projekt należy wybrać przejść kolejne kroki kreatora:
New Project -> Maven -> Maven Project

Z listy „Maven Archetypes” wybieramy „Archetypes from Local Respository” i zaznaczamy „Maven Webapp Archetype (1.0)„. W kolejnym oknie wypełniamy odpowiednie pola i po kliknięciu zostanie wygenerowany projekt. Pierwszy krok to dodanie zależności do pliku pom.xml (dostępny w gałęzi „Project Files„).
Do wykonania i uruchomienia projektu potrzebne są podstawowe paczki z org.springframework, paczka struts2-core, oraz plugin pozwalający na współpracę między Spring a Struts.

   <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-asm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>${org.apache.struts.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-convention-plugin</artifactId>
            <version>${org.apache.struts.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-spring-plugin</artifactId>
            <version>${org.apache.struts.version}</version>
        </dependency>
    </dependencies>

Jak widać zamiast wersji bibliotek użyłem ${org.springframework.version} oraz ${org.apache.struts.version}, oczywiście celowo – żeby w jednym miejscu zdeklarować numer wersji:

    <properties>
        <org.springframework.version>3.0.4.RELEASE</org.springframework.version>
        <org.apache.struts.version>2.2.1</org.apache.struts.version>
    </properties>

Po zapisaniu pliku można w menu kontekstowego gałezi „Libraries” wybrać „Download Missing Dependencies„.

Kolejny krok to utworzenie przykładowego kontrolera i konfiguracja Springa oraz Struts.

W tym celu w gałęzi „Source packages” tworzymy dowolną paczkę i dodajemy prostą klasę, niech to będzie klasa z akcją „Hello world”.

package eu.ryznar;

public class Hello {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String execute() {
        return "SUCCESS";
    }
}

W „Web Pages” tworzymy plik success.jsp:

<html>
<body>
<h2>Success</h2>
${message}
</body>
</html>

Teraz czas na konfigurację. W web.xml listener dla Springa oraz filter dla Struts2

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

Przeglądając różne tutoriale możecie trafić na przykład gdzie zamiast org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter została użyta klasa org.apache.struts2.dispatcher.FilterDispatcher. To zależy od wersji Struts2. Od wersji 2.1.3 FilterDispatcher jest oznaczona jako przestarzała.

Następnie w katalogu WEB-INF tworzymy plik applicationContext.xml w którym skonfigurujemy ziarna, w tym przypadku klasę „Hello”.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
    <bean id="helloClass" class="eu.ryznar.Hello" >
        <property name="message" value="Hello World!" />
    </bean>
</beans>

Następnie również w katalogu WEB-INF tworzymy plik struts.xml w którym definiujemy która klasa wykonuje akcję i zwraca odpowiedni widok.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <package name="default" extends="struts-default">
        <action name="hello" class="helloClass">
            <result name="SUCCESS">/success.jsp</result>
        </action>
    </package>
</struts>

Atrybut „class” nie wskazuje bezpośrenio na klasę eu.ryznar.Hello a na ziarno zdefiniowane w pliku konfiguracyjnym Springa.

Przed uruchomieniem należy ustawić serwer. We właściwościach projektu, w gałęzi „Run” wybieramy serwer Tomcat.
To wszystko, czas uruchomić aplikację. Jednak czeka nas niespodzianka 😉 w konsoli dostaniemy taki oto wyjątek:

2010-10-11 21:01:56 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
2010-10-11 21:01:57 org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter struts2
java.lang.reflect.InvocationTargetException - Class: com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector
File: ContainerImpl.java
Method: inject
Line: 295 - com/opensymphony/xwork2/inject/ContainerImpl.java:295:-1
        at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:428)
        at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69)
        at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:295)
        at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422)
        at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:115)
        at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3838)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4488)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:546)
        at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:637)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:521)
        at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1359)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
        at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1500)
        at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:849)
        at org.apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:351)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:199)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:558)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:295)
        at com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.construct(ContainerImpl.java:431)
        at com.opensymphony.xwork2.inject.ContainerBuilder$5.create(ContainerBuilder.java:207)
        at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:51)
        at com.opensymphony.xwork2.inject.ContainerBuilder$3.create(ContainerBuilder.java:93)
        at com.opensymphony.xwork2.inject.ContainerBuilder$7.call(ContainerBuilder.java:487)
        at com.opensymphony.xwork2.inject.ContainerBuilder$7.call(ContainerBuilder.java:484)
        at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:574)
        at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:484)
        at com.opensymphony.xwork2.config.impl.DefaultConfiguration.createBootstrapContainer(DefaultConfiguration.java:252)
        at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:193)
        at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
        at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:371)
        at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:415)
        ... 41 more
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:293)
        ... 54 more
Caused by: java.lang.ExceptionInInitializerError
        at com.opensymphony.xwork2.ognl.OgnlValueStackFactory.setContainer(OgnlValueStackFactory.java:85)
        ... 59 more
Caused by: java.lang.IllegalArgumentException: Javassist library is missing in classpath! Please add missed dependency!
        at ognl.OgnlRuntime.(OgnlRuntime.java:165)
        ... 60 more
Caused by: java.lang.ClassNotFoundException: javassist.ClassPool
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at ognl.OgnlRuntime.(OgnlRuntime.java:162)
        ... 60 more
2010-10-11 21:01:57 org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext

Co się okazuje w wersji 2.2.1 wykluczono z zależności Javassist, dlatego trzeba dodać zależność ręcznie w pom.xml

        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.9.0.GA</version>
        </dependency>

Próbujemy jescze raz uruchomić projekt. W przeglądarce zostaje otworzony plik index.jsp, jednak my chcemy zobaczyć wynik akcji hello, dlatego w pasku adresu zamiast index.jsp wpisujemy hello.action. Niestety strona się nie wyświetla a w konsoli widzimy kolejny wyjątek.

There is no Action mapped for namespace / and action name helloWorld. - [unknown location]
        at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:189)
        at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
        at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
        at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:475)
        at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
        at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:619)

Tym razem okazuje się że plik struts.xml powinien znajdować się w /WEB-INF/classes/ a nie tak jak teraz bezpośrednio w /WEB-INF/

 

Po tej poprawce projekt uruchomi się poprawnie. Mam nadzieję że wpis pomoże jakiemuś początkującemu programiście 🙂 Jeśli ktoś miałby jakieś uwagi to chętnie je poznam 🙂

Spring Framework 3 + SiteMesh 3 – pierwsze starcie

2 czerwca 2010 17 komentarzy

Po dłuższej przerwie czas wrócić do pisania 🙂 Wprawdzie praca magisterska jeszcze nie skończona ale jest trochę luźniej i czas na jakiś mądry 😉 wpis.

Ostatnio jeden blogerów Darek Zoń zaczął na swoim blogu pisać tutorial o tworzeniu aplikacji w Spring Framework z wykorzystaniem SiteMesh i Hibernate. Zainteresowałem się tematem i podzielę się się wrażeniami z pierwszego starcia z tymi narzędziami.

Swój projekt rozpocząłem w NetBeans 6.9 RC 2 (ma wsparcie dla Spring Framework 3, do projektu są automatycznie dodane biblioteki wersji 3.0.2). Do utworzenia aplikacji konieczne jest pobranie biblioteki SiteMesh (wersja alpha).

Standardowo tworzymy nowy projekt wykonując następujące kroki

  • New project
  • Java Web -> WebApplication
  • serwer może być domyślny (Apache)
  • zaznaczamy Spring Web MVC i w konfiguracji wybieramy wersję 3

W związku z tym że nowy Spring Framework pozwala na tworzenie kontrolerów poprzez adnotację @Controller w pliku konfiguracyjnym trzeba dodać odpowiednie opcje które na to pozwolą.

W pliku dispatcher-servlet.xml należy dodać poniższy kod:

</span></span>
<pre><pre><context:component-scan base-package="eu.ryznar.controller" />
<context:annotation-config />
<context:spring-configured />

Próba umieszczenia takiego projektu na serwerze zwróci wyjątek w postaci (fragment):

org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 13 in XML document from ServletContext resource [/WEB-INF/dispatcher-servlet.xml] is invalid; nested exception is org.xml.sax.SAXParseException: The prefix "context" for element "context:component-scan" is not bound.
.
.
.
Caused by: org.xml.sax.SAXParseException: The prefix "context" for element "context:component-scan" is not bound.
.
.
.
2010-06-02 12:25:23 org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /WebApp1 threw load() exception
org.xml.sax.SAXParseException: The prefix "context" for element "context:component-scan" is not bound.

Aby się tego „pozbyć” w tym samym pliku w sekcji beans należy dodać:

xmlns:context="http://www.springframework.org/schema/context"

Oraz do xsi:schemaLocation dopisać:

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd

Teraz można dodać kontroler we wskazanej wcześniej paczce:

package eu.ryznar.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

    @RequestMapping(value="/index")
    public ModelAndView index() {
        ModelAndView mv = new ModelAndView("hello");

        return mv;
    }
}

oraz utworzyć plik hello.jsp w katalogu /WEB-INF/jsp:

<html>
  <head>
    <title>Hello World</title>
    <meta name='description' content='A simple page'>
  </head>
  <body>
    <p>Hello <strong>world</strong>!</p>
  </body>
</html>

Próba uruchomienia takiej aplikacje rzuca kolejny wyjątek (fragment):

java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException
.
.
.
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.NoAspectBoundException
.
.
.
2010-06-01 22:43:05 org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /WebApp1 threw load() exception
java.lang.ClassNotFoundException: org.aspectj.lang.NoAspectBoundException

Brakuje nam biblioteki AspectJ. Należy ją pobrać ze strony http://eclipse.org/aspectj .
Pobrany plik należy wypakować, i do bibliotek tworzonego projektu dodać plik jar: aspectjrt.jar.

Teraz można uruchomić aplikację, i po wpisaniu adresu (port zależny od serwera) http://localhost:8084/WebApp1/index.html strona zostanie wyświetlona poprawnie.

Czas na SiteMesh. Do bibliotek projektu należy dodać pobrane archiwum jar.
Działania SiteMesh nie będę omawiał, pokażę tylko konfigurację. Autor wskazanego bloga użył konfiguracji opartej o klasę Java, mi jednak udało się z samą konfiguracją xml. Tzn. w pliku web.xml dodajemy odpowiednie filtry:

  <filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

I dodatkowo tworzymy plik sitemesh3.xml (w tej samej ścieżce co web.xml) o następującej zawartości:

<?xml version="1.0" encoding="UTF-8"?>
<sitemesh>
  <mapping path="/*" decorator="/WEB-INF/jsp/decorator.jsp"/>
</sitemesh>

Plik który widnieje w konfiguracji decorator.jsp trzeba stworzyć we wskazanej ścieżce. Odgrywa on rolę szablonu, wg którego budowane są podstrony. Przykładowa zawartość pliku.

<html>
  <head>
    <title>SiteMesh example: <sitemesh:write property='title'/></title>
    <style type='text/css'>
      /* Some CSS */
      body { font-family: arial, sans-serif; background-color: #ffffcc; }
      h1, h2, h3, h4 { text-align: center; background-color: #ccffcc; border-top: 1px solid #66ff66; }
      .mainBody { padding: 10px; border: 1px solid #555555; }
      .disclaimer { text-align: center; border-top: 1px solid #cccccc; margin-top: 40px; color: #666666; font-size: smaller; }
    </style>
    <sitemesh:write property='head'/>
  </head>
  <body>

    <h1 class='title'>SiteMesh example site: <sitemesh:write property='title'/></h1>

    <div class='mainBody'>
      <sitemesh:write property='body'/>
    </div>

    <div class='disclaimer'>Site disclaimer. This is an example.</div>

  </body>
</html>

To wszytko. Można odświeżyć wcześniej uruchomioną stronę i zobaczymy ładnie sformatowaną stronę z „Hello World”.

Jeśli coś źle napisałem będę wdzięczny za uwagi.

JSF i EJB 3 – prosta aplikacja CRUD

30 października 2009 7 komentarzy

Tutorial do którego dzisiaj się odniosę to prosta aplikacja webowa wykonana w środowisku Netbeans z wykorzystaniem JSF, EJB 3 oraz bazy danych (autor wykorzystuje PostgreSQL, ja miałem pod ręką MySQL – ale w tym przypadku baza nie robi różnicy).

Tutorial składa się z trzech części: pierwsza druga i trzecia

U mnie problemy zaczęły się w trzeciej części, w drugim kroku „Add fields to the User Entity Bean”
Po dodaniu nowych pól do bazy i klasy aplikacja przestała działać – pojawił sie wyjątek, już nie pamiętam dokładnie co tam pisało 😛 ale jakiś problem z PU i odnalezieniem klasy UserDAOBean.
Jak sobie z tym poradziłem? W części webowej aplikacji, z gałęzi „Libraries” usunąłem JumpStartEjbJsf-ejb.jar i dodałem go jeszcze raz. Czy można inaczej, nie wiem. Jeśli ktoś ma pomysł proszę o podpowiedź.

Ale to nie koniec. Kolejny problem to kroki 3-7. Po dodaniu do gałęzi „Libraries” podanych bibliotek Apache Commons Lang, Apache Commons Validator oraz Jakarta Oro, i próbie dodania użytkownika z błędnym mejlem dostałem taki wyjątek


codjava.lang.NoClassDefFoundError: org/apache/commons/validator/EmailValidator

to samo z lang/StringUtils. Oczywiście wujek Google prawie zawsze pomaga, no i tutaj podpowiada żeby te pliki *jar wrzucić do katalogu /WEB-INF/lib – pomogło.

Jednak walidacja mejla nadal sypie wyjątkami, tym razem


javax.servlet.ServletException: Uncompilable source code.

Problem leży w klasie EmailValidator, nie ma takiej metody jak


htmlInputText.getLabel()

Oczywiście znowu google, przeglądanie API i taki przebłysk, skąd w gałęzi „Libraries” mam MyFaces? Okazuje się że podczas dodawania JSF do projektu z menu „Properties”, w zakładce „Libraries” opcja „Registered Libraries” domyślnie wybrane jest „Facelets 1.1.14 MyFaces”. W związku z tym usunąłem te pliki jar, i z menu kontekstowego „Add Library…” wybrałem JSF 1.2.

Co się okazuje, tu metoda getLabel() jest, i poprzedni problem również znika, tzn można usunąć katalog /lib z WEB-INF i wszystko ładnie działa.

Źródeł nie zamieszczam, w przytoczonym tutorialu źródła są pełne, więc przerabiajac go nic nam nie umknie 🙂
Mam nadzieję że nie ma jakiś strasznych herezji w tym artykule 😉 jeśli są proszę o zwrócenie mi uwagi.

Pozdrawiam

Ajax w GWT – pogodynka

24 października 2009 4 komentarze

Czas na pierwszy, konkretny wpis. Jako że chciałem mniej więcej zobaczyć GWT, wygrzebałem link z moich zakładek na delicious: Ajax for Java developers: Exploring the Google Web Toolkit

Wpis z 2006, kilka metod przestarzałych, no i oczywiście aplikacja nie działa z nową biblioteką HTTP Components.

Informacja: W tym i kolejnych artykułach nie będę się rozpisywał o technologii, szkoda czasu na bawienie się w tłumacza i przepisywanie tego co już jest napisane, więc w razie potrzeby będę odsyłał do innych artykułów.

Potrzebujemy:

Krótki tutorial na temat używania Netbeans i GWT można znaleźć tutaj

Tworzymy nowy projekt „Java WebApplication” na liście frameworków wybieramy „Google Web Toolkit”. Do bibliotek dodajemy paczki httpclient-4.0.jar , httpcore-4.0.1.jar oraz commons-logging-1.1.1.jar. Po przeczytaniu artykułu na którym bazuję idziemy dalej.

Na początek zmiany w kodzie mające na celu usunięcie przestarzałych metod [w klasie Weather].

Najważniejsze zmiany to kod odpowiedzialny za przechwytywanie zdarzeń.

Czyli naciśnięcie klawisza ENTER zmieniamy z

txBox.addKeyboardListener(new KeyboardListenerAdapter(){
    public void onKeyPress(Widget sender, char keyCode, int modifiers) {
        if ((keyCode == 13) && (modifiers == 0)) {
            validateAndSubmit();
        }
    }
});

na

 txBox.addKeyPressHandler(new KeyPressHandler() {
    public void onKeyPress(KeyPressEvent event) {
        if ((event.getCharCode() == KeyCodes.KEY_ENTER) && (event.isAnyModifierKeyDown() == false)) {
            validateAndSubmit();
        }
    }
});

wykrycie kliku lewego przycisku myszy z

 Button btn = new Button("Submit", new ClickListener() {
    public void onClick(Widget sender) {
       validateAndSubmit();
    }
});

na poniższy kod

 Button btn = new Button("Submit", new ClickHandler() {
    public void onClick(ClickEvent event) {
        validateAndSubmit();
    }
});

w kilku miejscach znajdziemy też

ucRadio.setChecked(true)
ucRadio.isChecked();

i zmieniamy odpowiednio na

ucRadio.setValue(true)
ucRadio.getValue();

Reszta zmian, to dostosowanie aplikacji do nowej wersji bibliotek Apache HTTP Components [v.4].
W klasie YahooWeatherServiceImpl zmieniamy ciało funkcji getWeatherRssDocument() z:

String url = getRequestUrl(zip, isCelsius);

 HttpClient client = new HttpClient();
 GetMethod get = new GetMethod(url);
 try {
    int resultCode = client.executeMethod(get);
    log.debug("HTTP response: "+resultCode);

    if (resultCode == 200) {
       InputStream in = get.getResponseBodyAsStream();

       DocumentBuilder builder = builderFactory.newDocumentBuilder();
       return builder.parse(in);
    } else {
         throw new IOException("HTTP Communication problem, response code: "+resultCode);
      }

 } finally {

 get.releaseConnection();
 }

na następujący kod:

String url = getRequestUrl(zip, isCelsius);

 HttpClient client = new DefaultHttpClient();
 HttpGet get = new HttpGet(url);
 try {

 HttpResponse response = (HttpResponse) client.execute(get);
 int resultCode = response.getStatusLine().getStatusCode();
 log.debug("HTTP response: " + resultCode);
 HttpEntity entity = response.getEntity();
 if (resultCode == HttpStatus.SC_OK) {
 InputStream in = entity.getContent();

 DocumentBuilder builder = builderFactory.newDocumentBuilder();
 return builder.parse(in);
 } else {
 throw new IOException("HTTP Communication problem, response code: " + resultCode);
 }

 } finally {
 // Process the data from the input stream.
 }

To wszystko. Aplikacja działa 🙂 pokazuje pogodę [przykładowy kod pocztowy 90210].
Źródło aplikacji dostępne jest tutaj

Jeśli ktoś ma jakieś pytania co i jak, lub sugestie odnośnie lepszych rozwiązań zapraszam do komentowania 🙂