Wednesday, 15 September 2010

GWT EJB3 Maven JBoss 5.1 integration tutorial


Hello everyone,

In this article we are going to demonstrate how to properly integrate GWT and EJB3 in order to implement an example project, build it using maven and deploy it on JBoss 5.1 application server. Actually you can easily change the dependencies in the maven build file and deploy the project in your favorite application server. In order to be as generic as possible we will be using the command line flavors of maven and the gedit text editor.

First we have to create the pom project. We will call it ejb-gwt.
mkdir ejb-gwt 
cd ejb-gwt
gedit pom.xml 
pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven4.0.0.xsd">
  <modelversion>4.0.0</modelversion>
  <groupid>com.javacodegeeks</groupid>
  <artifactid>ejb-gwt</artifactid>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>ejb-gwt</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
  </properties>
  <dependencies>
  </dependencies>
  <modules>
  </modules>
 <build>
  <plugins>
   <plugin>
    <groupid>org.apache.maven.plugins</groupid>
    <artifactid>maven-compiler-plugin</artifactid>
    <configuration>
     1.6
     <target>1.6</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>

Then we will create the module that will contain the ejb classes. We will call it ejb-jar.
mvn archetype:create -DgroupId=com.javacodegeeks -DartifactId=ejb-jar
cd ejb-jar/src/main
mkdir resources
cd resources
mkdir META-INF
cd META-INF
gedit persistence.xml

We will configure the persistence.xml to use the default datasource of jboss.

persistence.xml
<persistence version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/persistence" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="MyPersistenceUnit">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <jta-data-source>java:/DefaultDS</jta-data-source>
   <properties>
   <property name="hibernate.hbm2ddl.auto" value="update">
   <property name="hibernate.show_sql" value="true">
   <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect">
  </property></property></property></properties>
 </persistence-unit>
</persistence>

At src/java you will place your ejb code. In our example we have an entity bean

Employee.java
package com.javacodegeeks.ejb.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "EMPLOYEE")
public class Employee implements java.io.Serializable {
 
 private static final long serialVersionUID = 7440297955003302414L;

 @Id
 @Column(name="employee_id")
 private long employeeId;
 
 @Column(name="employee_name", nullable = false, length=30)
 private String employeeName;
 
 @Column(name="employee_surname", nullable = false, length=30)
 private String employeeSurname;
 
 @Column(name="job", length=50)
 private String job;
  
 public Employee() {
 }

 public Employee(int employeeId) {
  this.employeeId = employeeId;  
 }

 public Employee(long employeeId, String employeeName, String employeeSurname,
   String job) {
  this.employeeId = employeeId;
  this.employeeName = employeeName;
  this.employeeSurname = employeeSurname;
  this.job = job;
 }

 public long getEmployeeId() {
  return employeeId;
 }

 public void setEmployeeId(long employeeId) {
  this.employeeId = employeeId;
 }

 public String getEmployeeName() {
  return employeeName;
 }

 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }

 public String getEmployeeSurname() {
  return employeeSurname;
 }

 public void setEmployeeSurname(String employeeSurname) {
  this.employeeSurname = employeeSurname;
 }

 public String getJob() {
  return job;
 }

 public void setJob(String job) {
  this.job = job;
 }
}

The local interface of a session bean.

EmployeeService.java
package com.javacodegeeks.ejb.session;

import com.javacodegeeks.ejb.entity.Employee;

public interface EmployeeService {
 public Employee findEmployee(long employeeId);
 public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
 public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
 public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
 public void deleteEmployee(long employeeId) throws Exception;
}

And finaly the session bean.

EmployeeServiceBean.java
package com.javacodegeeks.ejb.session;

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.javacodegeeks.ejb.entity.Employee;

@Stateless(name = "employeeService")
@Local(EmployeeService.class)
public class EmployeeServiceBean implements EmployeeService {
 @PersistenceContext
 private EntityManager entityManager;

 public void deleteEmployee(long employeeId) throws Exception {
  entityManager.remove(entityManager.find(Employee.class, employeeId));
 }

 public Employee findEmployee(long employeeId) {
  return entityManager.find(Employee.class, employeeId);
 }

 public void saveEmployee(long employeeId, String name, String surname,
   String jobDescription) throws Exception {
  Employee emp = new Employee();
  emp.setEmployeeId(employeeId);
  emp.setEmployeeName(name);
  emp.setEmployeeSurname(surname);
  emp.setJob(jobDescription);
  
  entityManager.persist(emp);

 }

 public void saveOrUpdateEmployee(long employeeId, String name,
   String surname, String jobDescription) throws Exception {
  Employee emp = new Employee();
  emp.setEmployeeId(employeeId);
  emp.setEmployeeName(name);
  emp.setEmployeeSurname(surname);
  emp.setJob(jobDescription);
  
  entityManager.merge(emp);
 }

 public void updateEmployee(long employeeId, String name, String surname,
   String jobDescription) throws Exception {
  Employee emp = entityManager.find(Employee.class, employeeId);
  emp.setEmployeeName(name);
  emp.setEmployeeSurname(surname);
  emp.setJob(jobDescription);
  
  entityManager.merge(emp);
 }

}

The pom.xml of ejb-jar module should be :

pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>
  <parent>
    <artifactid>ejb-gwt</artifactid>
    <groupid>com.javacodegeeks</groupid>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <groupid>com.javacodegeeks</groupid>
  <artifactid>ejb-jar</artifactid>
  <version>0.0.1-SNAPSHOT</version>
  <name>ejb-jar</name>
  <packaging>ejb</packaging>
  <url>http://maven.apache.org</url>

  <repositories>
   <repository>
    <id>jboss-maven2</id>
    <url>http://repository.jboss.com/maven2</url>
    </repository>
  </repositories>

  <dependencies>
   <dependency>
     <groupid>org.jboss.jbossas</groupid>
     <artifactid>jboss-as-client</artifactid>
     <version>5.1.0.GA</version>
     <type>pom</type>
     <scope>provided</scope>
 </dependency>
   <dependency>
      <groupid>junit</groupid>
      <artifactid>junit</artifactid>
      <version>4.7</version>
      <scope>test</scope>
    </dependency> 
  </dependencies>
  <build>
    <plugins>
        <plugin>
            <groupid>org.apache.maven.plugins</groupid>
            <artifactid>maven-ejb-plugin</artifactid>
            <configuration>
                <ejbversion>3.0</ejbversion>
            </configuration>
        </plugin>
    </plugins>
</build>
</project>

We will now generate our web project based on gwt-maven-plugin archertype.
mvn archetype:generate -DarchetypeGroupId=org.codehaus.mojo -DarchetypeArtifactId=gwt-maven-plugin -DarchetypeVersion=1.2    -DgroupId=com.javacodegeeks    -DartifactId=war
cd war
gedit pom.xml

pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  
  <modelversion>4.0.0</modelversion>
  <parent>
        <artifactid>ejb-gwt</artifactid>
        <groupid>com.javacodegeeks</groupid>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
  <groupid>com.javacodegeeks</groupid>
  <artifactid>war</artifactid>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version> 
  <properties>
      <gwt.version>2.0.4</gwt.version>
      <maven.compiler.source>1.6</maven.compiler.source>
      <maven.compiler.target>1.6</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupid>com.google.gwt</groupid>
      <artifactid>gwt-servlet</artifactid>
      <version>${gwt.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupid>com.google.gwt</groupid>
      <artifactid>gwt-user</artifactid>
      <version>${gwt.version}</version>  
      <scope>provided</scope>
    </dependency>
    <dependency>
     <groupid>org.jboss.jbossas</groupid>
     <artifactid>jboss-as-client</artifactid>
     <version>5.1.0.GA</version>
     <type>pom</type>
     <scope>provided</scope>
 </dependency>
 <dependency>
    <groupid>com.javacodegeeks</groupid>
    <artifactid>ejb-jar</artifactid>
    <version>0.0.1-SNAPSHOT</version>
    <type>ejb</type>
    <scope>provided</scope>
   </dependency>
    <dependency>
      <groupid>junit</groupid>
      <artifactid>junit</artifactid>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
  <finalname>war</finalname>
    <outputdirectory>war/WEB-INF/classes</outputdirectory>
    <plugins>
      <plugin>
        <groupid>org.codehaus.mojo</groupid>
        <artifactid>gwt-maven-plugin</artifactid>
        <version>1.2</version>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>generateAsync</goal>
              <goal>test</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <runtarget>com.javacodegeeks.war.Application/Application.html</runtarget>
        </configuration>
      </plugin>
      <plugin>
          <groupid>org.apache.maven.plugins</groupid>
          <artifactid>maven-compiler-plugin</artifactid>
          <version>2.0.2</version>
          <configuration>
            ${maven.compiler.source}
            <target>${maven.compiler.target}</target>
          </configuration>
      </plugin>
    </plugins>
  </build>

</project>

cd src/main/webapp/WEB-INF
gedit web.xml

web.xml
<web-app version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <display-name>GWT-Maven-Archetype</display-name> 
 <servlet>
    <servlet-name>emp</servlet-name>
    <servlet-class>com.javacodegeeks.war.server.services.EmployeeServiceGWTImpl</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>emp</servlet-name>
    <url-pattern>/com.javacodegeeks.war.Application/emp</url-pattern>
  </servlet-mapping>
 <welcome-file-list>
  <welcome-file>index.html</welcome-file>
 </welcome-file-list>
</web-app>


web.xml should apply at 2.5 specification if we want to have ejb injection at servlet container.

Now let's take a look at the gwt service.

EmployeeServiceGWT.java
package com.javacodegeeks.war.shared.services;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.javacodegeeks.war.shared.entity.EmployeeUtil;

@RemoteServiceRelativePath("emp")
public interface EmployeeServiceGWT  extends RemoteService  {
 public EmployeeUtil findEmployee(long employeeId);
 public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
 public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
 public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception;
 public void deleteEmployee(long employeeId) throws Exception;
}

Notice tha the RemoteServiceRelativePath is related with the servlet path /com.javacodegeeks.war.Application/emp that we have defined in the web.xml

EmployeeServiceGWTImpl.java
package com.javacodegeeks.war.server.services;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.javacodegeeks.ejb.entity.Employee;
import com.javacodegeeks.ejb.session.EmployeeService;
import com.javacodegeeks.war.shared.entity.EmployeeUtil;
import com.javacodegeeks.war.shared.services.EmployeeServiceGWT;

public class EmployeeServiceGWTImpl extends RemoteServiceServlet implements EmployeeServiceGWT{

 /**
  * 
  */
 private static final long serialVersionUID = 5995064321382986251L;
 
 private EmployeeService employeeService;
 @Resource(name="java:UserTransaction") UserTransaction ut;


 
 @EJB
 public void setEmployeeService(EmployeeService employeeService) {
  this.employeeService = employeeService;
 }

 public void deleteEmployee(long employeeId) throws Exception {
  employeeService.deleteEmployee(employeeId);
  
 }

 public EmployeeUtil findEmployee(long employeeId) {
  
  Employee emp = employeeService.findEmployee(employeeId);
  if(emp != null) {
   try {
    ut.begin();
    EmployeeUtil util = new EmployeeUtil(emp.getEmployeeId(), emp.getEmployeeName(), emp.getEmployeeSurname(), emp.getJob());
    
    ut.commit();
    return util;
   } catch (Exception e) {
   }
   
  }
  return null;
 }

 public void saveEmployee(long employeeId, String name, String surname,
   String jobDescription) throws Exception {
  employeeService.saveEmployee(employeeId, name, surname, jobDescription);
  
 }

 public void saveOrUpdateEmployee(long employeeId, String name,
   String surname, String jobDescription) throws Exception {
  employeeService.saveOrUpdateEmployee(employeeId, name, surname, jobDescription);
  
 }

 public void updateEmployee(long employeeId, String name, String surname,
   String jobDescription) throws Exception {
  employeeService.updateEmployee(employeeId, name, surname, jobDescription);
  
 }

}


As you can see ,we inject the employeeService session bean using the annotation @EJB.
Notice that we use EmployeeUtil class for a basic reason:
GWT cannot handle lazy initialized relationship so we replace proxy collection with real collections.The replacement should be in a transaction scope .


package com.javacodegeeks.war.shared.entity;

import java.io.Serializable;

public class EmployeeUtil implements Serializable  {
 
 /**
  * 
  */
 private static final long serialVersionUID = -2732740011239267035L;

 private long employeeId;
 
 private String employeeName;
 
 private String employeeSurname;
 
 private String job;
 
 
 public EmployeeUtil() {
 }

 public EmployeeUtil(int employeeId) {
  this.employeeId = employeeId;  
 }

 public EmployeeUtil(long employeeId, String employeeName, String employeeSurname,
   String job) {
  this.employeeId = employeeId;
  this.employeeName = employeeName;
  this.employeeSurname = employeeSurname;
  this.job = job;
 }

 public long getEmployeeId() {
  return employeeId;
 }

 public void setEmployeeId(long employeeId) {
  this.employeeId = employeeId;
 }

 public String getEmployeeName() {
  return employeeName;
 }

 public void setEmployeeName(String employeeName) {
  this.employeeName = employeeName;
 }

 public String getEmployeeSurname() {
  return employeeSurname;
 }

 public void setEmployeeSurname(String employeeSurname) {
  this.employeeSurname = employeeSurname;
 }

 public String getJob() {
  return job;
 }

 public void setJob(String job) {
  this.job = job;
 }

}

The rest of the source code for the gwt interface is provided in the source code of this article.

Now we have on final step,to build the ear.We will create a module to do that .
mvn archetype:create -DgroupId=com.javacodegeeks -DartifactId=ear
cd ear
rm -rf src
gedit pom.xml

pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelversion>4.0.0</modelversion>
  <parent>
    <artifactid>ejb-gwt</artifactid>
    <groupid>com.javacodegeeks</groupid>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <groupid>com.javacodegeeks</groupid>
  <artifactid>ear</artifactid>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>ear</packaging>
  <name>ear</name>
  <description>ear for gwt ejb3</description>
  <dependencies>
   <dependency>
    <groupid>com.javacodegeeks</groupid>
    <artifactid>ejb-jar</artifactid>
    <version>0.0.1-SNAPSHOT</version>
    <type>ejb</type>
   </dependency>
    <dependency>
    <groupid>com.javacodegeeks</groupid>
    <artifactid>war</artifactid>
    <version>0.0.1-SNAPSHOT</version>
    <type>war</type>
   </dependency>
  </dependencies>

 <build>
    <plugins>
      <plugin>
        <groupid>org.apache.maven.plugins</groupid>
        <artifactid>maven-ear-plugin</artifactid>
        <configuration>
          <generateapplicationxml>true</generateapplicationxml>
          <modules>
            <webmodule>
              <groupid>com.javacodegeeks</groupid>
              <artifactid>war</artifactid>
              <contextroot>ejb-gwt</contextroot>
            </webmodule>
            <ejbmodule>
              <groupid>com.javacodegeeks</groupid>
              <artifactid>ejb-jar</artifactid>
            </ejbmodule>
         </modules>
       </configuration>
     </plugin>
   </plugins>
  </build>
</project>


To build the project go to the root project and type :
mvn install

The source code for this article is located here .


Thanks


./pat


Related Articles :



8 comments:

  1. Kinda okay with the article.
    But it really has nothing to to with GWT to EJB integration per se (except for a SessionBean injection). You could integrate GWT with whatever you want in this manner.

    Now add a bit of spice specifying a lazy initialized relationship from your Employee entity and watch it blow up on serialization.

    The example should be a bit more real life-oriented.

    Regards,
    Dmitry

    ReplyDelete
  2. Dmitry ,

    In a real life scenario you could use something like dozer to replace proxy collections with real collections.
    If you notice our example you will see that GWT service use an EmployeeUtil class instead of Employee class.

    There is also another problem with a lazy initialized relationship. You would have to start a transaction to retrieve the values of the relationship.

    I have update EmployeeServiceGWTImpl with all the code you need in a real life scenario.

    Thank you for the comment

    Regards
    pat

    ReplyDelete
  3. XML (in my case) are case sensitive ... and some of the tags should have been spelt slightly differently.
    Like :
    goupid -> groupId
    I can mail you my pom.xml files if you want.

    \T,

    ps : jdk is 1.6 on Mac OSX with Maven2.2

    ReplyDelete
  4. Thank you tsmets.

    That would be great.

    ReplyDelete
  5. Hi Pat,

    I downloaded the source from the link you provide... and it returned an Exception :

    [INFO] Installing /Users/tsmets/Workspaces/MyEclipse 8.x/ejb-gwt-source/ejb-gwt/ejb-jar/target/ejb-jar-0.0.1-SNAPSHOT.jar to /Users/tsmets/.m2/repository/com/javacodegeeks/ejb-jar/0.0.1-SNAPSHOT/ejb-jar-0.0.1-SNAPSHOT.jar
    [INFO] ------------------------------------------------------------------------
    [INFO] Building Unnamed - com.javacodegeeks:war:war:0.0.1-SNAPSHOT
    [INFO] task-segment: [install]
    [INFO] ------------------------------------------------------------------------
    [INFO] [gwt:generateAsync {execution: default}]
    [INFO] using GWT jars from project dependencies : 2.0.4
    [INFO] [resources:resources {execution: default-resources}]
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] Copying 2 resources
    [INFO] [compiler:compile {execution: default-compile}]
    [INFO] Nothing to compile - all classes are up to date
    [INFO] [gwt:compile {execution: default}]
    [INFO] using GWT jars from project dependencies : 2.0.4
    [INFO] auto discovered modules [com.javacodegeeks.war.Application]
    [INFO] establishing classpath list (scope = compile)
    [INFO] using GWT jars for specified version 2.0.4
    [INFO] using GWT jars for specified version 2.0.4
    [ERROR] Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gwt/dev/Compiler
    [ERROR] Caused by: java.lang.ClassNotFoundException: com.google.gwt.dev.Compiler
    [ERROR] at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    [ERROR] at java.security.AccessController.doPrivileged(Native Method)
    [ERROR] at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    [ERROR] at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    [ERROR] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    [ERROR] at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    [INFO] ------------------------------------------------------------------------
    [ERROR] BUILD ERROR
    [INFO] ------------------------------------------------------------------------
    [INFO] Command [[
    /bin/sh -c /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/bin/java -Xmx512m -classpath '"/Users/tsmets/Workspaces/MyEclipse 8.x/ejb-gwt-source/ejb-gwt/war/src/main/java":"/Users/tsmets/Workspaces/MyEclipse 8.x/ejb-gwt-source/ejb-gwt/war/src/main/resources":"/Users/tsmets/Workspaces/MyEclipse 8.x/ejb-gwt-source/ejb-gwt/war/war/WEB-INF ...


    Specs :
    Thomas-SMETSs-MacBook-Pro:ejb-gwt tsmets$ mvn -v
    Apache Maven 2.2.0 (r788681; 2009-06-26 15:04:01+0200)
    Java version: 1.6.0_20
    Java home: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
    Default locale: en_US, platform encoding: MacRoman
    OS name: "mac os x" version: "10.6.4" arch: "x86_64" Family: "mac"
    Thomas-SMETSs-MacBook-Pro:ejb-gwt tsmets$


    I am investigating further but I have the feeling that on yr machine, the set up includes the Google compiler in the CP already (wild guess).

    \T,

    ReplyDelete
  6. Hello tsmets,

    maybe you should try this.

    http://stephou.wordpress.com/2010/05/28/noclassdeffounderror-com-google-gwt-dev-compiler-while-building-on-hudson/

    ./pat

    ReplyDelete
  7. There seems to be a bug on unix & mac plateform, as mentionned http://jira.codehaus.org/browse/MGWT-142
    The latest version of the code available in the repos are : 2.0.4 while the fix is planned for the 2.1.0

    It seems to be clearly a Maven plugin problem as the "Comment" on the issue clearly indicate :(

    \T,

    ReplyDelete
  8. Hi Pat,

    We've built a similar architecture except one point, our GWT code is mailny extracted into separated projects compiled as jars and used as dependencies of our GWt webapp.

    We encounters a lot of problems to develop and debug (old code executed, memory problems, debug breakpoints on ghost lines,...) it's quite impossible to use the GWT hosted mode and we have to build the entire project to test our modifications.

    We are using GWT 2.3, GXT 2.2.4, Glassfish 3.1, Eclipse Indigo or Netbeans 7.0.1

    Do you have any experience to improve development conditions ?

    Thanks

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...