In Tomcat 8.5.9, session.getAsyncRemote().sendText() method throws
java.lang.IllegalStateException: The remote endpoint was in state
[TEXT_FULL_WRITING]
I created a mutex acquired before calls to send methods and released after the call:
sendMutex.acquireUninterruptibly();
try{
session.getAsyncRemote().sendText(gson.toJson(message));
}catch(Exception exception){
logger.error("Session : "+session.getId()+" message : "+gson.toJson(message)+" exception : "+exception.getMessage(),exception);
}
sendMutex.release();
But exception is still thrown when this method is called. There are no calls to
session.getAsyncRemote().sendText() or session.getBasicRemote().sendText() other than this method. ServerEndpoint returns void in onMessage method.
Thanks
Been having the same issue.
I found this solution to work, seems not to create other problems.
this.session.getBasicRemote().sendObject(message);
instead of using
this.session.getAsyncRemote().sendObject(message);
Apparently this is a common issue with tomcat, and the way a websocket session instance can be accessed from different threads at the same times.
synchronized(ep)
{
this.session.getAsyncRemote().sendObject(message);
}
where ep is a static object, that did not work either in my experience.
Related
I have defined a whole camel context with routes using the component camel-http4. Basically, upon context startup, this route issues every 5 minuets an http request towards an external server. This works just perfect.
At some point I want to restart the camel context (using JMX), so I just do:
if (camelContext.getStatus().isStoppable()) {
camelContext.stop();
}
And later:
if (camelContext.getStatus().isStarttable()) {
camelContext.start();
}
Both operations appear to succeed, logs confirm actual stop and start. But when the first http request is issued, I get the following error:
java.lang.IllegalStateException: Connection pool shut down
at org.apache.http.util.Asserts.check(Asserts.java:34)[org.apache.httpcomponents:httpcore-nio:4.4.4 org.apache.httpcomponents:httpcore-osgi:4.4.4 org.apache.httpcomponents:httpcore:4.4.4]
at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:184)[org.apache.httpcomponents:httpcore-nio:4.4.4 org.apache.httpcomponents:httpcore-osgi:4.4.4 org.apache.httpcomponents:httpcore:4.4.4]
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251)[commons-codec:commons-codec:1.9 org.apache.httpcomponents:fluent-hc:4.5.2 org.apache.httpcomponents:httpclient-cache:4.5.2 org.apache.httpcomponents:httpclient-osgi:4.5.2 org.apache.httpcomponents:httpclient:4.5.2 org.apache.httpcomponents:httpmime:4.5.2]
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175)[commons-codec:commons-codec:1.9 org.apache.httpcomponents:fluent-hc:4.5.2 org.apache.httpcomponents:httpclient-cache:4.5.2 org.apache.httpcomponents:httpclient-osgi:4.5.2 org.apache.httpcomponents:httpclient:4.5.2 org.apache.httpcomponents:httpmime:4.5.2]
It looks like the connection pool is in an invalid state.
How can I force the pool re-creation when starting context ?
Is there other way to avoid this error ?
Versions:
camel-http4 2.17
apache httpclient 4.5.2
I saw already some posts saying the connection manager has to be shared by using (it's more a workaround) HttpClientConfigurer.
I define and inject my own client configurer, it does not work:
public class MyHttpClientConfigurer implements HttpClientConfigurer {
#Override
public void configureHttpClient(HttpClientBuilder httpClientBuilder) {
httpClientBuilder.setConnectionManagerShared(true);
}
}
Read the javadoc of those methods on the CamelContext to get details.
Instead of stopping camel context you should use suspend and resume it instead.
I'm trying to log the user name initiating each request in my JSF application, however apparently MDC on a web app server (thread pool) is risky.
I've already seen MDC leaking out into a new call when using the EJB #Asynchronous call which I wouldn't have expected.
What are the alternatives? I'd rather not have to rely on remembering to put the username on every log call. Do I wrap slf4j?
Clear your MDC put(..) with remove(..) in a try-finally block
MDC.put("system", "fedora");
try {
// your code here
} finally {
MDC.remove("system");
}
so that no state is kept after your code has run.
I've a spring web app running in a Tomcat server. In this there is a piece of code,in one of the Spring beans, which waits for a database connection to become available. My scenario is that while waiting for a database connection, if the Tomcat is shutdown, I should stop waiting for a DB connection and break the loop.
private Connection prepareDBConnectionForBootStrapping() {
Connection connection = null;
while (connection == null && !Thread.currentThread().isInterrupted()) {
try {
connection = getConnection();
break;
} catch (MetadataServerException me) {
try {
if (!Thread.currentThread().isInterrupted()) {
Thread.sleep(TimeUnit.MINUTES.toMillis(1));
} else {
break;
}
} catch (InterruptedException ie) {
logger.error("Thread {} got interrupted while wating for the database to become available.",
Thread.currentThread().getName());
break;
}
}
}
return connection;
}
The above piece of code is executed by one of the Tomcat's thread and it's not getting interrupted when shutdown is invoked. I also tried to achieve my scenario by using spring-bean's destroy method, but to my surprise the destroy method was never called. My assumption is that Spring application context is not getting fully constructed - since, I've the above waiting loop in the Spring bean - and when shutdown is invoked corresponding context close is not getting invoked.
Any suggestions?
Tomcat defines a life-cycle for Web applications (well, it's a kind of common specification aspect and not just tomcat specific, but anyway...)
So there is a way to hook into this process and terminate the loop or whatever.
In spring its very easy, because if tomcat shuts down gracefully, tomcat attempts to "undeploy" the WAR before actually exiting the process. In servlet specification in order to do that, a special web listener can be defined and invoked (you can see javax.servlet.ServletContextListener API for more information)
Now spring actually implements such a listener and once invoked, it just closes the application context.
Once this happens, your #PreDestroy methods will be called automatically. This is already a spring stuff, tomcat has nothing to do with that.
So bottom line, specify #PreDestroy method on your bean that would set some flag or something and it would close the logic that attempts to close the connection.
Of course all the stated above doesn't really work if you just kill -9 <tomcat's pid> But in this case the whole jvm stops so the bean is irrelevant.
I am working on a Java Portlet (extending GenericPortlet), using JBoss 7.02 and LifeRay Portal 6.1.0 GA1. This is one of the bundles that can be downloaded from LifeRay's release archive.
During deployment, when the init() method is called, getRequestDispatcher() returns null. Below is the exact error message:
09:22:15,972 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/my-portlet-name]] (MSC service thread 1-15) Error during mapping: java.lang.NullPointerException
Below is a snippet from my init() method:
PortletConfig config = getPortletConfig();
PortletContext context = getPortletContext();
PortletRequestDispatcher normalView = context.getRequestDispatcher("/portlet.jsp");
As a temporary workaround, I have moved all getRequestDispatcher() calls to doView() where it executes without problem. I do not understand why getRequestDispatcher() can locate portlet.jsp when called during doView, but not when its called during init()
Am I missing a preceding call of some other method that would resolve this? Is this a known issue?
Thanks for any help.
Getting the request dispatcher in the doView is the only place I've seen it done. I would imagine that it returns null during init because there is no actual request to dispatch.
Typically the init method is used for time-expensive operations that you don't want to incur for each request. This might be something like reading data from a file, or creating a reusable SQL connection.
You should also keep in mind that you should keep any portlet state thread safe. Don't create class or object variables that can only be used for one request at a time. The portlet methods are not inhererently thread safe, so you need to make sure that whatever variables a request is interacting with won't be manipulated by another request that is executing concurrently.
I'm not familiar with Portlets, but the answer should be the same as for Servlets.
The init() method is called exactly once, when your application is initially deployed. There is no active request (no one is asking for anything) or response (no one is going to read what the output is). Therefore, it is very reasonable forgetRequestDispatcher() to return null. In doView(), when you're handling a request and response, it makes sense to ask another resource to generate part (or all) of the response.
To address your question directly, getRequestDispatcher() has no problem locating portlet.jsp from init(); it's the request that's missing. (Where do you expect to see the result of portlet.jsp, anyway?)
If you do want to print some output during initialization, you can try logging it to a file, if your application is set up for that. Or, you can display data on System.out, if you know where the container's console is. (I use this second option quite often with servlets.)
I have an EJB3 application which consists of some EJB's for accessing a DB, and exposed via a Session Bean as a web service.
Now there are two things I need to find out:
1) Is there any way I can stop SQL exceptions from causing the web service from throwing a SOAP Fault? The transactions are handled by the container, and currently sql exceptions cause a RollBackException to be thrown, and consequently the transaction to be rolled back (desired behaviour) and the web service to throw a fault (not desired).
2) I wish to extend the webservice to be able to take in a list of entities, and the session bean to persist each. However, I want each entity to be executed in its own transaction, so that if one fails the others are not affected (and again the web service should not fault).
For (1) I have tried to catch the RollBackException, but I assume this is thrown somewhere on another thread, as the catch block is never reached. I assume for (2) I will need to look into User Transactions, but firstly would prefer the container to manage this, and secondly do not know how to force the use of user transactions.
Thanks.
no, you can do all this with container managed transactions (and this is definitely preferable, as managing transactions is a pain).
the gist of the solution is to create a second EJB with a local interface only and the transaction semantics you desire. then your "public" ejb, which the web-service is calling directly, calls into this second ejb via its local interface to do the actual work.
something along the lines of:
public class MyPublicEjb {
#EJB
private MyPrivateImpl impl;
public void doSomething() {
try {
impl.doSomething();
} catch(TXRolledBack) {
// handle rollback ...
}
}
}
I know this looks sort of ugly, but trust me, this is far preferable to directly manipulating transactions.
For (1): Debug your code to find out where the exception is being thrown and what is causing it. Then handle the exception there.
For (2): Wrap each instance with beginTransaction() and commit().
for(each Entity){
try{
//begin transaction
//save entity
//commit
} catch(Exception e) {
//handle Exception, but continue on
}
}