How can I list all deployed jax-ws webservices? - java

I have deployed some jax-ws webservices in a tomcat:
web.xml:
...
<servlet>
<servlet-name>WebServiceJaxWs</servlet-name>
<servlet-class>...a bean of mine which overwrites WSServletDelegate</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
...
The webservices themselves are defined in the sun-jaxws.xml
They work just fine.
I now need to write a jsp, which displays all deployed webservices. I have access to the servlet context, but I simple cannot find a way to access the WebServiceJaxWs Servlet. My idea was to access it and then enumerate the published endpoints.
Any ideas?

The manual way I can think of is to parse your sun-jaxws.xml and get the information from there.

Maybe you could deploy all those web services as JMX beans and see them using JConsole.

Related

What is the purpose of CXF servlet

I was going through a demo project setup for Restful webservice using Apache CXF, where I happened to come by a piece of code inside web.xml:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
I did not really understand the use of a servlet class in this web.xml. I googled for org.apache.cxf.transport.servlet.CXFServlet and found:
The CXFServlet class, which is defined by Apache CXF, is generated and
registered to handle incoming requests.
Now, I really do not understand what that line means
Does this servlet pose as a front-controller, like in Spring MVC flow?
What is the actual purpose of using this servlet class?
How does CXF use Spring to provide XML configuration of services defined in the project?
Does org.glassfish.jersey.servlet.ServletContainer serve the same purpose in Jersey Implementation as org.apache.cxf.transport.servlet.CXFServlet with Apache CXF?
Help me clarify these questions.
The JAX-RS specification is built on top of the Servlet specification. Each implementation should have a Servlet as an entry point to the application. When a request comes in, it gets processed by that Servlet. CXFServlet is CXF's implementation of that entry point Servlet.
Does this servlet pose as a front-controller, like in Spring MVC flow?
Pretty much. It's analogous to Spring MVC's DispatcherServlet
What is the actual purpose of using this servlet class?
As mentioned above, it's the entry point to the JAX-RS (CXF) application.
How does CXF use Spring to provide XML configuration of services defined in the project?
It uses Spring to wire up components; connect all of them together. But it's not required (see also).
Does org.glassfish.jersey.servlet.ServletContainer serve the same purpose in Jersey Implementation as org.apache.cxf.transport.servlet.CXFServlet with Apache CXF?
Pretty much.

Does Tomcat support JAX-RS out of the box (is it JAX-RS aware)?

From the textbook "RESTful Java with JAX-RS" we can read:
If our application server is JAX-RS-aware or, in other words, is tightly integrated with JAX-RS declare our ShoppingApplication class as a servlet:
<?xml version="1.0"?>
<web-app>
<servlet>
<servlet-name>Rest</servlet-name>
<servlet-class>
com.restfully.shop.services.ShoppingApplication
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
If our application server is not JAX-RS-aware, you will have to specify the JAX-RS provider's servlet that handles JAX-RS invocations. The Application class should be specified as an init-param of the servlet:
Now my question is: Is Tomcat a JAX-RS aware Servlet container? How do you distinguish a servlet container JAX-RS aware from one which is not JAX-RS aware? Why in the first case it's possible to use your custom class which extends javax.ws.rs.core.Application as a Servlet?
"Is Tomcat a JAX-RS aware Servlet container?"
No.
"How do you distinguish a servlet container JAX-RS aware from one wich is not JAX-RS aware?"
The fact this it is only a Servlet container, should tell you that it is not "JAX-RS aware". JAX-RS is part of the Java EE specification. Servlet containers supports exactly what their name implies; a container for Servlets. They might have support for other little features like JSP, but will not support the entire EE spec. This is not part of their design. If you want to use JAX-RS in a Servlet container, you need to add an implementation, like Jersey or Resteasy
When you say Servlet container you think of servers like Jetty, Tomcat, Undertow, Grizzly. If you want full Java EE support then you need to get an actual Java EE application server that supports the entire spec, like JBoss/Wildfly, Glassfish, TomEE, WebSphere, WebLogic.
"Why in the first case it's possible to use your custom class wich extends javax.ws.rs.core.Application as a Servlet?"
I was not able to produce a working example with either Glassfish 4.0 or Wildfly 8.1, nor is this specified anywhere in the JAX-RS specification. In Glassfish, I'll get an exception about ShoppingApplication not being a Servlet, and in Wildfly I'll just get a NotFoundException, meaning the application is never loaded.
The closest thing I could find to what the book states, is to specify the name of the application class as the <servlet-name> (which is part of the JAX-RS spec, but is not at all dependent on being deployed to a Java EE server)
<servlet>
<servlet-name>com.restfully.shop.services.ShoppingApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.restfully.shop.services.ShoppingApplication</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
This is from the JAX-RS spec
If an Application subclass is present that is not being handled by an existing servlet, then the servlet added by the ContainerInitializer MUST be named with the fully qualified name of the Application subclass.
Read JAX-RS spec - Plublication - 2.3.2 Servlet for the completely specification on standard JAX-RS deployment options. Any other deployment/configuration option not specified is implementation specific.

How to dynamically configure the WebLogicCluster property outside of web.xml

I have a web application deployed as war file in weblogic 10.3.3. Now I want to make this application clusterable. For this I'm using the HttpClusterServlet from Weblogic as a load balancer. According to the documentation I can put this servlet configuration into the web.xml
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>server-1:7122|server-1:7123</param-value>
</init-param>
</servlet>
The problem is that this configuration is hard wired at build time and can't be reconfigured at runtime. For instance I would like to be able to add 5 more servers dynamically. I had several ideas to solve that problem:
Extend the weblogic.servlet.proxy.HttpClusterServlet with an own servlet implentation. This is not possible, the class is final.
Use a servlet filter to reconfigure the servlet. The servlet is not accessible anymore through ServletContext().getServlet(String) since Java Servlet API 2.1, with no direct replacement.
Reflection might be an option, but I couldn't figure out a reliable way to access the configuration
All of my attempts to reconfigure this init-param externally failed so far. I'm open to any solutions.
This might help How to externalize web.xml servlet init-param? Spring DelegatingFilterProxy for Servlets? Even if your not using Spring it wouldn't be too hard to port that servlet to another IoC container.

Is there a generic way to specify the context-root for a WebService?

I'm new to writing web services, and am struggling with understanding how to specify the context root.
I've got my class annotated with
#Service
#javax.jws.WebService(endpointInterface= "com.domain.clientservices.lendingsimulation.model.v1.LendingSimulationServicePortType", targetNamespace="http://www.domain.com/ClientServices/LendingSimulation/V1.2", serviceName="LendingSimulationService", portName="LendingSimulationServicePort")
but I am not sure how to configure the context-root/path for it. I read that I could configure it as a servlet in web.xml, but that seems to be the case for a web service that is not annotate. Am I wrong? I have tried the following configuration in web.xml:
<servlet>
<description>This is the description for the LendingSimulation Service</description>
<display-name>Lending Simulation Service</display-name>
<servlet-name>LendingSimulationService</servlet-name>
<servlet-class>com.domain.clientservices.lendingsimulation.service.LendingSimulationServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LendingSimulationService</servlet-name>
<url-pattern>/WebService</url-pattern>
</servlet-mapping>
however, when I launch in JBoss, I get an error msg:
17:39:33,710 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/LendingSimulationService].[LendingSimulationService]] (http--127.0.0.1-8080-2) Allocate exception for servlet LendingSimulationService: java.lang.ClassCastException: com.domain.clientservices.lendingsimulation.service.LendingSimulationServiceImpl incompatible with javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1156) [jbossweb-7.0.1.Final.jar:7.0.2.Final]
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:952) [jbossweb-7.0.1.Final.jar:7.0.2.Final]
... (omitted for brevity)
I've read that I can configure jboss-web.xml specifically, but I assume there is a more generic way of doing this that can be applied to all app servers - isn't there? Or must I configure the service independently, depending on the AS that I am deploying to (ie: one way for Tomcat, one way for GlassFish, one way for JBoss, one way for WebSphere, etc...).
Is there an annotation I can use to specify my path for the web-service? Or a config param in the web.xml file?
Thanks!
Eric
Turns out that the JBoss error I was getting was due to the webservices module not being enabled. In JBoss7.0/7.1, you need to run the standalone-preview.xml config to get webservices for an out-of-box download: ie: standalone.sh --server-config=standalone-preview.xml. That eliminated the ClassCast/Servlet exception. However my question still remains if there is not a better/other way to accomplish this (perhaps via annotations) than declaring it as a servlet in web.xml.

Deploy web service on Tomcat with OpenEJB

I need to deploy web service on Tomcat with installed OpenEJB.
I compiled simple Hello service that just prints "Hello" with JAX-WS and tried to deploy on tomcat, but got errors while deployment :
ERROR - Error deploying CXF webservice for servlet helloservice.endpoint.Hello
java.lang.IllegalArgumentException: Could not find servlet helloservice in web application context /helloservice
Please, help what is done wrong here.
Is tomcat + openejb is sufficient for web service deployment?
Thanks.
For others who might be looking to do web services with Tomcat/OpenEJB, here's a simple example that uses an transactional EJB web service to add/list/delete records with JPA:
https://svn.apache.org/repos/asf/openejb/tags/openejb-3.1.2/examples/webapps/moviefun/
The example also includes a Perl SOAP::Lite client that can read/write to the web service.
Please, help what is done wrong here.
Is tomcat + openejb is sufficient for
web service deployment?
A servlet/JSP engine is sufficient for web development. You don't need OpenEJB for that.
"Service" is a loaded term. Do you mean "SOAP web service"? Or "EJB stateless session bean"?
Check your web.xml. Sounds like you failed to declare a servlet named helloservice. It ought to look like this:
<servlet>
<servlet-name>helloservlet</servlet-name>
<servlet-class>com.your.package.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloservlet</servlet-name> <!-- names must match -->
<url-pattern>*.html</url-pattern>
</servlet-mapping>

Categories