GWT Integration for Nuxeo
This documents assumes you are familiar with GWT have the basic knowledge on how to build GWT applications. You can find a complete introduction to GWT here: http://code.google.com/webtoolkit/gettingstarted.html GWT is a web toolkit to build rich clients in Java programming language. The Java code is transcoded in JavaScript at build time so the build process generates a fully HTML+JavaScript application ready to be deployed on an HTTP server. GWT applications may contain both server side code (which is Java byte code) and client side code (which is Java in development mode but is transcoded in JavaScript at build time). When using the GWT RPC mechanism you usually need to share the client code that makes up your application model (the data objects). This code is both compiled to JavaScript and to Java byte code. Note that only a small subset of JRE classes can be transcoded by GWT to JavaScript (e.g. most of the classes in java.lang and java.utils).Developing a GWT Application
Requirements
To develop a GWT based application for Nuxeo you need first to install the GWT Eclipse plugin. Here is the list of update sites for each supported Eclipse distribution: Also you need a Nuxeo version >= 5.3.1-SNAPSHOT for your Nuxeo dependencies and to be able to deploy your GWT applications.Creating a Hello World Application
Create a new Web Application Project. Uncheck Use Google App Engine in the wizard page. The GWT wizard will create a project structure like:src
org/my/app/client
org/my/app/server
your_module.gwt.xml
war
WEB-INF/web.xml
your_module.css
your_module.html- Add the JARs of nuxeo-webengine-gwt and nuxeo-distribution-tools v. 0.8
<dependency> <groupId>org.nuxeo.ecm.webengine</groupId> <artifactId>nuxeo-webengine-gwt</artifactId> </dependency> <dependency> <groupId>org.nuxeo.build</groupId> <artifactId>nuxeo-distribution-tools</artifactId> <classifier>all</classifier> <version>0.8</version> <scope>test</scope> </dependency>
- Add to war/WEB-INF/web.xml a filter as following:
<filter>
<display-name>WebEngine Authentication Filter</display-name>
<filter-name>NuxeoAuthenticationFilter</filter-name>
<filter-class>
org.nuxeo.ecm.webengine.gwt.dev.NuxeoLauncher
</filter-class>
<init-param>
<param-name>byPassAuthenticationLog</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>securityDomain</param-name>
<param-value>nuxeo-webengine</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NuxeoAuthenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>{user.home}/.nxserver-gwt.Deploying the GWT Application on a Nuxeo Server
To be able to deploy your GWT in a real Nuxeo Server you need to package it as a Nuxeo bundle that:- defines an OSGi Bundle-Activator in your MANIFEST.MF that points to org.nuxeo.ecm.webengine.gwt.GwtBundleActivator.
your-gwt-module.jar
META-INF/MANIFEST.MF
OSGI-INF/deployment-fragment.xml
...
org/
gwt-war/
your_gwt_module.html
...Accessing your GWT module from the client
But how to expose the GWT application to clients? For this you need to create a simple WebEngine module that expose the GWT application through a JAX-RS resource. (You can either use webengine objects or raw JAX-RS resources - or even a custom servlet your registered in web.xml) If your are using a WebEngine Module you only need to override the abstract class: org.nuxeo.ecm.webengine.gwt.GwtResource and implement a @GET method to server the GWT application home page like:@WebObject(type="myGwtApp") public class MyGwtApp extends GwtResource { @GET @Produces("text/html") public Object getIndex() { return getTemplate("studio.ftl"); } }
@GET
@Path("{path:.*}")
public Response getResource(@PathParam("path") String path) {
//System.out.println(">>> "+GWT_ROOT.getAbsolutePath());
// avoid putting automatic no cache headers
ctx.getRequest().setAttribute("org.nuxeo.webengine.DisableAutoHeaders", "true");
File file = new File(GwtBundleActivator.GWT_ROOT, path);
if (file.isFile()) {
ResponseBuilder resp = Response.ok(file);
String fpath = file.getPath();
int p = fpath.lastIndexOf('.');
String ext = "";
if (p > -1) {
ext = fpath.substring(p+1);
}
String mimeType = ctx.getEngine().getMimeType(ext);
if (mimeType == null) {
mimeType = "text/plain";
}
resp.type(mimeType);
return resp.build();
}
return Response.status(404).build();
}Using GWT RPC mechanism in a Nuxeo GWT module.
If you want to use GWT RPC inside Nuxeo GWT modules you must be sure your RPC servlet classes extends org.nuxeo.ecm.webengine.gwt.WebEngineGwtServlet instead of RemoteServiceServlet. This is required since the default RemoteServiceServlet is assuming a WAR structure that is not present in a Nuxeo Server. The WebEngineGwtServlet locates correctly the resources needed by the GWT Serializer and then it dispatches the request back to RemoteServiceServlet. And also don't forget to define your RPC servlets in the web.xml! You can use for this the regular approach in Nuxeo (through deployment-fragment.xml files). Note: Your GWT RPC servlets are executed in an authenticated context since the Nuxeo Authentication filter is in place.Using Other Server / Client Communication Mechanisms.
Apart the GWT RPC mechanism you can communicate with the server using any mechanism you need as far as you define a servlet and a protocol between your client and server applications. Event if custom communication works well in web mode (when the application is deployed in a real Nuxeo server) you will have problems to debug and use them in development mode (when Nuxeo is embedded in GWT IDE). This is because of the SOP (Same origin Policy) problems in Ajax applications. As I said before the embedded Nuxeo server will listen at a different port (by default to 8081) than the GWT embedded HTTP server. This means you will not be able to do calls from GWT client to servlets registered in the embedded Nuxeo server since they belong to another domain (i.e. different port). There are 2 ways of fixing the problem and make it work in development mode:- Register your servlets in the GWT HTTP server (in war/WEB-INF/web.xml)
- Use the redirection service provided by nuxeo-webengine-gwt. This is the recommended method since you don't have any limitation.
<!-- enable redirected request content tracing -->
<init-param>
<param-name>redirectTraceContent</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>redirectPrefix</param-name>
<param-value>/foo/bar</param-value>
</init-param>Example of a pom.xml
<properties>
<gwtVersion>2.0</gwtVersion>
<gwt.module>org.your_gwt_module</gwt.module>
</properties>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi-core</artifactId>
</dependency>
<dependency>
<groupId>org.nuxeo.runtime</groupId>
<artifactId>nuxeo-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.nuxeo.common</groupId>
<artifactId>nuxeo-common</artifactId>
</dependency>
<dependency>
<groupId>org.nuxeo.ecm.webengine</groupId>
<artifactId>nuxeo-webengine-gwt</artifactId>
</dependency>
<dependency>
<groupId>org.nuxeo.build</groupId>
<artifactId>nuxeo-distribution-tools</artifactId>
<classifier>all</classifier>
<version>0.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwtVersion}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>${gwtVersion}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<!-- gwt compiler needs the java sources to correctly work -->
<resources>
<resource>
<directory>src/main/java</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<!-- correctly generate eclipse files with GWT nature -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<downloadSources>false</downloadSources>
<additionalProjectnatures>
<projectnature>com.google.gwt.eclipse.core.gwtNature</projectnature>
<projectnature>com.google.gdt.eclipse.core.webAppNature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildCommand>
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
<arguments>
</arguments>
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
</additionalBuildcommands>
<classpathContainers>
<classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
<classpathContainer>com.google.gwt.eclipse.core.GWT_CONTAINER</classpathContainer>
</classpathContainers>
<buildOutputDirectory>war/WEB-INF/classes</buildOutputDirectory>
</configuration>
</plugin>
<!--
After compiling java sources compile java to JS using GWT compiler. This
must be done process-classes after compile step finished to be sure we
have all the needed files in classes directory. I am using ant for this
since the maven exec plugin is not able to run correctly this
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>compile-js</id>
<phase>process-classes</phase>
<configuration>
<tasks>
<property name="compile_classpath" refid="maven.compile.classpath" />
<property name="runtime_classpath" refid="maven.runtime.classpath"/>
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<pathelement location="${project.build.outputDirectory}" />
<pathelement path="${compile_classpath}" />
<pathelement path="${runtime_classpath}" />
</classpath>
<jvmarg value="-Xmx256M" />
<jvmarg value="${gwt.arg}" />
<!--arg value="-style" />
<arg value="DETAILED" /-->
<!-- to speed up compiler
<arg value="-draftCompile" /-->
<arg value="-war" />
<arg value="${project.build.outputDirectory}/gwt-war" />
<arg value="${gwt.module}" />
</java>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Version 10.1 last modified by Bogdan Stefanescu on 21/01/2010 at 14:49
Document data
Attachments:
No attachments for this document
Comments: 0