Deploy a webservice under Mule ESB using CXF
This short tutorial is aimed at showing the main steps allowing to deploy a WebService, using CXF framework, under a Mule ESB instance.
Java code
Declare an interface:
[java]@WebService
public interface BasicExampleServices {
@WebResult(name = "myReturnedInteger")
Integer getInteger(@WebParam(name="myInteger") Integer myInteger);
}[/java]
Implement this interface:
[java]@WebService(endpointInterface = "com.lalou.jonathan.services.BasicExampleServices", serviceName = "basicExampleServices")
public class WSBasicExampleServices implements BasicExampleServices {
public Integer getInteger(Integer param) {
return 12345;
}
}[/java]
XML files
Create a Spring config file ws-basicExample.xml
:
[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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="basicExampleService" scope="singleton"/>
</beans>[/xml]
Create a Mule configuration file ws-basicExample-config.xml
:
[xml]<?xml version="1.0" encoding="UTF-8" ?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:management="http://www.mulesource.org/schema/mule/management/2.2"
xmlns:stdio="http://www.mulesource.org/schema/mule/stdio/2.2"
xmlns:cxf="http://www.mulesource.org/schema/mule/cxf/2.2"
xmlns:jetty="http://www.mulesource.org/schema/mule/jetty/2.2"
xsi:schemaLocation="http://www.mulesource.org/schema/mule/management/2.2
http://www.mulesource.org/schema/mule/management/2.2/mule-management.xsd
http://www.mulesource.org/schema/mule/core/2.2
http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.mulesource.org/schema/mule/vm/2.2
http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
http://www.mulesource.org/schema/mule/cxf/2.2
http://www.mulesource.org/schema/mule/cxf/2.2/mule-cxf.xsd
http://www.mulesource.org/schema/mule/stdio/2.2
http://www.mulesource.org/schema/mule/stdio/2.2/mule-stdio.xsd">
<spring:beans>
<spring:import resource="ws-basicExample.xml"/>
</spring:beans>
<model name="wsBasicExampleModel">
<service name="wsBasicExampleService">
<inbound>
<cxf:inbound-endpoint address="http://localhost:8282/services/basicExampleServices"/>
</inbound>
<component>
<spring-object bean="basicExampleService"/>
</component>
</service>
</model>
</mule>
[/xml]
Checks
- Run the Mule, pointing your config file.
- In your favorite webbrowser, open the URL:
[xml]http://localhost:8282/services/basicExampleServices?wsdl[/xml] - You can also execute a runtime test:
[java]public class WSBasicExampleServicesRuntimeTest {
private BasicExampleServices basicExampleServices;
@Before
public void setup() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setServiceClass(BasicExampleServices.class);
factory.setAddress("http://localhost:8282/services/basicExampleServices");
basicExampleServices = (BasicExampleServices) factory.create();
}@Test
public void testGetInteger() {
final Integer expectedAnswer = 12345;
final Integer actualAnswer;
final Integer param = 912354;actualAnswer = basicExampleServices.getInteger(param);
assertNotNull(actualAnswer);
assertEquals(expectedAnswer, actualAnswer);
}}[/java]
The webservice contract is expected to be displayed.
Tutorial: Tomcat / OpenJMS integration
Install and Config
- Let’s assume you would like to run OpenJMS and Tomcat on the same server, eg
myLocalServer
- Download OpenJMS from this page.
- Unzip the archive, extract it to
C:\exe\openjms-0.7.7-beta-1
- Set an environment variable:
set OPENJMS_HOME=C:\exe\openjms-0.7.7-beta-1
- Take the archive
$OPENJMS_HOME/lib/openjms-tunnel-0.7.7-beta-1.war
- copy it to:
$CATALINA_HOME/webapps
- rename it as:
openjms-tunnel.war
- copy it to:
- Edit
OPENJMS_HOME/config/openjms.xml
:- Before the ending tag
</connectors>
, add the block:<Connector scheme="http"> <ConnectionFactories> <ConnectionFactory name="HTTPConnectionFactory"/> </ConnectionFactories> </Connector>
- After the ending tag
</connectors>
, add the block:<HttpConfiguration port="3030" bindAll="true" webServerHost="myLocalServer" webServerPort="8080" servlet="/openjms-tunnel/tunnel"/>
- Before the ending tag
Run applications
- Launch
$OPENJMS_HOME/bin/startup.bat
. The following output is expected:OpenJMS 0.7.7-beta-1 The OpenJMS Group. (C) 1999-2007. All rights reserved. http://openjms.sourceforge.net 15:15:27.531 INFO [Main Thread] - Server accepting connections on tcp://myLocalServer:3035/ 15:15:27.547 INFO [Main Thread] - JNDI service accepting connections on tcp://myLocalServer:3035/ 15:15:27.547 INFO [Main Thread] - Admin service accepting connections on tcp://myLocalServer:3035/ 15:15:27.609 INFO [Main Thread] - Server accepting connections on rmi://myLocalServer:1099/ 15:15:27.609 INFO [Main Thread] - JNDI service accepting connections on rmi://myLocalServer:1099/ 15:15:27.625 INFO [Main Thread] - Admin service accepting connections on rmi://myLocalServer:1099/ 15:15:27.625 INFO [Main Thread] - Server accepting connections on http-server://myLocalServer:3030/ 15:15:27.625 INFO [Main Thread] - JNDI service accepting connections on http-server://myLocalServer:3030/ 15:15:27.625 INFO [Main Thread] - Admin service accepting connections on http-server://myLocalServer:3030/
- Launch Tomcat. A webapp with path
/openjms-tunnel
and display name “OpenJMS HTTP tunnel” should appear.
Checks
-
- Open Console² or an MS-DOS prompt
- Go to
$OPENJMS/examples/basic
- Run:
build
. This will compile all the examples.
Check that OpenJMS is OK:
-
- Edit
jndi.properties
,- Comment the property
java.naming.provider.url
- Add the line:
java.naming.provider.url=tcp://myLocalServer:3035
- Comment the property
- Run:
run Listener queue1
- Open a second tab
- Run:
run Sender queue1 5
- Expected output in the second tab:
C:\exe\openjms-0.7.7-beta-1\examples\basic>run Sender queue1 5 Using OPENJMS_HOME: ..\.. Using JAVA_HOME: C:\exe\beaweblo922\jdk150_10 Using CLASSPATH: .\;..\..\lib\openjms-0.7.7-beta-1.jar Sent: Message 1 Sent: Message 2 Sent: Message 3 Sent: Message 4 Sent: Message 5
- Expected output in the first tab:
C:\exe\openjms-0.7.7-beta-1\examples\basic>run Listener queue1 Using OPENJMS_HOME: C:\exe\openjms-0.7.7-beta-1 Using JAVA_HOME: C:\exe\beaweblo922\jdk150_10 Using CLASSPATH: .\;C:\exe\openjms-0.7.7-beta-1\lib\openjms-0.7.7-beta-1.jar Waiting for messages... Press [return] to quit Received: Message 1 Received: Message 2 Received: Message 3 Received: Message 4 Received: Message 5
- Expected output in the second tab:
- Edit
Check that OpenJMS/Tomcat link is OK:
Manual Check
-
- Stop the
Listener
instance launched sooner - Edit
jndi.properties
,- Comment the line
java.naming.provider.url=tcp://myLocalServer:3035
- Add the line:
java.naming.provider.url=http://myLocalServer:8080
(this is Tomcat manager URL)
- Comment the line
- Run:
run Listener queue1
- Open a second tab
- Run:
run Sender queue1 5
- The expected output are the same as above.
- Stop the
GUI Check
- Stop the
Listener
instance launched sooner - Ensure
jndi.properties
contains the line:java.naming.provider.url=http://myLocalServer:8080
- Run:
$OPENJMS_HOME/bin/admin.bat
- A Swing application should start.
- Go to:
Actions > Connections > Online
- The queue
queue1
should be followed by a ‘0’. - Run:
run Sender queue1 50
-
Action > Refresh
- The queue
queue1
should be followed by a ’50’.
-
- Run:
run Listener queue1
-
Action > Refresh
- The queue
queue1
should be followed by a ‘0’.
-
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]
Petite enigme
Hier, on m’a presente l’enigme suivante:
Enonce
Il y a une salle, avec un interrupteur unique, qui allume une lampe unique. Cette lampe ne chauffe pas.
10 personnes sont dans la salle d’attente.
Une personne est appelee de maniere aleatoire. Elle peut allumer et eteindre la lampe, mais pas communiquer d’une quelconque maniere avec les autres membres du groupe. Ensuite elle retourne au groupe, et une autre personne est appellee.
Les personnes peuvent discuter avant l’epreuve pour mettre au point une strategie.
Question: comment faire pour qu’a un moment donne, une personne puisse affirmer “nous sommes deja tous passes au moins une fois”?
Solution
Soit n le nombre de personnes presentes initialement. Il est possible de restreindre initialement le probleme: en effet, il est equivalent que n=10 ou si n=4, voire meme n=3. En dessous de ce chiffre le probleme ne se pose evidemment plus.
Il y a deux facons d’aborder l’enigme. La premiere consiste a voir les 4 personnes comme des “pairs” (peers), chacun etant “egal” aux autres. Cette voie, que j’ai exploree, ne m’a pas permis de deboucher sur une solution.
La seconde facon consiste a considerer que parmi les 4, il y a 3 bonhommes “normaux“, egaux entre eux, et 1 “super“-bonhomme, avec des droits de “super user”.
Accordons donc les droits suivants:
- chaque bonhomme “normal” a le droit d’allumer une, et une seule, fois la lampe, a un moment bien choisi.
- le “super” bonhomme est le seul a avoir le droit d’eteindre la lampe.
Voici donc l’algorithme de resolution:
- Lorsqu’un bonhomme “normal” est appele:
- Si la lumiere est deja allumee, il ressort.
- Si la lumiere est eteinte et que le bonhomme courant n’a jamais allume la lampe, alors il l’allume.
- (De cette maniere, on s’assure que le bonhomme normal allume au plus une fois.)
- Le “super” user initialise un compteur a 0. Lorsque le super user est appele:
- Si la lumiere est deja allumee, il incremente son compteur, et il eteint la lumiere.
- Si la lumiere est eteinte, il ressort.
D’un point de vue mathematique, on se trouve face a un univers de probabilites discretes. D’apres la loi faible des grands nombres, au bout d’un temps suffisament long, le compteur atteint le nombre d’utilisateurs “normaux” (autrement dit: n-1, lui-meme sachant qu’il est deja passe). Il peut alors s’exclamer: “nous sommes tous deja passes au moins une fois!”.
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] <source path=’client’/>[/xml]
with:
[xml]<source path=’client’ excludes="**/*UnitTest.java,**/*RuntimeTest.java"/>[/xml]
NB: Never forget that Google teams work with Ant, and not with Maven!
Error 403 with Maven 2 deployment
Case
This morning, I tried to redeploy an EAR on a WebLogic 9.2, using Maven 2 and a classical deployment profile. I got this issue:
[java][ERROR] BUILD ERROR
[INFO] ————————————————————————
[INFO] Error executing ant tasks
Embedded error: The following error occurred while executing this line:
(…)
weblogic.deploy.api.internal.utils.DeployerHelperException: The source ‘C:\DOCUME~1\myLogin\LOCALS~1\Temp\myApplication-ear.ear’ for the application ‘my-application-ear’ could not be loaded to the server ‘http://myServer:1234/bea_wls_deployment_internal/DeploymentService’.
Response: ‘403: Forbidden’ for url: ‘http://myServer:1234/bea_wls_deployment_internal/DeploymentService'[/java]
Yesterday, I got a similar error when I launched a mvn tomcat:deploy
to deploy a WAR on a Tomcat 6.0 server:
[java][ERROR] BUILD ERROR
[INFO] ————————————————————————
[INFO] Cannot invoke Tomcat manager
Embedded error: Server returned HTTP response code: 403 for URL: http://myServer:3210/manager/deploy?path=%2FmyWebArchive&war=&update=true[/java]
Quick Fix
Running Maven2 in offline line, ie adding the option "-o"
, allows me to redeploy both the EAR on WebLogic and the WAR on Tomcat.
eg: mvn tomcat:deploy -o
I keep on investigating on this matter. I think there is an issue on the DNS. Indeed, when I deploy locally to my own machine myServer
(ie with its network name), this error is raised, but when I deploy to localhost
the build is successful.
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 thepom.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 toMyDependedProject.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. - Add the source
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.
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
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.