Integrating Web Services with J2EE
From the Microsoft Developer Network (MSDN):
A Web Service is a unit of application logic providing data and services to
other applications. Applications access Web Services via ubiquitous Web protocols and data
formats such as HTTP, XML, and SOAP, with no need to worry about how each Web Service
is implemented. Web Services combine the best aspects of component-based development
and the Web ...
In addition, Web Services can be characterised through their ability to describe themselves in a platform-independent, XML-based meta-language such as WSDL (Web Service Description Language) and their ability to federate through global, platform-independent, and XML-based registries such as UDDI (Universal Description, Discovery Integration).
As emphasised in the Sun Open Network Environment vision and to be put right into the core of the upcoming J2EE1.4 specification, Web Services and J2EE are an ideal match. J2EE is a mature and productive environment for developing and deploying application logic. Web Services provide a new degree of cross-platform interoperability especially wrt the Microsoft .NET cosmos that CORBA and IIOP have not been able to provide.
JBoss.Net is a plugin to the JBoss application server that should facilitate both
JBoss.NET is - for the time being -
NOT an attempt
to build an alternative implementation of .NET! For that purpose, please have a look at
the commercial Halycon iNet (Beta)
or the Mono Open Source project.
Overview and Team
For an introduction, please see this PowerPoint File that has been presented at the JBossOne Convention March 2002. The core guys behind Jboss.Net are Christoph G. Jung (Axis integration, .Net interoperability, EJB-Provisioning), Peter Braswell (JMX mappings, UDDI interfaces, JMS coupling), and Frederick N. Brier (Macromedia Flash support, XDoclet web service module).
Features and release plan
Jboss.net is currently released under 1.0 and has
been adopting the Apache Axis
package (Release Candidate 1, installed under
thirdParty/apache/axis).
Axis is a clean-room successor to Apache-SOAP 2.0 and comes with a
well-configurable, JAXRPC-compatible processing architecture that is quite similar to the JBoss container
concept (see the above overview slides). We aim to fit the Axis code optimally into the JBoss hot-deploying environment
such that MBeans and EJBīs can be straightforwardly exposed as Web Services and such that the basic
J2EE-related use-cases are supported.
The current features include:
org.jboss.net.axis.server.AxisService
MBean installs the basic Axis invocation engine to which the
dedicated transport servlet located in the embedded jboss-net.war talks to (has been tested with both Jetty and Tomcat).
(The org.jboss.net.axis.AxisInvocationHandler
that should originally ease the
construction of detached (dynamic) client proxies is deprecated and will soon vanish since the reflection
meta-data are too small for connecting to real-world web services ... rather we recommend using stubs as generated
by the wsdl2java tool and as integrated using the external web-service reference feature - see below).
org.jboss.net.jmx.server.MBeanProvider
handler that maps Web Service invocations directly to dedicated MBeans on the JMX bus. Similar to
the JMX way of invocation, any Web Method starts with a String-Array describing the signature of
the target Java method followed by the proper arguments. The corresponding
org.jboss.net.jmx.MBeanInvocationHandler
is also provided. Implemented, but not yet
fully tested, is the automatic WSDL (Web Service Description Language) emmission for such web services from the
JMX meta-information.
org.jboss.net.jmx.adaptor.server.RemoteAdapter
which exposes the full MBeanServer functionality as a Web Service (for client-side acccess you can use, e.g., the
org.jboss.net.jmx.adaptor.RemoteAdaptor
interface and the org.jboss.net.jmx.adaptor.RemoteAdaptorInvocationHandler
factory). Some of the relevant java types, such as javax.management.ObjectName and javax.management.Attribute, already have
a reasonable typemapping installed for that purpose.
org.jboss.net.axis.server.EJBProvider
allows to interface/map
Web Service invocations immediately to session beans. For that purpose, .wsr files can
be deployed as "client applications" within .ear files (<java/> modules). We allow
"<ejb-ref\>" entries in the Axis deployment descriptor to link the
naming environments of the Web Service to the corresponding EJBīs. This is exactly the same
mechanism that is usually used in the web.xml descriptor for being able to reroute bean-lookups
without changing the Servlet-code (see the WebContainer HowTo for that purpose). However, since there is usually
no code involved in exposing a web-service, this feature may dissappear in some future version.
org.jboss.net.axis.SetClassLoaderHandler
and
org.jboss.net.axis.ResetClassLoaderHandler
in the serverīs http transport chain. The first handler is installed
in the requestFlow and
remembers the old classloader in the messagecontext and associated the thread with the target serviceīs deployment classloader.
The latter is installed in the responseFlow and resets the association to the old loader after a successful call. Upon failure in each flow,
both handlers are able to reset the association.
org.jboss.net.axis.server.JBossAuthenticationHandler
and
org.jboss.net.axis.server.JBossAuthorizationHandler
. The first one is installed per-default in the http-transport
chain and maps the basic authentication data that has been extracted by a preceeding org.apache.axis.transports.http.HTTPAuthHandler
to a given JBoss security domain (as specified as a JNDI name in the handlers "securityDomain" parameter). The latter handler can
be inserted in the requestFlow of your particular Web-service to mimique a unix-style allow/denied roles authorization scheme (parameter
"securityDomain" as before, parameters "allowedRoles" and "deniedRoles" for controlling access to the
specified web service. See the servers axis-config.xml for that purpose.
org.jboss.axis.server.EntityBeanDeserializer
. The Deserializer is given a particular find method
and corresponding attributes from the entityīs state, such as the primary key attribute, which are the parameters to the
find method. During Deserialization, it will first obtain these attribute to get a reference to the entity instance through
the home interface and the find method and afterwards will set the remaining attributes and elements from the structure. This way, even
if your application has not yet been designed using value objects, e.g., because it is yet used with a browser-based
GUI and the WebContainer is hosted in-VM, you can easily extend it into a web-service.
org.jboss.net.axis.server.JBossTxHandler
and the org.jboss.net.axis.server.JBossResetTxHandler
will spawn a minimal user transaction around the
exposed Web-Service, or particular methods of the Web-Service. the org.jboss.net.axis.server.JbossForceSerHandler
is used
to ensure that serialisation is indeed done within the transaction borders.
Plans for the 2.0 release include adherence to the EJB2.1 specification wrt. EJB-related web service features and will address advanced issues like adopting the pending XML-related JSRīs (Java API for XML DataBinding - JAXB, Java API for XML Remote Procedure Call - JAX-RPC, Java API for XML Messaging - JAXM, Java API for XML Registries - JAXR), introducing lightweight Internet Transactions and providing more sophisticated bean interaction patterns. Eventually, we will also provide basic C#-, or .Net-Code that will speed up your building of Microsoft-enabled client applications.
How to build, install and use Jboss.net
Before you go on writing your first Web Service in Java, we recommend that you have a look at code and meta-data samples at the axis site.
To build, you can run either
or
cd build
build -Dmodules=jboss.net
or
cd build
build -Dgroups=plugins
or (this is for our friends of logical progression ;-)
cd build
build -Dgroups=optional
cd build
build -Dgroups=optional-plugins
To install : JBoss.net relies requires a WebContainer installation (Tomcat, Jetty; JBoss.net has currently been tested under Jetty) to realize the http transport facility. The necessary runtime libraries (lib/ext/axis.jar, deploy/lib/jboss-net.sar and client/jboss-net-client.jar) and configuration files (conf/default/axis-config.xml and client/client-config.xml) are installed as a part of the above BUILD step.
AxisService will register itself as a .wsr deployer at the org.jboss.system.MainDeployer
, hence simply putting a .wsr file (or a .wsr file embedded into some other
hierarchically structured deployment package, such as an .ear) into your deploy directory is enough.
If you would like to configure JBoss.net with a different WebContainer, please replace the dependency and
WarDeployer references in deploy/lib/jboss-net.sar!META_INF/jboss-service.xml (the way that
code and deployment descriptors are bundled is likely and hopefully to change in RH!)
by your favorite servlet-runner:
<server> <mbean code="org.jboss.net.axis.server.AxisService" name="jboss.net:service=Axis"> <depends>jboss.web:service=Jetty</depends> <attribute name="WarDeployerName">jboss.web:service=Jetty</attribute> <attribute name="RootContext">axis/</attribute> <attribute name="SecurityDomain">java:/jaas/other</attribute> </mbean> </server>
To test: The successfull installation of JBoss.net will be reported during the JBoss boot process (The WebContainer should acknowledge the deployment of the _axis_\<RootContext/> web application including the main AxisServlet, where <RootContext/> is the configurable URL infix that defaults to axis/ and under which the deployed Web-Services can be reached, see above).
After that, pointing your browser to http://localhost:8080/jboss-net/servlet/AxisServlet (or an equivalent address depending on the configuration of your WebContainer and the RootContext) should return the default "hello" response page of the AxisServlet.
When you start JBoss with the -Daxis.enableListQuery=true option (which you usually do not in a security-aware productive environment), a http://localhost:8080/jboss-net/services?list request should return an xml document describing the current configuration of the AxisEngine including the deployed services. The services section should look like:
<?xml version="1.0" encoding="UTF-8" ?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="RemoteAdaptor" provider="Handler"> <parameter name="handlerClass" value="org.jboss.net.jmx.server.MBeanProvider" /> <parameter name="ObjectName" value="jboss.net:service=Adaptor" /> </service> <service name="Administration" provider="java:MSG"> <parameter name="allowedMethods" value="AdminService" /> <parameter name="isStatic" value="true" /> <parameter name="methodName" value="AdminService" /> <parameter name="enableRemoteAdmin" value="false" /> <parameter name="className" value="org.apache.axis.utils.Admin" /> </service> <transport name="http"> <requestFlow> <handler type="java:org.apache.axis.handlers.http.HTTPActionHandler" /> <handler type="java:org.apache.axis.handlers.http.URLMapper" /> <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler" /> <handler type="java:org.jboss.net.axis.SetClassLoaderHandler" /> <handler type="java:org.jboss.net.axis.server.JBossAuthenticationHandler" /> </requestFlow> <responseFlow> <handler type="java:org.jboss.net.axis.ResetClassLoaderHandler" /> </responseFlow> </transport> <typeMapping encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" serializer="org.jboss.net.jmx.adaptor.ObjectNameSerializerFactory" deserializer="org.jboss.net.jmx.adaptor.ObjectNameDeserializerFactory" type="java:javax.management.ObjectName" qname="ns1:ObjectNameType" xmlns:ns1="http://net.jboss.org/jmx" /> </deployment>
We recognize inter alia the already mentioned end-point of the RemoteAdaptor web service that
is mapped (via the org.jboss.net.jmx.server.MBeanProvider
) to a dedicated MBean with JMX-ObjectName "jboss.net:service=Adaptor".
Indeed, if you have a look at your current JMX state there
should be the corresponding service up and running, ready to take your Web Invocations through
the JMX bus.
In the JBoss.net testsuite,
we have assembled some samples and tests that can serve as an inspiration and source of insight.
You can build and run the testsuite against a running jboss server as follows (after having built the main jboss-all/testsuite!)
cd jboss.net/testsuite
build tests-standard-unit
In the output directory, there will be some deployable Web Services (output/lib/addr.wsr is the JBoss-compatible package containing the Axis Address example, output/lib/hello.ear is a J2EE application consisting of the hello ejb module from the JBoss main testsuite and an additional web service layer on top of the HelloBean). In output/bin we also have put some (non-functional, arrgh) batch files to run the individual tests.
Under samples/win, we have checked-in a tiny C#/.Net-based client application that can be run against the advanced store-test from the above testsuite. You can play around especially with the "Add Web Reference" functionality to see how programming against the live server and the wsdl-descriptions can be achieved. For example, you can access the meta-data of the BusinessPartnerService bean under http://localhost:8080:/jboss-net/services/BusinessPartnerService?wsdl once the store.ear is deployed.
DISTRIBUTION AND CVS
JBoss.net is shipped with JBoss 3
It isavailable as source under the CVS module contrib/jboss.net
The TODO and BUG list can be found under Sourceforge.
PROBLEMS
Axis questions should be directed to axis-users@xml.apache.org
JBoss questions should be directed to jboss-user@list.sourceforge.net
I shall be happy to answer questions about the integration.
Enjoy.
"Dr. Schorsch" (christoph.jung@jboss.org) - 29/09/2001, Last update on 30/03/2002
All mentioned trademarks on this page are copyright of their respective owners ... or so ...