Supporting i18n in GWT - java

Till now, our web application supports only English. Now we have to provide support for Italian as well. There is GWT module for some functionality. To support the Italian language I have added below line in the file "APP_Module.gwt.xml"
<extend-property name="locale" values="it"/>
I have also placed "XXX_it.properties" file under the source code where the properties file for en is kept.
Setting the locale in the jsp by following line:
<meta name="gwt:property" content="locale=${locale}">
Now, the issue is how to compile the code. I am debugging the application but it is not hitting the client code of GWT presented under WEB-INF/src.
I am very new to GWT. Please suggest how can I compile the code or there is no need of compilation. It will automatically take the changes done in "APP_Module.gwt.xml" and there is some other issue. How can I see logs of GWT?

To add support for locales to GWT application, you need to do the following in your xxx.gwt.xml:
under <module> add this to include the support:
<inherits name="com.google.gwt.i18n.I18N" />
and this to configure it:
<extend-property name="locale" values="en,it"/>
<set-property-fallback name="locale" value="en"/>
Add all your property files under some package like this:
src/main/resources/foo/bar/client/i18n/MyMessages.properties
src/main/resources/foo/bar/client/i18n/MyMessages_it.properties
Then you need to tell GWT to compile them into classes. This is example from a pom.xml file (if you don't use maven, you will have to use a different way, but you still need to configure it).
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.3.1.google</version>
<executions>
<execution>
<goals>
<goal>i18n</goal>
<goal>generateAsync</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<i18nMessagesBundles>
<resourceBundle>foo.bar.client.i18n.MyMessages</resourceBundle>
</i18nMessagesBundles>
</configuration>
</plugin>
Then you need to recompile the code. In maven mvn compile. And that's all, you will have your messages in generated sources folder ready to use.

For seeing the logs of gwt you can use gradlew gwt also you can use it to compile the code too.

Related

Adding GWT to existing Maven web application

I would like to add some GWT (Google web toolkit) functionality to my existing web application built with maven (servlets, jsps etc). I have read some tutorials about GWT and managed to successfully write some basic examples but I can't seem to understand how to integrate it with my existing project. All the tutorials that I found focus on building this application from scratch (without Maven) or by crating new project with GWT archetype (with Maven).
How do I proceed with existing application (webapp archetype)? I tried adding the path do GWT SDK to the project and created basic HelloWorld class (I created separate package structire just for GWT) following THIS tutorial.
What I don't understand is how to setup everything correctly and where to place the configuration files? Is the config file supposed to be in the root folder of the project (next to pom.xml)? Should it be named the same as my project is named or based on the class specified as entry point?
Basically, my current structure looks like this:
src/main/java/wa2/gwt/clients/CarRental.java
src/main/webapp/CarRental.html (same directory as my JSPs)
src/resousrce/wa2/gwt/CarRental.gwt.xml (same directory as pom.xml) - let's say that my project is called "CarRental"
This obviously does not work. Did I forgot some configuration? Are the locations wrong? Thanks for any help!
EDIT: I changed the structure of the project and added the maven dependencies. It seems that GWT is recognized now. However, it is still not running any GWT code when accessing the html page.
This is my silly test with CarRental.html (src/main/webapp/CarRental.html):
<html>
<head>
<title>CarRental</title>
<script language="javascript" src="carrental/carrental.nocache.js">
</script>
</head>
<body>
<h1>Hello World</h1>
<p>Welcome to first GWT application</p>
</body>
</html>
The CarRental.java (src/main/java/wa2.gwt.clients.CarRental.java):
package wa2.gwt.clients;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
public class CarRental implements EntryPoint {
public void onModuleLoad() {
Window.alert("Hello, World!");
}
}
Am I still missing something? I am accessing the html file by clicking it and executing run as > run on server (the webapp is deployed to my Tomcat server) or alternatively just typing the URL on localhost.
I have a Maven/GWT app with the following structure:
approot/pom.xml
approot/src/main/resources
approot/src/main/java/org/mydomain/MyApplication.gwt.xml
approot/src/main/java/org/mydomain/client/...
approot/src/main/java/org/mydomain/others/...
All the GWT Java code is in the client package, as deined in the gwt.xml file like this:
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd">
<module rename-to='resources'>
<inherits name='com.google.gwt.user.User'/>
<inherits name="com.google.gwt.resources.Resources" />
<inherits name="com.google.gwt.uibinder.UiBinder"/>
<inherits name="some.other.Dependency" />
<source path="client" />
<entry-point class='org.mydomain.client.Main'/>
</module>
Here, the source element specifies that all Java in the client package (and any sub-packages) is to be processed by the GWT compiler and converted into JavaScript. All other packages are server-side and are not converted. If you have no server-side Java, then you'll only have the client package.
You'll need the GWT dependencies. Here's the minimum, there are others:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
It is also important to include the GWT maven plugin, so the GWT compiler will run during a Maven build. Configure the plugin in your <plugins> section of your pom.xml. Here's an example:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>

Wildfly exploded war hot deployment

I have a web application deployed as exploded war using wildfly. What I want to get is
Changes in jsp files are automatically reflected, without redeploying the app
Changes in .class files enforce an app redeployment.
At the moment I am in a situation in which either I can get one option or the other, but not both at the same time (meaning that either every jsp change forces a new deployment or that .class files do not force a new deployment).
Current configuration of wildfly (using version 8.1.0) is
<deployment-scanner
path="deployments"
relative-to="jboss.server.base.dir"
scan-enabled="true"
scan-interval="1000"
auto-deploy-exploded="true"
runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"
/>
...
<servlet-container name="default">
<jsp-config development="true"/>
</servlet-container>
Also, something I have found is that no matter what I set in the deployment-scanner config, once the server is up and running, if I go to the wildfly web console, the parameter auto-deploy-war is marked as true and auto-deploy-exploded is marked as false, even the scan-interval is always set to 5000 ms, which makes me think that the deployment scanner config is somehow being ignored.
I am kind of lost here quite frankly, it has to be possible for wildfly to reload the app if the change is a .class file and not do it if it is a jsp.
Have you tried JRebel? following my blog entries would help also.
http://www.nailedtothex.org/roller/kyle/entry/evaluating-jrebel-for-wildfly-and
http://www.nailedtothex.org/roller/kyle/entry/exploded-deployment-for-wildfly-on
Manik Hot deploy is an open source Maven Plugin that simplifies your web development. The plugin provides both deployment modes - the auto-deployment and also the hot-deployment. It can be easily configured in a maven project by adding the plugin to the pom.xml
....
<build>
<plugins>
.....
<!-- Manik Hotdploy -->
<plugin>
<groupId>org.imixs.maven</groupId>
<artifactId>manik-hotdeploy-maven-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- List Source and Target folders for Autodeploy and Hotdeploy -->
<autodeployments>
<deployment>
<!-- wildcard deployment -->
<source>target/*.{war,ear,jar}</source>
<target>/opt/wildfly/standalone/deployments/</target>
<unpack>true</unpack>
</deployment>
</autodeployments>
<hotdeployments>
<deployment>
<source>src/main/webapp</source>
<target>/opt/wildfly/standalone//deployments/my-app.war</target>
</deployment>
</hotdeployments>
</configuration>
</plugin>
.....
</plugins>
</build>
....

Is there any way to trigger the Maven Appengine Devserver to auto-refresh static files?

The most recent version of the maven plugin has enabled updating of code every 5s, which is a great improvement. But unless I am configuring this wrong, it doesn't seem to pick up static file changes such as work in progress Javascript connecting to the appengine code.
Is there any way to alter this behavior or do I just need to wait for a new release?
Automatic updates cannot be done using appending devserver alone right now. Strictly speaking, we need to wait.
But you can achieve the effect of seamless html/js/css/etc update, hot java code replacement, etc. with the configuration below.
Configure Apache httpd or Nginx to serve static code directly from your war-source and route to app engine for servlets. In my case, all the html are directly accessible from webapp directory and servlets are called via /sim/. Using nginx and 7070 port, my working nginx config looks like:
server {
listen 7070;
root /home/pchauhan/Projects/my-company/my-mvn-gae-project/my-mvn-gae-project-war/src/main/webapp;
location /sim/ {
proxy_pass http://localhost:8080/sim/;
}
}
Use this documentation of nginx, for more configurations.
Configure Eclipse and GAE separately.
Now, you can directly make changes to source and get them on refresh, both for html (via nginx) and servlets (via devserver).
Add this webapp folder to your Chrome Dev Tools, Sources Workspace and life will be easier. Small changes can directly be saved from chrome to src via ctrl
Please note, that while this is great, you should test your app once solely on 8080 (devserver port) before uploading, just in case there is a bug in maven config and target is not being created/served correctly.
Alternate Idea for syncing: If you do not want to use nginx/httpd for some reason, you can add target...webapp to chrome workspace, work directly there for seamless updt and then use lsyncd to sync target back to src. I haven't tried it yet, but looks feasible, albeit a bit risky.
So far, best way i found was configuring below entries in pom.xml. This will build automatically your static files and reflects on the page.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="target.webapp.dir"
value="${project.build.directory}/${project.build.finalName}" />
<property name="src.webapp.dir" value="${basedir}/src/main/webapp" />
<sync verbose="true" todir="${target.webapp.dir}"
includeEmptyDirs="true">
<fileset dir="${src.webapp.dir}" />
<preserveintarget>
<include name="WEB-INF/lib/**" />
<include name="WEB-INF/classes/**" />
<include name="WEB-INF/appengine-generated/**" />
</preserveintarget>
</sync>
<!-- <sync verbose="true" todir="${target.webapp.dir}/WEB-INF/classes">
<fileset dir="${basedir}/target/classes" /> </sync> -->
</target>
</configuration>
</execution>
</executions>
</plugin>
And another entry after
<pluginManagement>
<plugins>
<!-- This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<versionRange>[1.6,)</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
This is working fine. As soon as any static files changed and saved, it got reflected on the page.
Like PoojaC20, I have also not been able to get this working with devserver alone but I ended up with a different workaround which I thought I'd share in case others found it helpful.
I now host my development static files outside of the GAE devserver by using grunt-serve. This allows a large number of advantages including:
Automatic page refresh when static files have changed - don't even need to press the refresh button.
Automatic conversion of advanced CSS such as LESS
Automatic conversion of javascript-compileable languages such as CoffeeScript
Mechanism for minification and CDN-ification when development is done.
The most profound implication of the above is that I have needed to move away from session based authentication to OAuth or OpenID Connect based authentication systems and to make all of my web service calls CORS compatible. This is some work, but it too has one very profound advantage:
Once your web sever has moved to OpenID Connect based authentication, it can now connect identically to native (e.g. mobile) client or web based clients!

Maven: Usage of external libraries for integration test

Currently, I set up an integration test suite. The base is a Maven project with several modules which are dependent to each other to setup a database, to put some data into it and to run tests on it, before wrapping everything up. Additionally, I have modules with some utilities and test data in there.
The first step (not mentioned above) is the copy of a zipped image which includes a lot of JAR files which make up the software suite to be tested. Unfortunately, the software is not build by Maven, but by Ant, so I can not find the stuff in an Artifactory or something similar.
My problem is now, that I copy and unzip the image with an integration test method, but I do not know, how I can add the JAR files to the Maven classpath. All other modules need to compile and run against the jars extracted from the ZIP file.
How can I add the JARs to the Maven class path for later compiling and test runs? The destination of the ZIP content is always the same directory. Unfortunately, the names of the JARs contain version information (build numbers) which change. So an easy usage of system and the tag is not working so easily. A path entry like ${package.path}/lib/*/.jar would be great. Is there a plugin, maybe?
Or does anyone have a better idea to setup an integration test against prebuild JARs?
Create a single jar from all of your dependencies, everything in ${package.path}/lib/*/.jar.
You could use an ant task to create this jar, either before you run maven, or as part of your maven build.
To merge your jars, you can use the Ant Jar Task (see section Merging Archives). From there:
<jar destfile="build/main/checksites.jar">
<fileset dir="build/main/classes"/>
<restrict>
<name name="**/*.class"/>
<archives>
<zips>
<fileset dir="lib/main" includes="**/*.jar"/>
</zips>
</archives>
</restrict>
</jar>
This creates a jar file which embeds all the classes from all the jars in lib/main.
You can then use the system scope which points at this jar as normal in maven. Note: if you create the jar in maven (via ant), then you should create the jar in target, so that it gets cleaned correctly.
To use an ant build file from maven, you can use the maven antrun plugin, similarly to:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<property name="local.project.artifact.name" value="${project.build.finalName}" />
<property name="local.distribution.artifact.name" value="${local.project.artifact.name}-distribution" />
<property name="local.distribution.artifact.file" value="${project.build.directory}/${local.distribution.artifact.name}.zip" />
<ant antfile="build-deploy.xml" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
This runs the ant build file build-deploy.xml in the package phase. The modifications necessary for your system are left as an exercise for the reader :-).

In the Eclipe PMD plugin, can I reference the standard ruleset files?

I would like my eclipse PMD plugin configuration to access the same standard ruleset files as the maven-pmd-plugin.
You can configure the maven pmd plugin to use a custom set of rule sets like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>2.5</version>
<configuration>
<rulesets>
<!-- Two rule sets that come bundled with PMD -->
<ruleset>/rulesets/braces.xml</ruleset>
<ruleset>/rulesets/naming.xml</ruleset>
<!-- Custom local file system rule set -->
<ruleset>d:\rulesets\strings.xml</ruleset>
<!-- Custom remote rule set accessed via a URL -->
<ruleset>http://localhost/design.xml</ruleset>
</rulesets>
</configuration>
</plugin>
but in the eclipse plugin you can only switch on / turn off individual rules or specify a single ruleset file. Is there perhaps a way that ruleset file can include several others? Or do I have to aggregate that file automatically from the rulesets I want to use?
You can include other rulesets in a PMD ruleset file, e.g.
<ruleset ...>
...
<rule ref="rulesets/basic.xml"/>
...
<rule ref="rulesets/strings.xml">
<exclude name="AvoidDuplicateLiterals"/>
</rule>
...
</ruleset>
This is actually an excerpt from our own ruleset file, so it is proven to work :-)
As you can see, you can exclude/include individual rules from your ruleset, or even reconfigure them. One caveat: you must not mix rules for different languages in a single ruleset. I.e. in our case, we had to create separate rulesets for Java and JSP.
I learned the tricks myself from this page.

Categories