Deploying CXF webservices in Tomcat - cxf

I am trying to deploy a web service in Tomcat7 using maven.
Below I provide some configuration info:
web.xml
...
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
...
pom.xml
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>TomcatServer</server>
<path>/services/userinfo</path>
...
Given the <url-pattern>/services/*</url-pattern> and <path>/services/userinfo</path> configuration, the URL http://localhost:8080/services/userinfo shows 404.
If using instead <url-pattern>/*</url-pattern> everything works as expected (i.e. http://localhost:8080/services/userinfo shows the list of available methods).
The question:
Why /services/* doesn't work in my case?

The path in your tomcat-maven-plugin configuration
<path>/services/userinfo</path>
defines where you are deploying the webapp (the context root). In this case, you are deploying it to
http://localhost:8080/services/userinfo
Check out the webapps directory in your Tomcat installation.
Since you are defining the CXFServlet mapping as /services/*, the CXF service list would show at
http://localhost:8080/services/userinfo/services/
When you re-defined the mapping to /*, it just appeared to work as expected, but that was only because the context root you used and the service listing path you expected were the same.

Related

Google App Engine different web.xml config per environment?

I'm developing a Java app to be deployed on Google App Engine. Google App Engine allows me to include a web.xml file in my WEB-INF folder in which I can configure different levels of auth for different URLs.
If I want only admin users to be able to access the foobar URL, I can use this config:
<security-constraint>
<web-resource-collection>
<web-resource-name>aname</web-resource-name>
<url-pattern>/foobar/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
If I want any users - even unauthenticated users - to be able to access the foobar URL, I can use this config:
<security-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Here's the problem. In my test environment, I would like to authorize only admins to access foobar. But in my production environment, I would like to allow all users (included unauthenticated users) to access foobar. How can I achieve this? How can I change the web.xml config per environment?
You can keep different web.xml for each environments and replace while deploying into each environment.
E.g web_dev.xml, web_test.xml, web_prod.xml
Replace web_prod.xml to web.xml
I decided to implement a solution similar to what Vikram suggested, but slightly different.
Rather than having a single web.xml file in my WEB-INF folder:
- WEB-INF
+ web.xml
I instead created two folders (one for each environment) in my WEB-INF folder:
- WEB-INF
+ local
| + web.xml
+ prod
+ web.xml
Now, in order for Google App Engine to pick up the config file, it needs to be located in WEB-INF, not in the subdirectories I've created. Therefore, during the build, I use the Maven War Plugin to copy the files from one of the two folders into the parent folder.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF/${configDirectory}</directory>
<filtering>false</filtering>
<targetPath>WEB-INF</targetPath>
<includes>
<include>web.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
And I use Maven Profiles to specify the name of the folder containing the files which I want to actually use.
<profiles>
<profile>
<id>local</id>
<properties>
<configDirectory>local</configDirectory>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<configDirectory>prod</configDirectory>
</properties>
</profile>
</profiles>
So, the web.xml file gets copied from the correct subdirectory to the parent directory, thereby allowing me to control which config gets used each time I build the app.

Apache CXF Https issue

I have generated self signed certificate using keytool command. and successfully configured https at jboss fuse level and port assigned to it is 8443. https://localhost:8443/hawtio/login works perfectly fine. In apache cxf i am facing issue. following configuration is done in blueprint xml file.
<cxf:rsServer address="http://0.0.0.0:9192/"
id="serviceOrderEndpoint" serviceClass="pk.com.telenor.so.controller.ServiceOrder"/>
<cxfcore:bus/>
<httpj:engine-factory bus="cxf">
<httpj:engine port="8443">
<httpj:tlsServerParameters secureSocketProtocol="TLSv1">
<sec:keyManagers keyPassword="password">
<sec:keyStore resource="certs/jbossfuse-dev.jks" password="password" type="JKS"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore resource="certs/jbossfuse-dev.jks" password="password" type="JKS"/>
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_WITH_3DES_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:exclude>.*_WITH_NULL_.*</sec:exclude>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
<sec:clientAuthentication want="true" required="false"/>
</httpj:tlsServerParameters>
</httpj:engine>
</httpj:engine-factory>
I want to run it on https://localhost:9192/
In pom.xml file i have placed the following dependencies:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.0.M0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.5.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.2.3</version>
</dependency>
This is the issue that i am facing
Caused by: java.lang.ClassNotFoundException: org.apache.cxf.jaxb.JAXBDataBinding not found by org.apache.cxf.cxf-rt-wsdl
When you said "configured https at jboss fuse level " I believe you mean you configured in the $JBOSS_FUSE/etc/org.ops4j.pax.web.cfg.
Then as your cxf rs endpoint get deployed into the JBoss FUSE container, the best practice is that this endpoint use the servlet transport managed by this container(the HTTP OSGi service implmented by OPS4J PAXWEB with jetty), so your configuration address for the cxf:rsServer should be relative address like address="/myendpoint", then you can access it from
https://localhost:8443/cxf/myendpoint.
Also, as the https already configured at JBoss FUSE level, you don't need
<httpj:engine-factory bus="cxf">
...
</httpj:engine-factory>
stuff.
Freeman

queue.yaml not deployed when i use mvn appengine:deploy

I updated my pom.xml to use the new mvn appengine plugin
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<project>{project_id}</project>
<devserver.host>0.0.0.0</devserver.host>
<devserver.port>1984</devserver.port>
</configuration>
</plugin>
Now when I run mvn appengine:deploy it converts my queue.xml to queue.yaml in the staging directory. However this queue configuration is not deployed.
I have tried so many ways to deploy it to google cloud but nothing worked. This setup is for my cloud endpoints project setup. The documentations do not cover this.
This is the maven plugin code i added after trying your suggestion out .
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<project>{project_id}</project>
<devserver.host>0.0.0.0</devserver.host>
<devserver.port>1984</devserver.port>
</configuration>
</plugin>
I opened a similar issue on the project board
By default, only the app.yaml file is deployed (which represents the application).
If you want (in addition, or only) the queue.yaml, or even the cron or index, you need to specify those files inside the plugin configuration.
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.maven.plugin.version}</version>
<configuration>
<deployables>
<param>target/appengine-staging/app.yaml</param>
<param>target/appengine-staging/cron.yaml</param>
<param>target/appengine-staging/queue.yaml</param>
<param>target/appengine-staging/index.yaml</param>
</deployables>
</configuration>
</plugin>
Please remember that if you specificy certain files, the app.yaml files should be added as well. It is deployed by default only if the deployabels parameter is missing.
Playing with this parameter you can choose which files to deploy

debugging JAX-RS service registration on jboss AS 7.1

I have setup a very simple test application to try RESTeasy on Jboss AS 7.1.
Environment:
jboss-as-7.1.0.Final
eclipse 3.7 with Jboss Tools
maven 3
I followed the steps in the tutorial but did not get the same result. The webapp is deployed correctly and it appears in the admin console but it does not work as intended.
The server invariably tells me 404 Resource not available when I try to access http://localhost:8080/SeamSertalVision/services/test
There are 4 files in the whole project:
pom.xml
web.xml
RestApplication.java
Login.java
the pom.xml has one dependency which resolves fine:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>ch.sertal</groupId>
<artifactId>SertalVision</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>SertalVision</name>
<description />
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<resteasy.version>2.3.1.GA</resteasy.version>
</properties>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<outputDirectory>${basedir}/build/classes</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>${basedir}/src/main/webapp</warSourceDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<!-- Include the JBoss Maven repository so we can access JBoss artifacts -->
<repositories>
<repository>
<id>jboss-public-repository</id>
<name>JBoss Repository</name>
<url>https://repository.jboss.org/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jboss-public-repository</id>
<name>JBoss Repository</name>
<url>https://repository.jboss.org/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${resteasy.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
the web.xml is empty:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Sertal Vision</display-name>
</web-app>
the RestApplication.java is empty:
package ch.sertal.vision.server;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/services")
public class RestApplication extends Application {
}
the Login.java contains just one method for testing:
package ch.sertal.vision.server;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
#Path( "/test" )
public class Login {
#GET
#Produces(MediaType.TEXT_HTML)
public Response login() {
return Response.ok( "logged in" ).build();
}
}
that's the whole thing, as it was described in the tutorial (I believe). The deployment works fine. If I add a welcome-file entry to the web.xml it is displayed.
here is the jboss log after teh application is deployed:
WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager' or the 'java.util.logging.LogManager' service loader.
11:35:17,819 INFO [org.jboss.modules] JBoss Modules version 1.1.1.GA
11:35:18,016 INFO [org.jboss.msc] JBoss MSC version 1.0.2.GA
11:35:18,060 INFO [org.jboss.as] JBAS015899: JBoss AS 7.1.0.Final "Thunder" starting
11:35:18,721 INFO [org.xnio] XNIO Version 3.0.3.GA
11:35:18,722 INFO [org.jboss.as.server] JBAS015888: Creating http management service using socket-binding (management-http)
11:35:18,732 INFO [org.xnio.nio] XNIO NIO Implementation Version 3.0.3.GA
11:35:18,743 INFO [org.jboss.remoting] JBoss Remoting version 3.2.2.GA
11:35:18,755 INFO [org.jboss.as.logging] JBAS011502: Removing bootstrap log handlers
11:35:18,758 INFO [org.jboss.as.configadmin] (ServerService Thread Pool -- 26) JBAS016200: Activating ConfigAdmin Subsystem
11:35:18,770 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 31) JBAS010280: Activating Infinispan subsystem.
11:35:18,779 INFO [org.jboss.as.naming] (ServerService Thread Pool -- 38) JBAS011800: Activating Naming Subsystem
11:35:18,780 INFO [org.jboss.as.osgi] (ServerService Thread Pool -- 39) JBAS011940: Activating OSGi Subsystem
11:35:18,781 INFO [org.jboss.as.security] (ServerService Thread Pool -- 44) JBAS013101: Activating Security Subsystem
11:35:18,796 INFO [org.jboss.as.security] (MSC service thread 1-10) JBAS013100: Current PicketBox version=4.0.6.final
11:35:18,803 INFO [org.jboss.as.webservices] (ServerService Thread Pool -- 48) JBAS015537: Activating WebServices Extension
11:35:18,829 INFO [org.jboss.as.connector] (MSC service thread 1-9) JBAS010408: Starting JCA Subsystem (JBoss IronJacamar 1.0.7.Final)
11:35:18,856 INFO [org.jboss.as.naming] (MSC service thread 1-11) JBAS011802: Starting Naming Service
11:35:18,861 INFO [org.jboss.as.mail.extension] (MSC service thread 1-12) JBAS015400: Bound mail session [java:jboss/mail/Default]
11:35:18,911 INFO [org.jboss.as.connector.subsystems.datasources] (ServerService Thread Pool -- 27) JBAS010403: Deploying JDBC-compliant driver class org.h2.Driver (version 1.3)
11:35:18,937 INFO [org.jboss.ws.common.management.AbstractServerConfig] (MSC service thread 1-4) JBoss Web Services - Stack CXF Server 4.0.1.GA
11:35:19,014 INFO [org.apache.coyote.http11.Http11Protocol] (MSC service thread 1-2) Starting Coyote HTTP/1.1 on http--127.0.0.1-8080
11:35:19,288 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-13) JBAS010400: Bound data source [java:jboss/datasources/ExampleDS]
11:35:19,556 INFO [org.jboss.as.server.deployment.scanner] (MSC service thread 1-8) JBAS015012: Started FileSystemDeploymentService for directory /Development/jboss-as-7.1.0.Final/standalone/deployments
11:35:19,561 INFO [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) JBAS015003: Found SeamSertalVision.war in deployment directory. To trigger deployment create a file called SeamSertalVision.war.dodeploy
11:35:19,574 INFO [org.jboss.as.remoting] (MSC service thread 1-5) JBAS017100: Listening on /127.0.0.1:9999
11:35:19,574 INFO [org.jboss.as.remoting] (MSC service thread 1-11) JBAS017100: Listening on /127.0.0.1:4447
11:35:19,664 INFO [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.1.0.Final "Thunder" started in 2145ms - Started 134 of 205 services (70 services are passive or on-demand)
11:35:19,676 INFO [org.jboss.as.server.deployment] (MSC service thread 1-14) JBAS015876: Starting deployment of "SeamSertalVision.war"
11:35:20,028 INFO [org.jboss.web] (MSC service thread 1-13) JBAS018210: Registering web context: /SeamSertalVision
11:35:20,066 INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "SeamSertalVision.war"
My question is: how can I verify that my Webservice is being registered? There is no hint to his in the log but no error either. There must be something wrong but I can't see what it is.
I have an application on Tomcat with Jersey and there the log clearly shows which classes perform RESTful services.
thank you for your help.
You will not see if the REST service is registered during startup because the service only starts on-demand, then you will see something like this:
INFO [org.jboss.resteasy.cdi.CdiInjectorFactory] (http--127.0.0.1-8080-1)
Found BeanManager at java:comp/BeanManager
INFO [org.jboss.resteasy.spi.ResteasyDeployment] (http--127.0.0.1-8080-1)
Deploying javax.ws.rs.core.Application:
class my.rest.JaxRsActivator$Proxy$_$$_WeldClientProxy
I don't see a significant error in your configuration, but it's possible that you are missing a WEB-INF/beans.xml?
To get a working example of a JBoss7 with a REST service you can create a new project using the following archetype: org.jboss.spec.archetypes:jboss-javaee6-ear-webapp:7.0.2.CR2
(you have to change the version of all JBoss dependencies from 7.0.2.CR2 to 7.1.0.Final).

Jboss webservice error using topdown approach

I started creating a sample webservice using top-down approach in jboss4.2.2 GA.
From the wsdl, i generated stubs using wsconsume
I created a new java class: SalesTaxImpl implementing the interface in the generated stub. Configured #WebService with endpointInterface, portname, wsdllocation.
My war application has the following:
WEB-INF/classes/
WEB-INF/wsdl/SalesTaxService.wsdl
WEB-INF/web.xml
In web.xml i have,
<web-app>
<servlet>
<servlet-name>SalesTax</servlet-name>
<servlet-class>com.hp.np.ws.SalesTaxImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SalesTax</servlet-name>
<url-pattern>/tax</url-pattern>
</servlet-mapping>
</web-app>
After placing the war in <JBOSS_HOME>/server/default/deploy path, i am getting the following error:
19:25:05,046 INFO [DefaultEndpointRegistry] register: jboss.ws:context=JbossWST
opDown,endpoint=SalesTax
19:25:05,078 INFO [TomcatDeployer] deploy, ctxPath=/JbossWSTopDown, warUrl=.../
tmp/deploy/tmp13893JbossWSTopDown-exp.war/
19:25:05,171 ERROR [MainDeployer] Could not start deployment: file:/C:/jboss-4.2
.2.GA/server/default/deploy/JbossWSTopDown.war
org.jboss.ws.WSException: Cannot build meta data: Cannot get URL for: WEB-INF/ws
dl/SalesTaxService.wsdl
at org.jboss.ws.metadata.builder.jaxws.JAXWSWebServiceMetaDataBuilder.bu
ildWebServiceMetaData(JAXWSWebServiceMetaDataBuilder.java:207)
at org.jboss.ws.metadata.builder.jaxws.JAXWSServerMetaDataBuilder.setupP
roviderOrWebService(JAXWSServerMetaDataBuilder.java:50)
I tried giving different combination, but no luck

Resources