Recent Posts
Archives

Posts Tagged ‘GWT’

PostHeaderIcon Useful DTD

DTDs are useful when your XML editor take them in account: detecting errors, suggestions, complete statements… For instance, I save much time with IntelliJ IDEA automatic completion ; unlike, Eclipse amazingly does not implement this feature.

Here is a list of some widely used DTDs:

File DTD
weblogic-application.xml [xml]<!DOCTYPE weblogic-application PUBLIC "-//BEA Systems, Inc.//DTD WebLogic Application 7.0.0//EN" "http://www.oracle.com/technology/weblogic/weblogic-application/1.1/weblogic-application.xsd">[/xml]
weblogic-application.xml [xml]<!DOCTYPE weblogic-application PUBLIC "-//BEA Systems, Inc.//DTD WebLogic Application 7.0.0//EN" "http://www.oracle.com/technology/weblogic/weblogic-application/1.1/weblogic-application.xsd">[/xml]
web.xml [xml]<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >[/xml]
*.hbm.xml [xml]<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">[/xml]
GWT modules [xml]<!DOCTYPE module SYSTEM "http://google-web-toolkit.googlecode.com/svn/trunk/distro-source/core/src/gwt-module.dtd">[/xml]
GWT UI [xml]<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">[/xml]
Tangosol / Oracle Coherence [xml]<!DOCTYPE coherence SYSTEM "coherence.dtd">[/xml]
Log4J [xml]<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">[/xml]

Tangosol and Log4J DTDs are included within their distribution JARs: you have to extract them or to give their path to IntelliJ IDEA.

PostHeaderIcon GWT / Sonar / Cannot invoke clone() on the array type… / The user-supplied array … is stored directly

I have to fix all critical “Violations” owing to Sonar.
Let’s consider a basic block:
[java] public void setSushis(float[] sushis) {
this.sushis = sushis;
}[/java]
This piece of code raises this error in Sonar:
[java] Security – Array is stored directly : The user-supplied array ‘sushis’ is stored directly.[/java]
In a naive step, I modified the code as this:
[java] public void setSushis(float[] sushis) {
this.sushis = sushis.clone();
}[/java]
This may have been OK… but, now, I get the following error within GWT compilation:
[java]Cannot invoke clone() on the array type float[][/java]

To fix the issue, I amended the code as follows:
[java] public void setSushis(float[] theSushis) {
this.sushis= new float[theSushis.length];
System.arraycopy(theSushis, 0, this.sushis, 0, theSushis.length);
}[/java]

Disclaimer: even though I followed Sonar’s advice and requirements, I am a little skeptic about this kind of “violation”. 😐

PostHeaderIcon Tutorial: an Event Bus Handler for GWT / GXT

Overview

Introduction

Let’s consider a application, JonathanGwtApplication, divided in three main panels

  • a panel to select animal name name
  • a panel to display, expand and collapse trees of the animal ancestors
  • a panel of information to display many indicators (colors, ages, etc.).

An issue we encounter is: how to make the different panels communicate? In more technical terms, how to fire events from a panel to another one?

A first solution would be to declare each panel as listener to the other panels. Indeed, this principle may go further, and declare each component as listener to a list of other components…
Main drawbacks:

  • the code becomes hard to read
  • adding or removing a component requires to modify many parts of the code
  • we don’t follow GWT 2’s “philosophy”, which is to use Handlers rather than Listeners.

Hence, these reasons incited us to provide a global EventBusHandler.

The EventBusHandler concept

The EventBusHandler is a global bus which is aware of all events that should be shared between different panels, and fires them to the right components.
The EventBusHandler is a field of JonathanGwtApplicationContext.

Intrastructure

  • lalou.jonathan.application.web.gwt.animal.events.HandledEvent: generic interface for a event. Abstract method:
    [java]EventTypeEnum getEventEnum();[/java]
  • lalou.jonathan.application.web.gwt.animal.handler.EventHandler: generic interface for a component able to handle an event. Abstract method:
    [java]void handleEvent(HandledEvent handledEvent);[/java]
  • lalou.jonathan.application.web.gwt.animal.handler.EventHandlerBus: the actual bus. As a concrete class, it has two methods:
    [java]/**
    * Fires an event to all components declared as listening to this event
    * event type.
    *
    * @param baseEvent
    */
    public void fireEvent(HandledEvent baseEvent) {
    // …
    }

    /**
    * Adds an listener/handler for the event type given as parameter
    *
    * @param eventTypeEnum
    * @param eventHandler
    * @return The List of handlers for the key given as parameter. This list
    * contains the eventHandler that was given as second parameter
    */
    public List<EventHandler> put(EventTypeEnum eventTypeEnum,
    EventHandler eventHandler) {
    // …
    }[/java]

How to use the bus?

  1. Define an event: in JonathanGwtApplication, an event is decribed by two elements:
    • a functionnal entity: eg: “animal”, “food”, “tree node”. The functionnal entity must be isomorph to a technical DTO, eg: AnimalDTO for an entity Animal.(in the scope of this turoriel we assume to have DTOs, even though the entities may ne sufficient)
    • a technical description of the event: “selection changed”, “is expanded”
  2. Add an entry in the enum EventTypeEnum. Eg: “ANIMAL_SELECTION_CHANGED
  3. in lalou.jonathan.application.web.gwt.animal.events, create an event, implementing HandledEvent and its method getEventEnum(). The match between EventTypeEnum and DTO is achieved here. Eg:
    [java]public class AnimalSelectionChangedEvent extends
    SelectionChangedEvent<AnimalDTO> implements HandledEvent {

    public AnimalSelectionChangedEvent(
    SelectionProvider<AnimalDTO> provider,
    List<AnimalDTO> selection) {
    super(provider, selection);
    }

    public EventTypeEnum getEventEnum() {
    return EventTypeEnum.ANIMAL_SELECTION_CHANGED;
    }

    }[/java]

  • When an event that should interest other component is fired, simply call the bus. The bus will identify the event type and dispatch it to the relevant handlers. eg:
    [java]animalComboBox.addSelectionChangedListener(new SelectionChangedListener<AnimalDTO>() {

    @Override
    public void selectionChanged(SelectionChangedEvent<AnimalDTO> se) {
    final AnimalDTO selectedAnimalVersion;
    selectedAnimalVersion= se.getSelectedItem();
    JonathanGwtApplicationContext.setSelectedAnimal(selectedAnimal);

    final AnimalSelectionChangedEvent baseEvent = new AnimalSelectionChangedEvent(
    se.getSelectionProvider(), se.getSelection());
    JonathanGwtApplicationContext.getEventHandlerBus()
    .fireEvent(baseEvent);

    }
    });[/java]

  • Handlers:
    • easy case: the component handles only one type of event: this handler must implement the right interface (eg: AnimalSelectionChangedEventHandler) and its method, eg:
      [java]protected void handleAnimalSelectionChangedEvent(HandledEvent handledEvent) {
      return;
      }[/java]
    • frequent case: the component handles two or more event types. No matter, make the component implement all the needed interfaces (eg: AnimalSelectionChangedEventHandler, FoodSelectionChangedEventHandler). Provide a unique entry point for the method to implement, which is common to both interfaces. Retrieve the event type, and handle it with ad hoc methods. Eg:
      [java]public void handleEvent(HandledEvent handledEvent) {
      final EventTypeEnum eventTypeEnum;

      eventTypeEnum = handledEvent.getEventEnum();

      switch (eventTypeEnum) {
      case ANIMAL_SELECTION_CHANGED:
      handleAnimalSelectionChangedEvent(handledEvent);
      return;
      case FOOD_SELECTION_CHANGED:
      handleFoodSelectionChangedEvent(handledEvent);
      return;
      default:
      break;
      }
      }

      protected void handleAnimalSelectionChangedEvent(HandledEvent handledEvent) {
      // do something
      }
      protected void handleFoodSelectionChangedEvent(HandledEvent handledEvent) {
      // do something else
      }[/java]

  • PostHeaderIcon Dynamic serviceUrl with Spring’s HttpInvokerProxyFactoryBean

    Abstract

    How to set dynamically the URL used by a HttpInvokerProxyFactoryBean in a Spring-deployed WAR?

    Detailed Case

    I have to deploy a GWT/GXT application, calling two distant services:
    a remote EJB
    a service accessed through Spring Remoting

    Here is the Spring configuration file I firstly used:

    [xml]
    <util:properties id="jndiProperties" location="classpath:jndi.properties"/>
    <jee:remote-slsb id="myRemoteEJBService" jndi-name="ejb.remote.myRemoteService"
    business-interface="lalou.jonathan.myRemoteEJBService"
    environment-ref="jndiProperties" cache-home="false"
    lookup-home-on-startup="false" refresh-home-on-connect-failure="true" />

    <bean id="mySpringRemoteService"
    class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
    <property name="serviceInterface"
    value="lalou.jonathan.services.mySpringRemoteService" />
    <property name="serviceUrl" value="${spring.remote.service.url}"/>
    </bean>
    [/xml]

    Unhappily, even though the remote EJB is retrieved (which proves that the jndi file is available in the classpath and rightly loaded), the Spring Remote service is not. I had to write the URL in hard in the configuration file… This is not very efficient when you work in a large team, with different production and testings environments!

    This is the log when myRemoteEJBService bean is loaded:
    [java]2010-08-17 16:05:42,937 DEBUG support.DefaultListableBeanFactory – Creating shared instance of singleton bean ‘myRemoteEJBService’
    2010-08-17 16:05:42,937 DEBUG support.DefaultListableBeanFactory – Creating instance of bean ‘myRemoteEJBService’
    2010-08-17 16:05:42,937 DEBUG support.DefaultListableBeanFactory – Eagerly caching bean ‘myRemoteEJBService’ to allow for resolving potential circular references
    2010-08-17 16:05:42,937 DEBUG support.DefaultListableBeanFactory – Returning cached instance of singleton bean ‘jndiProperties’
    2010-08-17 16:05:42,937 DEBUG support.DefaultListableBeanFactory – Invoking afterPropertiesSet() on bean with name ‘myRemoteEJBService’
    2010-08-17 16:05:42,937 DEBUG framework.JdkDynamicAopProxy – Creating JDK dynamic proxy: target source is EmptyTargetSource: no target class, static
    2010-08-17 16:05:42,953 DEBUG support.DefaultListableBeanFactory – Finished creating instance of bean ‘myRemoteEJBService'[/java]

    That is the log when mySpringRemoteService is loaded:
    [java]2010-08-17 16:05:42,968 DEBUG support.DefaultListableBeanFactory – Creating shared instance of singleton bean ‘mySpringRemoteService’
    2010-08-17 16:05:42,968 DEBUG support.DefaultListableBeanFactory – Creating instance of bean ‘mySpringRemoteService’
    2010-08-17 16:05:42,984 DEBUG support.DefaultListableBeanFactory – Eagerly caching bean ‘mySpringRemoteService’ to allow for resolving potential circular references
    2010-08-17 16:05:43,234 DEBUG support.DefaultListableBeanFactory – Invoking afterPropertiesSet() on bean with name ‘mySpringRemoteService’
    2010-08-17 16:05:43,250 DEBUG framework.JdkDynamicAopProxy – Creating JDK dynamic proxy: target source is EmptyTargetSource: no target class, static
    2010-08-17 16:05:43,250 DEBUG support.DefaultListableBeanFactory – Finished creating instance of bean ‘mySpringRemoteService'[/java]

    You can notice that no mention to jndiProperties appears. Here is the key of the problem: jndiProperties is considered as a bean among others, which cannot be accessed easyly from the HttpInvokerProxyFactoryBean.

    Fix

    To fix the issue, you have to add an actual property holder in Spring XML configuration file, ie after:

    [xml]<util:properties id="jndiProperties" location="classpath:jndi.properties"/>[/xml]

    add an instanciation of PropertyPlaceholderConfigurer:

    [xml]<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:jndi.properties"/>
    </bean>[/xml]

    PostHeaderIcon GWT in noserver mode with Tomcat or WebLogic

    Abstract

    You would like to work on the client side of your GWT application, without building and deploying the Jetty server. Or, in the same way, you need test some server features available in WebLogic but not in Jetty, such as the EJB.
    GWT 2.0 documentation, at the segment How do I use my own server in hosted mode instead of GWT’s built-in Jetty instance? is not precise at all on the 3rd step: it simply states:

    “change the URL at the end of the argument list to match the URL you recorded in step #1.”

    Process

    • Let’s assume your WAR is deployed on http://distantMachine:8080/myApplication. The servlet container may be Tomcat or WebLogic, it does not matter
    • In Eclipse, go in “Run Configuration...“. Duplicate your current and classic GWT application configuration.
    • Go in Server , uncheck “Run built-in server“.
    • In Arguments tab, write the following line:
      [java]-noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -war C:\eclipse\workspace\myApplication\src\main\webapp\lalou.jonathan.web.gwt.MyApplication -startupUrl http://distantMachine:8080/myApplication lalou.jonathan.web.gwt.MyApplication[/java]
    • Run
    • The application is available at the following address:
      [html]http://distantMachine:8080/muyApplication/?gwt.codesvr=127.0.0.1:9997[/html]

    PostHeaderIcon No source code is available for type org.junit.Assert; did you forget to inherit a required module?

    Case

    You run a GWT application, with a a service layer. Those services are tested through unit tests, which may use EasyMock, among other frameworks. Of course, you hinted at related jars, such us JUnit, by a <scope>test</scope> in your pom.xml.

    Yet, when you run the GWT application with a Jetty light container, you get the following message:

    Compiling module lalou.jonathan.gwt.client.MyModule

    Validating newly compiled units

    [java][ERROR] Errors in ‘file:/C:/eclipse/workspace/…/test/unit/lalou/jonathan/gwt/client//MyServiceUnitTest.java’
    [ERROR] Line 26: No source code is available for type org.easymock.MockControl; did you forget to inherit a required module?
    [ERROR] Line 76: No source code is available for type org.junit.Assert; did you forget to inherit a required module?[/java]

    Fix

    Since Maven2 and GWT scopes are fully independant, you have to modify you *.gwt.xml. Replace:

    [xml] &lt;source path=’client’/&gt;[/xml]

    with:

    [xml]&lt;source path=’client’ excludes=&quot;**/*UnitTest.java,**/*RuntimeTest.java&quot;/&gt;[/xml]

    NB: Never forget that Google teams work with Ant, and not with Maven!

    PostHeaderIcon No source code is available for type … ; did you forget to inherit a required module?

    Context

    In a GWT application, you have to use RPC calls, using entities which are package in external jar archives. With Eclipse, no error appears ; yet when you build the project with Maven2, you get this message:

    [java][INFO] [ERROR] Errors in ‘file:/C:/eclipse/workspace/myGwtProject/src/java/com/lalou/jonathan/web/gwt/client/component/JonathanPanel.java’
    (…)
    [INFO] [ERROR] Line 24: No source code is available for type com.lalou.jonathan.domain.MyEntity; did you forget to inherit a required module?
    (…)
    [INFO] Finding entry point classes[/java]

    Fix

    In related jar

    In the project to which MyEntity belongs to (here: my/depended/project):

    • create a file com/lalou/jonathan/MyDependedProject.gwt.xml, with as content:

      [xml]<module>
      <source path="">
      <include name="**/MyEntity.java"/>
      </source>
      </module>[/xml]

    • In the pom.xml:
      • Add the source MyEntity.java in built jar. This way, the Java file itself will be considered as a resource, like an XML or property file. To perform this, the quickest manner is to add the following block in the pom.xml:
        [xml]<resources>
        <resource>
        <directory>${basedir}/src/java</directory>
        <includes>
        <include>**/MyEntity.java</include>
        </includes>
        </resource>
        </resources>[/xml]
      • Add an <include>**/*.gwt.xml</include> so that to have to MyDependedProject.gwt.xml file in the built jar.

      In GWT project

      In your *.gwt.xml file, add the dependency:

      [xml]<inherits name=’com.lalou.jonathan.MyDependedProject’ />[/xml]

      Caution!

      All these operations need be done on all dependencies -either direct or indirect-. Therefore, possibly you may have a huge amount of code to be got.
      Another issue appears when you use a jar of which you do not have the source code, such as in the case of tiers API for instance.

    PostHeaderIcon GWT: call a remote EJB with Spring lookup

    Abstract

    Let’s assume you have followed the article “Basic RPC call with GWT“. Now you would like to call an actual EJB 2 as remote, via a Spring lookup.
    Let’s say: you have an EJB MyEntrepriseComponentEJB, which implements an interface MyEntrepriseComponent. This EJB, generates a remote MyEntrepriseComponentRemote.

    Entry Point

    In myApplication.gwt.xml entry point file, after the line:

    [xml]<inherits name=’com.google.gwt.user.User’/>[/xml]

    add the block:

    [xml]
    <inherits name=’com.google.gwt.user.User’ />
    <inherits name="com.google.gwt.i18n.I18N" />
    <inherits name="com.google.gwt.http.HTTP" />[/xml]

    Add the line:

    [xml]<servlet path=’/fooService.do’/>[/xml]

    Client

    Under the *.gwt.client folder:

    Update the service interface. Only the annotation parameter is amended:

    [java]@RemoteServiceRelativePath("services/fooService")
    public interface FooService extends RemoteService {
    public String getHelloFoo(String fooName);
    }[/java]

    You have nothing to modify in asynchronous call interface (FooServiceAsync).

    Server

    Under the *.gwt.server folder, update the implementation for service interface:

    Change the super-class, replacing RemoteServiceServlet with GWTSpringController:

    [java]public class FooServiceImpl extends GWTSpringController implements FooService {
    public FooServiceImpl() {
    // init
    }
    }
    [/java]

    Add new field and its getter/setter:

    [java]// retrieved via Spring
    private myEntrepriseComponent myEntrepriseComponent;

    public myEntrepriseComponent getMyEntrepriseComponent() {
    return myEntrepriseComponent;
    }

    public void setmyEntrepriseComponent(myEntrepriseComponent _myEntrepriseComponent) {
    myEntrepriseComponent = _myEntrepriseComponent;
    }[/java]

    Write the actual call to EJB service:

    [java]
    public String getHelloFoo(String fooName) {
    return myEntrepriseComponent.getMyDataFromDB();
    }
    }[/java]

    web.xml

    Fill the web.xml file:

    [xml]<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>

    <!– Spring –>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
    <servlet-name>gwt-controller</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>gwt-controller</servlet-name>
    <url-pattern>/myApplication/services/*</url-pattern>
    </servlet-mapping>

    <!– Default page to serve –>
    <welcome-file-list>
    <welcome-file>MyApplicationGwt.html</welcome-file>
    </welcome-file-list>

    </web-app>
    [/xml]

    JNDI

    Add a jndi.properties file in src/resources folder:

    [java]
    java.naming.provider.url=t3://localhost:12345
    java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
    java.naming.security.principal=yourLogin
    java.naming.security.credentials=yourPassword
    weblogic.jndi.enableDefaultUser=true[/java]

    These properties will be used by Spring to lookup the remote EJB. The last option is very important, otherwise you may happen to face issues with EJB if they were deployed under WebLogic.

    WEB-INF

    In the WEB-INF folder, add an applicationContext.xml file:

    [xml]<?xml version="1.0" encoding="UTF-8"?>
    <beans>

    <util:properties id="jndiProperties" location="classpath:jndi.properties" />

    <jee:remote-slsb id="myEntrepriseComponentService"
    jndi-name="ejb.jonathan.my-entreprise-component"
    business-interface="lalou.jonathan.myApplication.services.myEntrepriseComponent"
    environment-ref="jndiProperties" cache-home="false"
    lookup-home-on-startup="false" refresh-home-on-connect-failure="true" />

    </beans>[/xml]

    Add a gwt-controller-servlet.xml file:

    [xml]<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <bean>
    <property name="order" value="0" />
    <property name="mappings">
    <value>
    /fooService=fooServiceImpl
    </value>
    </property>
    </bean>

    <bean id="fooServiceImpl"
    class="lalou.jonathan.myApplication.web.gwt.server.FooServiceImpl">
    <property name="myEntrepriseComponent" ref="myEntrepriseComponentService" />
    </bean>
    </beans>
    [/xml]

    Of course, if your servlet mapping name in web.xml is comoEstasAmigo, then rename gwt-controller-servlet.xml as comoEstasAmigo-servlet.xml 😉

    Build and deploy

    Now you can compile, package your war and deploy under Tomcat or WebLogic. WebLogic server may raise an error:
    java.rmi.AccessException: [EJB:010160]Security Violation: User: '<anonymous>' has insufficient permission to access EJB
    This error is related to the rights required to call a method on the EJB. Indeed, two levels of rights are used by WebLogic: firstly to lookup / instanciate the EJB (cf. the property java.naming.security.principal we set sooner), and another to call the method itself. In this second case, WebLogic requires an authentication (think of what you do when you login an web application deployed: your login and rights are kept for all the session) to grant the rights. I wish to handle this subject in a future post.

    NB: thanks to David Chau and Didier Girard from SFEIR, Sachin from Mumbai team and PYC from NYC.

    PostHeaderIcon WebLogic deployment automatization with Maven and/or Ant

    Case

    I had to automatize the deployment of a basic GWT application, packaged as a WAR archive, on a WebLogic 9.2 server.

    Maven 2

    Mojo Plugin

    Firstly, I tried to use Mojo’s maven plugin for Weblogic. I had to add some lines in my pom.xml, almost identical to those available in Mojo’s documentation.

    The main issue I encountered was to retrieve the jars mandatory to the plugin, and install them in my local Maven repository. Since the missing jars names given by Maven are not so obvious, here are the paths to retrieve these jars, all included with WebLogic 9.2 installation:

    [java]mvn install:install-file -DgroupId=weblogic -DartifactId=xbean -Dversion=9.2 -Dpackaging=jar -Dfile=%BEA_HOME%\server\lib\wlxbean.jar
    mvn install:install-file -DgroupId=weblogic -DartifactId=wlw-langx -Dversion=9.2 -Dpackaging=jar -Dfile=%BEA_HOME%\server\lib\wlw-langx.jar
    mvn install:install-file -DgroupId=weblogic -DartifactId=wlw-util -Dversion=9.2 -Dpackaging=jar -Dfile="%BEA_HOME%\common\lib\wlw-util.jar"
    mvn install:install-file -DgroupId=weblogic -DartifactId=bcel -Dversion=5.1 -Dpackaging=jar -Dfile="%BEA_HOME%\javelin\lib\bcel-5.1.jar"
    mvn install:install-file -DgroupId=weblogic -DartifactId=javelinx -Dversion=9.2 -Dpackaging=jar -Dfile="%BEA_HOME%\javelin\lib\javelinx.jar"
    mvn install:install-file -DgroupId=weblogic -DartifactId=weblogic-container-binding -Dversion=9.2 -Dpackaging=jar -Dfile="%BEA_HOME%\server\lib\schema\weblogic-container-binding.jar"[/java]

    Issues

    Once this issue fixed, I tried to launch the deployment (with mvn weblogic:deploy). But I encountered the following error:
    Response: '404: Not Found' for url: 'http://localhost:7070/bea_wls_deployment_internal/DeploymentService'
    Complete stacktrace in debug and verbose mode:

    [java]weblogic.deploy.api.internal.utils.DeployerHelperException: The source ‘C:\LOCALS~1\Temp\appliGWT-1.0-SNAPSHOT.war’ for the application ‘iVarGwt’ could not be loaded to the server ‘http://localhost:7070/bea_wls_deployment_internal/DeploymentService’.
    Response: ‘404: Not Found’ for url: ‘http://localhost:7070/bea_wls_deployment_internal/DeploymentService’
    at weblogic.deploy.api.internal.utils.JMXDeployerHelper.uploadSource(JMXDeployerHelper.java:658)
    at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.upload(ServerConnectionImpl.java:653)
    at weblogic.deploy.api.spi.deploy.internal.BasicOperation.uploadFiles(BasicOperation.java:319)
    at weblogic.deploy.api.spi.deploy.internal.BasicOperation.execute(BasicOperation.java:411)
    at weblogic.deploy.api.spi.deploy.internal.BasicOperation.run(BasicOperation.java:169)
    at weblogic.deploy.api.spi.deploy.WebLogicDeploymentManagerImpl.deploy(WebLogicDeploymentManagerImpl.java:369)
    at weblogic.deploy.api.tools.deployer.DeployOperation.execute(DeployOperation.java:47)
    at weblogic.deploy.api.tools.deployer.Deployer.perform(Deployer.java:139)
    at weblogic.deploy.api.tools.deployer.Deployer.runBody(Deployer.java:88)
    at weblogic.utils.compiler.Tool.run(Tool.java:158)
    at weblogic.utils.compiler.Tool.run(Tool.java:115)
    at weblogic.Deployer.run(Deployer.java:70)
    at org.codehaus.mojo.weblogic.DeployMojoBase.executeDeployer(DeployMojoBase.java:510)
    at org.codehaus.mojo.weblogic.DeployMojo.execute(DeployMojo.java:49)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
    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:585)
    at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
    at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:375)[/java]

    Deploying another application worked, deploying my application using WebLogic console worked too… After many hours of search, I gave up Maven2 way.

    Ant

    After retiring from using Mojo’s plugin, I used a way I feared would be less elegant: Ant.

    Indeed, Ant script is very short and efficient:

    [xml]<?xml version="1.0" encoding="UTF-8"?>

    <project name="redeploy" basedir="." default="deploy">
    <property file="redeploy.properties" />

    <target name="init-weblogic-task">
    <available file="${env.WL_HOME}/server/lib/weblogic.jar"
    property="weblogic-jar.present" />
    <fail unless="weblogic-jar.present">${env.WL_HOME}/server/lib/weblogic.jar does not
    exist</fail>

    <taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy"
    classpath="${env.WL_HOME}/server/lib/weblogic.jar" />
    </target>

    <target name="deploy" depends="init-weblogic-task">
    <wldeploy action="deploy" source="${source}"
    name="${name}" user="${user}" password="${password}" verbose="true"
    adminurl="${adminurl}" debug="true" targets="${targets}" upload="true"
    securitymodel="${securitymodel}" stage="stage" />
    </target>

    </project>[/xml]

    In the same folder, I created a property file, gathering the properties hinted at in Ant build.xml.

    [java]env.WL_HOME=C:/bea/weblogic_9_2
    adminurl=t3://localhost:7070
    name=appliGWT
    user=weblogic
    password=myPassword
    targets=myTarget
    securitymodel=Advanced
    source=../../../target/appliGWT-1.0-SNAPSHOT.war
    [/java]

    I launched Ant and the deployment was successful.

    Maven anyway, but with Ant

    Yet, since I build with Maven, I do not want to have to build, change folder, and then deploy: I want a unique command line to package and deploy. To perform that, I added a profile in my pom.xml, using a Maven plugin to call Ant tasks:

    [xml] <profiles>
    <profile>
    <id>deploy</id>
    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.4.2</version>
    <configuration>
    <skipTests>true</skipTests>
    </configuration>
    </plugin>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.1</version>
    <executions>
    <execution>
    <phase>package</phase>
    <goals>
    <goal>run</goal>
    </goals>
    <configuration>
    <tasks>
    <ant antfile="./src/resources/ant/build.xml"
    target="deploy"
    inheritall="false" inheritrefs="false"/>
    </tasks>
    </configuration>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>
    </profile>
    </profiles>[/xml]

    At last, my target was OK: I can build and deploy with a simple mvn package -Pdeploy

    PostHeaderIcon Basic RPC call with GWT

    Let’s assume you have a “Hello World” GWT application. You need emulate a basic RPC call (RMI, EJB, etc.). Here is the program:

    Under the *.gwt.client folder:

    Create an service interface:

    [java]@RemoteServiceRelativePath("fooService")
    public interface FooService extends RemoteService {
    public String getHelloFoo(String totoName);
    }[/java]

    Create another interface for asynchronous call. You can notice the method name differs lightly from the one in the other interface:

    [java]public interface FooServiceAsync {
    void getHelloFoo(String fooName, AsyncCallback<String> callback);
    }[/java]

    Under the *.gwt.server folder, create an implementation for service interface:

    [java]public class FooServiceImpl extends RemoteServiceServlet implements FooService {
    public FooServiceImpl() {
    // TODO init
    }

    public String getHelloFoo(String fooName) {
    // TODO call actual service
    return "hello world!";
    }
    }[/java]

    In the web.xml file, add the following blocks:

    [xml] <!– Servlets –>
    <servlet>
    <servlet-name>fooService</servlet-name>
    <servlet-class>com…….server.FooServiceImpl</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>fooService</servlet-name>
    <url-pattern>/ivargwt/fooService</url-pattern>
    </servlet-mapping>
    [/xml]

    The tags content match the argument given as parameter to RemoteServiceRelativePath annotation above.

    From then, in your concrete code, you can instantiate the service and call remote method:

    [java]FooServiceAsync fooService = GWT.create(FooService.class);
    fooService.getHelloFoo("how are you?", new AsyncCallback<String>() {

    public void onSuccess(String result) {
    MessageBox.alert("OK", result, null);
    }

    public void onFailure(Throwable caught) {
    MessageBox.alert("ERROR", "rpc call error-" + caught.getLocalizedMessage(), null);
    }
    });
    [/java]

    Now you can compile, package your war and deploy under Tomcat or WebLogic.

    NB: special to “black-belt GWT guy” David Chau from SFEIR.