How to implement generic test for RMI connection, J2EE services? - java

I'd like to implement a little test to check connectivity to J2EE services over RMI. It needs to be generic, so that I could just give it a property file with the following properties set in it:
java.naming.factory.initial=oracle.j2ee.rmi.RMIInitialContextFactory
java.naming.security.principal=user
java.naming.security.credentials=pass
java.naming.provider.url=ormi://hostname:port/application
Checking the port is not sufficient, because other applications could be successfully deployed on the server. I can't assume that all applications in our environment have a default service with default method (like a ping method), which would make it much easier.
Is there a standard test I could perform using the java.naming.provider.url?

I settled for a method which isn't quite as generic as I would like, but which works.
Because all services are deployed on an Oracle OAS, I can execute opmnctl to get the status of the container and all applications. Not pretty, but it does the job.

Related

Assuming a CLI or Swing interface client, how is a remote Bean accessed through Liberty

I want to access to remote EJB running on Liberty Server from a swing Client like this :
Object found = new InitialContext().lookup(
"corbaloc:iiop:localhost:2809#ejb/ear/ejb.jar/package/Bean#com.package.BeanRemote);
I'm getting that error :
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or in an application resource file: java.naming.factory.initial
at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:691)
at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at java.naming/javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:342)
at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)
at com.package.ClassMain.main(ClassMain.java:43)
How is a connection to Liberty established?
Need help please
I'd strongly recommend you to re-architect your app to use JAX-RS (rest over http) instead of remote EJB. Just use Facade pattern and wrap your EJB as REST endpoints, and use Rest client on the Swing side.
There are several reasons:
remote EJB is almost dead technology now
http/rest is more firewall/network/container friendly
http/rest is more client agnostic - if you would later like to change your client from Swing to web/JS it will be much easier
But if you really insist, setting up remote EJB is not very simple.
The easiest would be to use Liberty Application client and run your Swing app from there.
If you cannot use that you will need to get traditional WebSphere Application Server Client, and use the client jar provided with that com.ibm.ws.ejb.thinclient_8.5.0.jar. If the client is running with a non-IBM java you will also need to add the orb jar onto the class path (com.ibm.ws.orb_8.5.0.jar).
See theses links:
how-to-set-up-thin-client-to-call-remote-ejb-on-liberty
Running the IBM Thin Client for Enterprise JavaBeans (EJB)
Using enterprise JavaBeans with remote interfaces on Liberty
So all in all, rewrite will be usually simpler and more beneficial.

Java RMI and Application Server

I am looking to implement a Java RMI Server in our corporate network. This Java RMI Server will provide information to our Java Eclipse Client. I have everything working when I run the Java RMI Server on a machine with RMIRegistry and the appropriate Java call to run the program.
I am looking for some advice/suggestions on how I can make it more robust. Specifically the Java RMI Server will connect to a SQL Server DB. How can I deal with things like DB Connection Pooling? How do I scale up the number of instances of the Java Server program to all of my users?
I'm sure there are a lot of things to consider and I was hoping for some clarity on whether or not I need to download something like JBoss or is it overkill?
I don't believe I'll be able to run the RMIRegistry and Java server program by itself but I'm not sure what my next steps are.
Thanks,
Kevin
You do not need to use JBoss to provide RMI services if you don`t need an application server. You can run spring over tomcat or even implement web services to increase interoperability.
Unless you have a truly specific need to do RMI, I'd simply punt on RMI and implement a web service against any of the servlet containers. It'll likely just be easier, if for no other reason there are zillions of others doing the same thing, so there's lots of support for it.
If you still feel you want to use RMI, consider instead using JMX.
JMX make RMI much more painless. Every VM has a JMX service running in it "for free" and JMX is running RMI underneath.
JMX is also rather ubiquitous in the Java world, so there are lots of tools that can be used to interact with your servers (such as JConsole).
JMX is basically the RMI transport, with a much friendlier surface for management.
It's very difficult today to justify a greenfield RMI app, frankly.

An embeddable web server with native #WebService support as an alternative to Endpoint.publish

I have spent some time on investigating what Endpoint.publish can and cannot do, and it appears that you very quickly enter undocumented territory.
In case you build a simple stand alone application which expose one or more #WebService annotated classes with Endpoint.publish and you then run into a situation where you cannot use Endpoint.publish any more (for any reason) what is then the simplest migration path?
I know that you can create a WAR with sun-jaxws.xml and optionally Metro jars which you can then deploy to an embedded web server (like Jetty or Winstone) but I like the simple "take THIS class and expose it at THIS url" API of Endpoint.publish() without any XML or full containers.
Is there a good way to do this?
It's been said that you can an instance of com.sun.net.httpserver.HttpServer to customize the HTTP behavior of the endpoint. It's always a good idea to be cautious of com.sun APIs but it might be appropriate depending your situation. There's an HttpsServer subclass that can be used to provide SSL, for example.
The process seems to be:
Use HttpServer.create(new InetSocketAddress(listenPortNumber), waitQueueDepth) to create a server instance.
Use server.createContext("/path") to create a context that will host the endpoint.
Create an endpoint with Endpoint.create(new RpcLitEndpoint()). It's not clear where RpcLitEndpoint is defined or whether it's strictly required; it may be part of Metro JAX-WS.
Call endpoint.publish(context) to associate the endpoint with the HttpServer (or HttpsServer) instance.
When done, use endpoint.stop and server.stop to shut down.
There's also a blog entry on blogs.oracle.com describing the creation of custom network transports. It didn't have enough detail for me to get a great understanding from a quick scan, but maybe you can get more out of it.

Remoting and OSGi

Is there an elegant way to use Services across or between OSGi containers?
Is it even possible?
For instance, lets say I have a service interface on my local machine. What methodologies/technologies can I use to get that service interface accessible through a remote OSGi container's BundleContext?
There is a RFC called Remote Services (formerly Distributed OSGi) that does exactly what you are trying to achieve. The RFC is almost completed, and there are already 2 implementations provided respectively by Apache CXF and Eclipse ECF.
Both the implementations allows to do transparent remoting of an OSGi service. You just have to define the OSGi service as usual, and add some configuration parameters to make it a remote service.
Check:
http://cxf.apache.org/distributed-osgi.html
It is possible, but there are no libraries (afaik) that will do this for you. I've rolled my own for my current job. OSGi runtime on client and server, RMI is the transport. I've had to make HEAVY use of Proxy objects.
Register a service in the server's OSGi runtime (Equinox). I have a listener that watches all services looking for a property/attribute indicating this service should be exported (made remote), something like "remotable=true". It's easy to filter using the ServiceTracker. Over RMI I instruct the client to create a Proxy object with the service interface. All calls to this proxy object are generically send back over RMI (a call like execService serviceid, method name, var args params) and then invoked on the REAL service.
I've left out some of the low level details, but you can probably sort it out. If you can stray away from RMI, you may want to look into Riena (there may even be a way to write an RMI transport for Riena, I just haven't bothered to try)
It's not very clear what you are trying to achieve. You have got a service, you can access it using RMI, and you need to available as an OSGi service?
I guess you could write an interface to you local machine service. You could then write a bundle that connectes to that service and exposes that interface in the OSGi service registry. Then, your main bundle could locate that service using the interface name or service name.
It shouldn't be too much work to get an RMI connection to your local service. Maybe some config options to establish the initial connection. It might be important to write a facade for your service before you publish it in OSGi, in order to achieve some form of decoupling, and perhaps to hide the fact that it is an RMI service.
But then maybe I completely misunderstood you and all this is useless.
As well as CXF above, there's also Eclipse ECF, which is a collection of communication frameworks and provies an early implementation of the OSGi 4.2 remote services (aka distributed OSGi). It works by registering a local service to which your client binds in the VM, then creates a proxy on the remote machine, and using a technology of your choice (RMI, WebServices etc.) can remote the calls.
Obviously this uses by-value method invocation syntax (which your service needs to know about) but other than that, any comms errors are RuntimeException.
It certainly is possibly. Check out https://docs.paremus.com//display/NIM20/Home which includes an OSGi RSA implementation that includes a high performance RMI distribution provider.
Check the chapter "Remote Services" in the OSGi specification version 4.2.
It defines a standard way for distributing services between several OSGi containers.
The brand new version 4.3 of the OSGi spec has even more detailed support for this - see chapter 6 Remote Services and 112 Remote Service Admin Service.

Testing Web Services Consumer

Here are some tools that I have found to test web services consumers:
http://www.soapui.org/
https://wsunit.dev.java.net/
Are there any others? I would prefer testing frameworks that are written in Java or Python.
I have used soapui by a maven plugin. It can create junit-linke reports to be run and analysed like unit tests. This can be easily integrated in continious build, also with the free distribution of soapui.
I've used Web Service Studio.
Web Service Studio is a tool to invoke web methods interactively. The
user can provide a WSDL endpoint. On clicking button Get the tool
fetches the WSDL, generates .NET proxy from the WSDL and displays the
list of methods available. The user can choose any method and provide
the required input parameters. On clicking Invoke the SOAP request is
sent to the server and the response is parsed to display the return
value.
This tool is meant for web service implementers to test their web
services without having to write the client code. This could also be
used to access other web services whose WSDL endpoint is known.
Also the Web Services Explorer in Eclipse which comes as part of the Web Tools Platform.
Through UDDI and WSIL, other applications can discover WSDL documents
and bind with them to execute transactions or perform other business
processes. The Web Services Explorer allows you to explore, import,
and test WSDL documents.
The Grinder is right up your ally with both Java and Python, that handles most web services, (SOAP/REST/CORBA/RMI/JMS/EJB) etc.
http://grinder.sourceforge.net/
You really need to be more specific: What is it that you want to test in your WS-consumer? That it calls the right WS? This looks a bit pointless - WS are a perfect place for mocking whatever may be called - without anything being called.
In order to test the consumer you'd otherwise be writing a Webservice that mocks the original, right? I'd suppose that the communication protocol that goes through the wire is not the clients domain - e.g. it's generated. So the only thing a WS-consumer's client sees is the interface. And there's nothing to test in an interface.
It might be that I completely misunderstood your question - please clarify if I did. I'll revise the answer then.

Categories

Resources