JCR session closed by container causes duplicate attempt to close session - java-ee-6

In my EJB I use a JCR session to store a File. I then logout of the session and throw a CDI event. The EJB which observes the CDI event then creates a new JCR session in which it wants to use the stored file. (Note: I had to add a delay in order to get this to work because for some reason the file wasn't available directly after storing it). After the method is done with using the file I also logout of this session. However after 15 minutes I get the exception "Attempt to close session-a84d60ac-1c8f-4cad-bc5a-84102b12f8e5-385 after it has already been closed." with stacktrace :
Stack trace of the duplicate attempt to close session-c7bc3b30-9a5f-4922-bf80-8f197c583370-389
at org.apache.jackrabbit.core.session.SessionState.close(SessionState.java:280) ~[jackrabbit-core-2.4.2.jar:na]
at org.apache.jackrabbit.core.SessionImpl.logout(SessionImpl.java:943) [jackrabbit-core-2.4.2.jar:na]
at org.apache.jackrabbit.core.XASessionImpl.logout(XASessionImpl.java:392) [jackrabbit-core-2.4.2.jar:na]
at org.apache.jackrabbit.jca.JCAManagedConnection.cleanup(JCAManagedConnection.java:169) [jackrabbit-jca-2.4.2.jar:na]
at ...
and after 1 hour :
Unclosed session detected. The session was opened here: java.lang.Exception: Stack Trace
at org.apache.jackrabbit.core.SessionImpl.<init>(SessionImpl.java:222) ~[jackrabbit-core-2.4.2.jar:na]
at org.apache.jackrabbit.core.SessionImpl.<init>(SessionImpl.java:239) ~[jackrabbit-core-2.4.2.jar:na]
at org.apache.jackrabbit.core.XASessionImpl.<init>(XASessionImpl.java:99) ~[jackrabbit-core-2.4.2.jar:na]
at ...
I believe this is because the application server (Glassfish v.3.1.2.2) tries to close the session I already closed. But when I don't close any sessions, I also get an exception where it says that the pool size limit is reached. How can I avoid my problem?

It looks like you are using Jackrabbit in a XA transaction.
I had a similar problem with JBoss, which I resolved by using a non XA datasource different from the one for my EJBs.
Look into for more info :
http://jackrabbit.510166.n4.nabble.com/How-to-handle-XA-Transactions-td521875.html

Related

Vertx - Multiple failureHandlers for the same route

The question is simple: is it possible to have multiple failure handlers for one route?
router.route(HttpMethod.POST, "/test")
.handler(LoggerHandler.create())
.handler(ResponseTimeHandler.create())
.failureHandler(MyCustomFailureHandler1.create())
.failureHandler(MyCustomFailureHandler2.create());
I'm currently using vert.x version 4.0.2, and I can see that internally, every failure handler I create is added to a failureHandlers list, but when an error is thrown, the only failure handler executing is the first one specified.
From the first failure handler (MyCustomFailureHandler1.create()), you have to call RoutingContext#next()
Documentation of RoutingContext#next() states: "If next is not called for a handler then the handler should make sure it ends the response or no response will be sent".
See TestCase here: testMultipleSetFailureHandler

MutableMessageBuilderFactory in Spring Integration

I have a spring cloud stream consumer getting messages from Kafka. I want to modify the message headers, but currently the message I get is of type GenericMessage.
I saw this post and this code from spring integration core so I added to my configuration a bean of type MutableMessageBuilderFactory but I'm still getting the message as GenericMessage. Actually, the bean creating code doesn't even seem to get called, the getMessageBuilderFactory(BeanFactory beanFactory) in IntegrationUtils classs gets called multiple times and everytime beanFactory.getBean("messageBuilderFactory", MessageBuilderFactory.class) returns DefaultMessageBuilderFactory.
What might be the problem causing the factory I defined as bean not to work and the message to keep coming as GenericMessage?
Spring versions:
spring-boot: 1.5.21
spring-integration: 4.3.12
Messages are immutable and there are many reasons for that, but it's out of scope of this question. What you can do is create a new Message in your handler and return it. If you want to copy most of the previous message and then modify the header you can do this:
Message resultMessage = MessageBuilder.fromMessage(sourceMessage).setHeader("myExistingHeader", "foo").build();

lift Session management

I am new to lift. I have been working with MVC model so far and using basic session management model i.e. storing a token in the session and check on each request.
I am trying to do the same with lift, but my session getting expired abruptly. even some time I just logged in and it logged out. I have analysis that whenever I gets log message like this:
INFO - Session ucjrn5flnq9q1ke52z5zixgtt expired
I have searched but I couldn't find any step by step tutor
Sessions are managed by your servlet container. Which one are you using? You should look at the container's documentation.
Do not attempt to use S.get et al to access session bound information. This is just plain dangerous. Do it like this:
class Thing {
object SessionThing extends SessionVar[Box[String]](Empty)
...
def someMethod = {
...
SessionThing.is // returns you a Box[String].
// operates on the session variable if it exists,
// otherwise provides a sensible default
SessionThing.is.map(_.toLowerCase).openOr("default")
...
}
}
You need to understand the snippet and state lifecycles really, as it seems you're not fully understanding how lift's session mechanics work.
I found the solution of the problem. I was using embedded jetty server, where I was using ServletContextHandler to register lift filter. I changed it to WebAppContext and it started working fine.
Puneet

asp.net mvc azure "Error accessing the data store!"

I've started using the AspProviders code to store my session data in my table storage.
I'm sporadically getting the following error:
Description: Exception of type 'System.Web.HttpException' was thrown. INNER_EXCEPTION:Error accessing the data store! INNER_EXCEPTION:An error occurred while processing this request. INNER_EXCEPTION: ConditionNotMet The condition specified using HTTP conditional header(s) is not met. RequestId:0c4239cc-41fb-42c5-98c5-7e9cc22096af Time:2010-10-15T04:28:07.0726801Z
StackTrace:
System.Web.SessionState.SessionStateModule.EndAcquireState(IAsyncResult ar)
System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) INNER_EXCEPTION:
Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 484
System.Web.SessionState.SessionStateModule.GetSessionStateItem()
System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state) INNER_EXCEPTION:
Microsoft.WindowsAzure.StorageClient.Tasks.Task1.get_Result()
Microsoft.WindowsAzure.StorageClient.Tasks.Task1.ExecuteAndWait()
Microsoft.WindowsAzure.StorageClient.TaskImplHelper.ExecuteImplWithRetry[T](Func`2 impl, RetryPolicy policy)
Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(TableServiceContext svc, SessionRow session, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 603
Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 480 INNER_EXCEPTION:
System.Data.Services.Client.DataServiceContext.SaveResult.d__1e.MoveNext()
Anyone run into this? The only useful information I've found is this, which I'm hesitant to do:
If you want to bypass the validation, you can open TableStorageSessionStateProvider.cs, find ReleaseItemExclusive, and modify the code from:
svc.UpdateObject(session);
to:
svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(session);
from here
Thanks!
So I decided to change this:
svc.UpdateObject(session);
svc.SaveChangesWithRetries();
to this:
try
{
svc.UpdateObject(session);
svc.SaveChangesWithRetries();
}
catch
{
svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(session);
svc.SaveChangesWithRetries();
}
So, I'll see how that works...
I've encountered this problem as well and after some investigation it seems to happen more often when you have more than one instance and you try to make calls in rapid succession in the same session. (e.g. if you had an auto complete box and making ajax calls on each key press)
This occurs because when you try to access the session data, first of all the web server takes out a lock on that session. When the request is complete, it releases the lock. With the table service provider, it updates this lock status by updating a field in the table. What I think is happening is that Instance1 loads the session row, then Instance2 loads the session row, Instance1 saves down the updated lock status and when Instance2 attempts to save the lock status it gets an error because the object isn't in the same state as when it loaded it (the ETag doesn't match any more).
This is why the fix that you found will stop the error from occurring, because by specifying the "*" in the AttachTo, when Instance2 attempts to save the lock it will turn off ETag checking (and over write the changes made by Instance1).
In our situation we have altered the provider so that we can turn off session for certain paths (the ajax call that was giving us our problems didn't need access to session data, neither did the loading of images) which may be an option for you depending on what is causing your problem.
Unfortunately the TableStorageSessionStateProvider is part of the sample projects and so isn't (as far as I'm aware, but I'll happily be told otherwise) officially supported by Microsoft. It does have other issues, like the fact that it doesn't clean up it's session data once a session expires, so you will end up with lots of junk in the session table and blob container that you'll have to clean up some other way.

transaction problem with entity framework 4

I'm trying to implement a transaction with entity framework 4. From what I've read, the code below is correct. The SaveChanges works fine but as soon as I hit the first ExecuteFunction call I get the following exception:
The underlying provider failed on
Open. --->
System.Transactions.TransactionManagerCommunicationException:
Network access for Distributed
Transaction Manager (MSDTC) has been
disabled. Please enable DTC for
network access in the security
configuration for MSDTC using the
Component Services Administrative
tool.
I've logged on to the database server and I don't see a service called Distributed Transaction Manager but I do see Distributed Transaction Coordinator and it is started. I'm not sure what I need to change to allow this to work. Anyone know? Thanks.
Here's the code.
using (var h = new WhaleEntities(ConnectionHelper.DBConnectString))
{
using (TransactionScope ts = new TransactionScope())
{
h.Sites.AddObject(s);
h.SaveChanges(SaveOptions.DetectChangesBeforeSave);
retval = s.SiteID;
h.ExecuteFunction("UpdateSiteInterfaceList", new ObjectParameter("pSiteID", retval), new ObjectParameter("pList", "10"));
h.ExecuteFunction("UpdateSiteInterfaceRequiredList", new ObjectParameter("pSiteID", retval),new ObjectParameter("pList", "Email"));
h.ExecuteFunction("UpdateSiteInterfaceAlwaysShownList", new ObjectParameter("pSiteID", retval),new ObjectParameter("pList", "10"));
h.ExecuteFunction("UpdateSiteInterfaceAlwaysRequiredList",new ObjectParameter("pSiteID", retval),new ObjectParameter("pList", "Email"));
ts.Complete();
//changes must be accepted manually once transaction succeeds.
h.AcceptAllChanges();
}
}
See here: How do I enable MSDTC on SQL Server?