Initialization errors in EJB blocked deployment of the WebLogic application - java

I have a client class from third party jar that needs to be integrated in my WebLogic ear application. A #Startup #Singleton EJB is created to contain and call the initialization of this 3rd party client.
But during the initialization of the 3rd party client, it tried to create some of its own JMS connectors and failed (because no connection in a test environment), then it got stuck there and didn't return a client instance.
As a result, the deployment of my ear application got "Error Timed out waiting for completion: Activate State: STATE_DISTRIBUTED" and cannot complete a normal deployment and have a state Active.
I have tried to make the initialization method asynchronous or the whole singleton EJB asynchronous, but it didn't work out.
#Singleton
#Startup
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ClientStartupBean
{
ThirdPartyClient client = null;
public ClientStartupBean()
{
//some init
}
#PostConstruct
public void initialize()
{
try
{
Trace.info(TCI, MN, "Start to init 3rd party client");
client = ThirdPartyClient.getThirdPartyClient(some_init_para_a, init_para_b);
Trace.info(TCI, MN, "Finished init of 3rd party client");
}
catch (Exception e)
{
throw new EJBException(e);
}
}
//other stuff
}
I can see the 'Start to init..' in logs, but not the 'Finished init' in logs the line after initialization of 3rd party client.
What is a proper way to resolve this? Thanks in advance for your help,

Related

Keep Spring Boot application alive with websocket connection

My Spring Boot application is quite small and has one job: Act as a client by opening a websocket connection to a third-party website and listen for messages.
The problem is that after my javax.websocket.Endpoint implementation has been initialised and the connection has been created, my Spring boot application closes.
I would have thought that any open websocket connection would keep my application up and running?
I don't need an embedded servlet container so I have specifically set web-environment: false in application.yaml.
Is there a way to remedy this without adding a servlet container I will never use?
I fixed this by using OkHttpClient and initialising it with a #PostConstruct in my #Configuration. I annotated the listener with #Component and it now stays alive without needing the embedded servlet container.
#PostConstruct
void handleRequest() {
Runnable runnable = () -> {
while (true) {
try {
JSONObject requestBody = getRequestBodyFromInput(serverSocket.accept());
requestHandler.handleRequest(requestBody);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
new Thread(runnable).start();
}
I started a new thread on while socket would keep listening and I am not letting that new thread die by looping it over within while loop.
You simply could simply loop forever.
while (true) {}

Integrate a long running service into Spring boot framework

I have already implemented a kinesis stream consumer which will run forever and I want to integrate that into spring framework for monitoring and graceful shutdown. But I found I wasn't able to stop the consumer by the http shutdown request. More specifically, only the spring web app is stopped but not the consumer. Here's what I did:
I created a main class for spring as follows:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.addListeners(new ApplicationPidFileWriter("./app.pid"));
application.run(args);
System.out.println("I'm Here!!");
}
}
And in the entrance of consumer class, I added #EventListener(ApplicationReadyEvent.class) to the startConsumer method
#EventListener(ApplicationReadyEvent.class)
public static void startConsumer() throws Exception {
init();
...
int exitCode = 0;
try {
worker.run(); // will run forever
} catch (Throwable t) {
System.err.println("Caught throwable while processing data.");
t.printStackTrace();
exitCode = 1;
}
System.exit(exitCode);
}
The consumer successfully started after mvn package && java -jar myJar, but when I use use the http shutdown to stop the program, only the spring app stops. The consumer was still running.
Any idea on how to stop the consumer? Or more generally how to integrate a long running process into spring framework? I've tried non-web choice, but that prevents me from using http requests to do monitoring.
Any suggestion will be appreciated!!!
One important thing is that it is not correct to block execution in EventListener. You should start a thread from the event listener method and that thread will do processing for you. So you need to invoke Worker.run in a separate thread. Alternatively you can mark your event listener as #Async.
Now the problem is to stop it correctly when spring boot application is stopped.
In order to be able to react to shutdown events in spring you can implement SmartLifecycle in your bean.
When stop is invoked you need to stop the Worker. This answer has some good options how to do that.
Make sure you invoke the Runnable passed to stop when worker shutdown is complete. For more details see SmartLifecycle.stop javadoc.

How does class generation with Apache CXF work?

So, I've created a client stub application with Apache CXF from a WSDL. The process was relatively straight-forward. I did it within SoapUI interface. I supplied the WSDL location, told CXF to generate the client stub and hit okay.
Then, I imported the project into Eclipse, added the Apache CXF libraries, configured some security options, certs and whatnot.
I wrote a main with a few test calls to my webservice, and... it worked.
Now my problem is that I don't know WHY it worked. To be more specific, when I hit run in Eclipse, the debug output clearly shows that there are CXF classes being invoked.
INFO: Loaded configuration file cxf.xml.
and
org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
In my main() I'm invoking the
MyServices ss = new MyServices(wsdlURL, SERVICE_NAME);
port = ss.getWSHttpBindingMyService();
But the MyServices class extends javax.xml.ws.Service and there's nothing that hints to CXF.
wsdl2java also generated a MyService interface and a MyServiceImpl class that sits in the same package. It looks like a good candidate. In my main() I can write stuff like port.someMethod(someRequest). If I ctrl-click on someMethod and follow the implementation, it actually brings me to MyServiceImpl class but there's only dummy code there!
public Boolean someMethod(SomeRequest request) {
LOG.info("Executing operation");
System.out.println(request);
try {
Boolean _return = null;
return _return;
} catch (java.lang.Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
So there must be some configuration somewhere that is telling the runtime which implementation to use. But I cannot figure out where or which one it is.
Thanks
Whether you use cxf or wsdl2java to generate the client code .
The client code will be generated as per the J2EE specification.
The code generated is just the declaration of service , the implementation of service will be on server.
The client code make uses of the webservice wsdl location to find the service and the operation exposed by it.
Check in your MyServices , You will see your service URL.
Ex
wsdlLocation = `"http://127.0.0.1/bookstore/services/search?wsdl"`
Thanks

Weblogic Websocket endpoint not working

I'm trying to crete a simple Websocket application based on tutorial here: http://docs.oracle.com/javaee/7/tutorial/doc/websocket004.htm
So the code looks something like this:
#ServerEndpoint("/echo")
public class EchoEndpoint {
#OnMessage
public void onMessage(Session session, String msg) {
try {
session.getBasicRemote().sendText(msg);
} catch (IOException e) { ... }
}
}
I'm running Weblogic 12c. I thought the annotation should be automatically picked up and websocket endpoint created on the address localhost:8888/myApp/echo, but when I try to connect there with this js test: http://www.websocket.org/echo.html, nothing happens. Also when I attach debugger, I see that the EchoEndpoint class was not loaded. What else should I do to make it running? I see nothing else in the Oracle tutorial
The Tyrus library requires a JEE7 container, Weblogic only supports JEE6.
Follow this tutorial to get websockets in Weblogic.
http://docs.oracle.com/middleware/1212/wls/WLPRG/websockets.htm

Getting 2 Tomcat servers comminicating with each other

I have a Java web application I’m developing for a school project. There’s a requirement to have the presentation tier (servlets/jsp) be deployed to one server and business logic be deployed to another.
I need a solution to connecting the 2 servers.
Currently I’ve researching RMI and Axis2.
I’m not able to get RMI successfully working. I’m following official tutorial and keep getting a security exception locally, and imagine that it will get worse when Tomcat is involved.
Axis2 seems like a good solution, but I will need time to ramp up on it.
My question is: there a simple way of connection 2 servers so that I can call my business layer? Maybe Tomcat has something built-in.
If RMI is the de-facto protocol and API I should use, is there any good tutorials on using RMI with Tomcat.
Servers that I’m using are both running Tomcat.
I am not sure how complicated is your data layer but you can implement REST interface on business logic server using Apache CXF, for example. That should be easier than using Axis2.
There are many many options:
Write a file from one side, read it from the other. "the other" has to have an infinite loop to monitor the folder where "one side" writes request files.
Use sockets
Use REST
RMI
If you're on Linux:
Shared memory
Pipes
Given your environment I would go with REST.
I ended up using RMI. Using this tutorial I got it working: http://sacrosanctblood.blogspot.com/2008/11/rmi-tutorial-rmi-and-tomcat.html . The key is: in the start up servlet you have to make sure that the Object that you are stubbing out is class scoped and not method scoped. Also, the Security manager code is not needed.
Here's the code for the startServer servlet that I'm using:
public class startServer extends HttpServlet
{
public static boolean isRegistered = false;
public IRemote service = new RemoteImpl();
#Override
public void init(ServletConfig config) throws ServletException
{
super.init(config);
if (!isRegistered)
{
try
{
IRemote stub = (IRemote) UnicastRemoteObject.exportObject(service, 0);
Registry registry = LocateRegistry.createRegistry(9345);
registry.rebind(IRemote.serviceName, stub);
System.out.println("Remote service bound");
isRegistered = true;
}
catch (Exception e)
{
System.err.println("Remote service exception:");
e.printStackTrace();
}
}
}
}
And here's the client code:
public String getRemoteString()
{
String result = "";
try
{
Registry registry = LocateRegistry.getRegistry(9345);
IRemote serv = (IRemote) registry.lookup(IRemote.serviceName);
result = serv.executeRemote("Test");
}
catch (Exception e)
{
System.err.println("Remoteservice exception:");
e.printStackTrace();
}
return result;
}
Currently it's running all on the same server, but I'm sure that I can get the 2 working at a later time.

Categories