buildbot success in on tomee-trunk-ubuntu

2017-06-01 Thread buildbot
The Buildbot has detected a restored build on builder tomee-trunk-ubuntu while 
building tomee. Full details are available at:
https://ci.apache.org/builders/tomee-trunk-ubuntu/builds/742

Buildbot URL: https://ci.apache.org/

Buildslave for this Build: bb_qnode5_ubuntu

Build Reason: The SingleBranchScheduler scheduler named 
'on-tomee-trunk-ubuntu-commit' triggered this build
Build Source Stamp: [branch master] 2be715d0d698e234f9886b450fb3643c0fb89f16
Blamelist: rmannibucau 

Build succeeded!

Sincerely,
 -The Buildbot





buildbot failure in on tomee-trunk-ubuntu-jvm8

2017-06-01 Thread buildbot
The Buildbot has detected a new failure on builder tomee-trunk-ubuntu-jvm8 
while building tomee. Full details are available at:
https://ci.apache.org/builders/tomee-trunk-ubuntu-jvm8/builds/647

Buildbot URL: https://ci.apache.org/

Buildslave for this Build: bb_qnode5_ubuntu

Build Reason: The SingleBranchScheduler scheduler named 
'on-tomee-trunk-ubuntu-jvm8-commit' triggered this build
Build Source Stamp: [branch master] 2be715d0d698e234f9886b450fb3643c0fb89f16
Blamelist: rmannibucau 

BUILD FAILED: failed test

Sincerely,
 -The Buildbot





[jira] [Resolved] (TOMEE-2045) TomEE tries to register a provider as a resource

2017-06-01 Thread Romain Manni-Bucau (JIRA)

 [ 
https://issues.apache.org/jira/browse/TOMEE-2045?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Romain Manni-Bucau resolved TOMEE-2045.
---
   Resolution: Fixed
 Assignee: Romain Manni-Bucau
Fix Version/s: 7.0.4

> TomEE tries to register a provider as a resource
> 
>
> Key: TOMEE-2045
> URL: https://issues.apache.org/jira/browse/TOMEE-2045
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: TURPIN Michel
>Assignee: Romain Manni-Bucau
> Fix For: 7.0.4
>
>
> When an Application subclass declares a class ( through the 
> Application#getClasses() method ) which implements one or more provider 
> interfaces but is not annotated with the Provider annotation, the provider is 
> not registred as a provider.
> From chapter 4 of the Jax-RS spec :
> ??A provider is a class that implements one or more JAX-RS interfaces 
> introduced in this specification and that *may* be annotated with @Provider 
> for automatic discovery.??



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


tomee git commit: TOMEE-2045 ensure @Provider is not mandatory when explicitly registered

2017-06-01 Thread rmannibucau
Repository: tomee
Updated Branches:
  refs/heads/master 022d8fa45 -> 2be715d0d


TOMEE-2045 ensure @Provider is not mandatory when explicitly registered


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/2be715d0
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/2be715d0
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/2be715d0

Branch: refs/heads/master
Commit: 2be715d0d698e234f9886b450fb3643c0fb89f16
Parents: 022d8fa
Author: rmannibucau 
Authored: Thu Jun 1 23:21:48 2017 +0200
Committer: rmannibucau 
Committed: Thu Jun 1 23:21:48 2017 +0200

--
 .../cxf/rs/ProviderWithoutAnnotationTest.java   | 103 +++
 .../apache/openejb/server/rest/RESTService.java |  21 +++-
 2 files changed, 123 insertions(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/tomee/blob/2be715d0/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ProviderWithoutAnnotationTest.java
--
diff --git 
a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ProviderWithoutAnnotationTest.java
 
b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ProviderWithoutAnnotationTest.java
new file mode 100644
index 000..d1e6c03
--- /dev/null
+++ 
b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ProviderWithoutAnnotationTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.server.cxf.rs;
+
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.EnableServices;
+import org.apache.openejb.testing.RandomPort;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@RunWith(ApplicationComposer.class)
+@Classes(innerClassesAsBean = true)
+public class ProviderWithoutAnnotationTest {
+@RandomPort("http")
+private URL base;
+
+@Test
+public void run() {
+final Client client = ClientBuilder.newClient();
+try {
+assertEquals("foo", client.target(base.toExternalForm() + 
"openejb/api/ProviderWithoutAnnotationTest")
+.request("foo/bar")
+.get(String.class));
+} finally {
+client.close();
+}
+}
+
+@ApplicationPath("api")
+public static class App extends Application {
+@Override
+public Set getClasses() {
+return new HashSet<>(asList(Endpoint.class, FooWriter.class));
+}
+}
+
+@Path("ProviderWithoutAnnotationTest")
+public static class Endpoint {
+@GET
+@Produces("foo/bar")
+public Endpoint get() {
+return this;
+}
+}
+
+@Produces("foo/*")
+public static class FooWriter implements MessageBodyWriter {
+@Override
+public boolean isWriteable(final Class type, final Type 
genericType, final Annotation[] annotations, final MediaType mediaType) {
+return type == Endpoint.class && mediaType.getType().equals("foo");
+}
+
+@Override
+public long getSize(final Endpoint s, final Class type, final Type 
genericType, final 

[jira] [Created] (TOMEE-2045) TomEE tries to register a provider as a resource

2017-06-01 Thread TURPIN Michel (JIRA)
TURPIN Michel created TOMEE-2045:


 Summary: TomEE tries to register a provider as a resource
 Key: TOMEE-2045
 URL: https://issues.apache.org/jira/browse/TOMEE-2045
 Project: TomEE
  Issue Type: Bug
  Components: TomEE Core Server
Affects Versions: 7.0.3
Reporter: TURPIN Michel


When an Application subclass declares a class ( through the 
Application#getClasses() method ) which implements one or more provider 
interfaces but is not annotated with the Provider annotation, the provider is 
not registred as a provider.

>From chapter 4 of the Jax-RS spec :
??A provider is a class that implements one or more JAX-RS interfaces 
introduced in this specification and that *may* be annotated with @Provider for 
automatic discovery.??



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


buildbot failure in on tomee-trunk-ubuntu

2017-06-01 Thread buildbot
The Buildbot has detected a new failure on builder tomee-trunk-ubuntu while 
building tomee. Full details are available at:
https://ci.apache.org/builders/tomee-trunk-ubuntu/builds/741

Buildbot URL: https://ci.apache.org/

Buildslave for this Build: bb_qnode5_ubuntu

Build Reason: The SingleBranchScheduler scheduler named 
'on-tomee-trunk-ubuntu-commit' triggered this build
Build Source Stamp: [branch master] 022d8fa45ae849db5832777ebc3857969db30cba
Blamelist: rmannibucau 

BUILD FAILED: failed test

Sincerely,
 -The Buildbot





buildbot success in on tomee-trunk-ubuntu-jvm8

2017-06-01 Thread buildbot
The Buildbot has detected a restored build on builder tomee-trunk-ubuntu-jvm8 
while building tomee. Full details are available at:
https://ci.apache.org/builders/tomee-trunk-ubuntu-jvm8/builds/646

Buildbot URL: https://ci.apache.org/

Buildslave for this Build: bb_qnode5_ubuntu

Build Reason: The SingleBranchScheduler scheduler named 
'on-tomee-trunk-ubuntu-jvm8-commit' triggered this build
Build Source Stamp: [branch master] 022d8fa45ae849db5832777ebc3857969db30cba
Blamelist: rmannibucau 

Build succeeded!

Sincerely,
 -The Buildbot





[jira] [Commented] (TOMEE-2044) threadPool-queue (in ServicePool) from ejbd-Service is never processed

2017-06-01 Thread Romain Manni-Bucau (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2044?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16033263#comment-16033263
 ] 

Romain Manni-Bucau commented on TOMEE-2044:
---

Hi Lars,

very good analyzis!

master has some refactoring around it, is it possible to give it a try?

> threadPool-queue (in ServicePool) from ejbd-Service is never processed 
> ---
>
> Key: TOMEE-2044
> URL: https://issues.apache.org/jira/browse/TOMEE-2044
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 1.7.4
> Environment: FreeBSD 10.3-STABLE amd64 
> openjdk8-8.131.11
>Reporter: Lars Herschke
> Fix For: 7.0.4
>
>
> If you have many requests to your ejbd-service the queue from the threadPool 
> in ServicePool.java is filled. This queue is never processed depending on 
> your server config. If you have only ejbd-service enabled and the services 
> admin, ejbds and httpejbd are disabled all is fine. If you have two or more 
> of these services enabled the issue could occur. The reason is the following.
> KeepAliveServer.java has the following line to get the queue.
> final ServicePool incoming = 
> SystemInstance.get().getComponent(ServicePool.class);
> SystemInstance.java hold components in a HahMap with the class type as key. 
> On server-startup the above named services are initalized in 
> ServiceManager.manage(...). This method instances new ServicePool for this 
> services. Each ServicePool-instance calls in his constructor
> SystemInstance.get().setComponent(ServicePool.class, this);.
> Every other call of setComponent replace the old entry in the components 
> HashMap. So KeepAliveServer gets always the queue of the last initalized 
> service.
> Workaround:
> Use only one of the four above named services
> or
> set threadsCore for your services at least as high, that the queue is never 
> used.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Updated] (TOMEE-2044) threadPool-queue (in ServicePool) from ejbd-Service is never processed

2017-06-01 Thread Romain Manni-Bucau (JIRA)

 [ 
https://issues.apache.org/jira/browse/TOMEE-2044?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Romain Manni-Bucau updated TOMEE-2044:
--
Fix Version/s: 7.0.4

> threadPool-queue (in ServicePool) from ejbd-Service is never processed 
> ---
>
> Key: TOMEE-2044
> URL: https://issues.apache.org/jira/browse/TOMEE-2044
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 1.7.4
> Environment: FreeBSD 10.3-STABLE amd64 
> openjdk8-8.131.11
>Reporter: Lars Herschke
> Fix For: 7.0.4
>
>
> If you have many requests to your ejbd-service the queue from the threadPool 
> in ServicePool.java is filled. This queue is never processed depending on 
> your server config. If you have only ejbd-service enabled and the services 
> admin, ejbds and httpejbd are disabled all is fine. If you have two or more 
> of these services enabled the issue could occur. The reason is the following.
> KeepAliveServer.java has the following line to get the queue.
> final ServicePool incoming = 
> SystemInstance.get().getComponent(ServicePool.class);
> SystemInstance.java hold components in a HahMap with the class type as key. 
> On server-startup the above named services are initalized in 
> ServiceManager.manage(...). This method instances new ServicePool for this 
> services. Each ServicePool-instance calls in his constructor
> SystemInstance.get().setComponent(ServicePool.class, this);.
> Every other call of setComponent replace the old entry in the components 
> HashMap. So KeepAliveServer gets always the queue of the last initalized 
> service.
> Workaround:
> Use only one of the four above named services
> or
> set threadsCore for your services at least as high, that the queue is never 
> used.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


tomee git commit: TOMEE-2044 avoid singleton when we dont need it

2017-06-01 Thread rmannibucau
Repository: tomee
Updated Branches:
  refs/heads/master 85635cd8c -> 022d8fa45


TOMEE-2044 avoid singleton when we dont need it


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/022d8fa4
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/022d8fa4
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/022d8fa4

Branch: refs/heads/master
Commit: 022d8fa45ae849db5832777ebc3857969db30cba
Parents: 85635cd
Author: rmannibucau 
Authored: Thu Jun 1 18:34:04 2017 +0200
Committer: rmannibucau 
Committed: Thu Jun 1 18:34:04 2017 +0200

--
 .../openejb/server/ejbd/KeepAliveServer.java|  4 +--
 .../openejb/server/ServerServiceFilter.java |  7 -
 .../openejb/server/ServiceAccessController.java |  2 +-
 .../apache/openejb/server/ServiceDaemon.java| 13 ++---
 .../org/apache/openejb/server/ServicePool.java  | 16 ++-
 .../org/apache/openejb/server/Unwrappable.java  | 21 ++
 .../openejb/server/UnwrappbleServerService.java | 29 
 7 files changed, 83 insertions(+), 9 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/tomee/blob/022d8fa4/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/KeepAliveServer.java
--
diff --git 
a/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/KeepAliveServer.java
 
b/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/KeepAliveServer.java
index c25b988..d41d36f 100644
--- 
a/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/KeepAliveServer.java
+++ 
b/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/KeepAliveServer.java
@@ -18,10 +18,10 @@ package org.apache.openejb.server.ejbd;
 
 import org.apache.openejb.client.FlushableGZIPOutputStream;
 import org.apache.openejb.client.KeepAliveStyle;
-import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.server.ServerService;
 import org.apache.openejb.server.ServiceException;
 import org.apache.openejb.server.ServicePool;
+import org.apache.openejb.server.Unwrappable;
 import org.apache.openejb.server.context.RequestInfos;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
@@ -161,7 +161,7 @@ public class KeepAliveServer implements ServerService {
 private BlockingQueue getQueue() {
 if (this.threadQueue == null) {
 // this can be null if timer fires before service is fully 
initialized
-final ServicePool incoming = 
SystemInstance.get().getComponent(ServicePool.class);
+final ServicePool incoming = Unwrappable.class.isInstance(service) 
? Unwrappable.class.cast(service).unwrap(ServicePool.class) : null;
 if (incoming == null) {
 return null;
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/022d8fa4/server/openejb-server/src/main/java/org/apache/openejb/server/ServerServiceFilter.java
--
diff --git 
a/server/openejb-server/src/main/java/org/apache/openejb/server/ServerServiceFilter.java
 
b/server/openejb-server/src/main/java/org/apache/openejb/server/ServerServiceFilter.java
index 66d74f9..0835696 100644
--- 
a/server/openejb-server/src/main/java/org/apache/openejb/server/ServerServiceFilter.java
+++ 
b/server/openejb-server/src/main/java/org/apache/openejb/server/ServerServiceFilter.java
@@ -29,7 +29,7 @@ import java.util.Properties;
  *
  * @version $Rev$ $Date$
  */
-public class ServerServiceFilter implements ServerService {
+public class ServerServiceFilter extends UnwrappbleServerService {
 
 @Managed
 private final ServerService service;
@@ -77,4 +77,9 @@ public class ServerServiceFilter implements ServerService {
 public void init(final Properties props) throws Exception {
 service.init(props);
 }
+
+@Override
+protected Object getDelegate() {
+return service;
+}
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/022d8fa4/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
--
diff --git 
a/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
 
b/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
index 037ddce..da6e0d7 100644
--- 
a/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
+++ 
b/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
@@ -38,7 +38,7 @@ import java.util.Properties;
 import java.util.StringTokenizer;
 
 @Managed
-public class ServiceAccessController 

[jira] [Created] (TOMEE-2044) threadPool-queue (in ServicePool) from ejbd-Service is never processed

2017-06-01 Thread Lars Herschke (JIRA)
Lars Herschke created TOMEE-2044:


 Summary: threadPool-queue (in ServicePool) from ejbd-Service is 
never processed 
 Key: TOMEE-2044
 URL: https://issues.apache.org/jira/browse/TOMEE-2044
 Project: TomEE
  Issue Type: Bug
  Components: TomEE Core Server
Affects Versions: 1.7.4
 Environment: FreeBSD 10.3-STABLE amd64 
openjdk8-8.131.11
Reporter: Lars Herschke


If you have many requests to your ejbd-service the queue from the threadPool in 
ServicePool.java is filled. This queue is never processed depending on your 
server config. If you have only ejbd-service enabled and the services admin, 
ejbds and httpejbd are disabled all is fine. If you have two or more of these 
services enabled the issue could occur. The reason is the following.

KeepAliveServer.java has the following line to get the queue.
final ServicePool incoming = 
SystemInstance.get().getComponent(ServicePool.class);
SystemInstance.java hold components in a HahMap with the class type as key. On 
server-startup the above named services are initalized in 
ServiceManager.manage(...). This method instances new ServicePool for this 
services. Each ServicePool-instance calls in his constructor
SystemInstance.get().setComponent(ServicePool.class, this);.
Every other call of setComponent replace the old entry in the components 
HashMap. So KeepAliveServer gets always the queue of the last initalized 
service.

Workaround:
Use only one of the four above named services
or
set threadsCore for your services at least as high, that the queue is never 
used.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


buildbot failure in on tomee-trunk-ubuntu

2017-06-01 Thread buildbot
The Buildbot has detected a new failure on builder tomee-trunk-ubuntu while 
building tomee. Full details are available at:
https://ci.apache.org/builders/tomee-trunk-ubuntu/builds/738

Buildbot URL: https://ci.apache.org/

Buildslave for this Build: bb_qnode5_ubuntu

Build Reason: The SingleBranchScheduler scheduler named 
'on-tomee-trunk-ubuntu-commit' triggered this build
Build Source Stamp: [branch master] 85635cd8ca5e7256d3295bbaa5cc88674eebcfca
Blamelist: rmannibucau 

BUILD FAILED: failed test

Sincerely,
 -The Buildbot





[jira] [Resolved] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)

 [ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Svetlin Zarev resolved TOMEE-2043.
--
Resolution: Not A Problem

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
> exception specified in the "donotRollbackOn" attribute inside 
> TransactionalException



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Romain Manni-Bucau (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032902#comment-16032902
 ] 

Romain Manni-Bucau commented on TOMEE-2043:
---

[~SvetlinZarev] sadly the bug is on your side so you should fix it on your 
side. From the interceptor we don't know if it is intended or not when we exit 
the method and what's the handling outside so we would likely log more false 
positive than real issues IMHO.

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
> exception specified in the "donotRollbackOn" attribute inside 
> TransactionalException



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032900#comment-16032900
 ] 

Svetlin Zarev commented on TOMEE-2043:
--

I agree. Do you think that clearing the thread local (and not committing the 
transaction) and logging an error is OK ? My point is that such state should 
not be randomly carried across requests - a bug in one request should not make 
other requests to fail.

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
> exception specified in the "donotRollbackOn" attribute inside 
> TransactionalException



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Romain Manni-Bucau (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032855#comment-16032855
 ] 

Romain Manni-Bucau commented on TOMEE-2043:
---

if you start the transaction and use propagation then you are the one 
responsible of finishing it. So it sounds like tomee impl is good.

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
> exception specified in the "donotRollbackOn" attribute inside 
> TransactionalException



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Comment Edited] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032853#comment-16032853
 ] 

Svetlin Zarev edited comment on TOMEE-2043 at 6/1/17 11:53 AM:
---

Your test case passes because the transaction is started in the TxRequired 
policy. While my sample app fails, because the transaction is ".begin()"ed 
manually in the servlet:

{code}
 transaction.begin();
 transactionalBean.withDontRollbackOn();
 transaction.commit();
{code}

ThRequired policy: 
{code}
public void commit() throws ApplicationException, SystemException {
// only commit if we started the transaction
if (clientTx == null) {
completeTransaction(currentTx);
} else {
fireNonTransactionalCompletion();
}
}
{code}

So in the junit test case, the execution goes to the "clientTx == null" branch, 
while in my case it goes to  " fireNonTransactionalCompletion();" IMO that's 
fine in all cases except for if this is the outermost interceptor, because in 
that case there is no one to complete the transaction.

What do you think ?


was (Author: svetlinzarev):
Your test case passes because the transaction is started in the TxRequired 
policy. While may sample app fails, because the transaction is ".begin()"ed 
manually in the servlet:

{code}
 transaction.begin();
 transactionalBean.withDontRollbackOn();
 transaction.commit();
{code}

ThRequired policy: 
{code}
public void commit() throws ApplicationException, SystemException {
// only commit if we started the transaction
if (clientTx == null) {
completeTransaction(currentTx);
} else {
fireNonTransactionalCompletion();
}
}
{code}

So in the junit test case, the execution goes to the "clientTx == null" branch, 
while in my case it goes to  " fireNonTransactionalCompletion();" IMO that's 
fine in all cases except for if this is the outermost interceptor, because in 
that case there is no one to complete the transaction.

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> 

[jira] [Commented] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032853#comment-16032853
 ] 

Svetlin Zarev commented on TOMEE-2043:
--

Your test case passes because the transaction is started in the TxRequired 
policy. While may sample app fails, because the transaction is ".begin()"ed 
manually in the servlet:

{code}
 transaction.begin();
 transactionalBean.withDontRollbackOn();
 transaction.commit();
{code}

ThRequired policy: 
{code}
public void commit() throws ApplicationException, SystemException {
// only commit if we started the transaction
if (clientTx == null) {
completeTransaction(currentTx);
} else {
fireNonTransactionalCompletion();
}
}
{code}

So in the junit test case, the execution goes to the "clientTx == null" branch, 
while in my case it goes to  " fireNonTransactionalCompletion();" IMO that's 
fine in all cases except for if this is the outermost interceptor, because in 
that case there is no one to complete the transaction.

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> 

[jira] [Commented] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032699#comment-16032699
 ] 

Svetlin Zarev commented on TOMEE-2043:
--

Sure, I'll try to update the test


> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
> exception specified in the "donotRollbackOn" attribute inside 
> TransactionalException



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Commented] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Romain Manni-Bucau (JIRA)

[ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16032687#comment-16032687
 ] 

Romain Manni-Bucau commented on TOMEE-2043:
---

Hi Svetlin, added this test 
https://github.com/apache/tomee/commit/85635cd8ca5e7256d3295bbaa5cc88674eebcfca#diff-a4abce7d91e66d06fa3fcc3106da9fb7R65
 and it seems it is committed properly. Do you want to try to enhance this test 
class with a test reproducing your use case?

> Thread local transactions are left open across requests
> ---
>
> Key: TOMEE-2043
> URL: https://issues.apache.org/jira/browse/TOMEE-2043
> Project: TomEE
>  Issue Type: Bug
>  Components: TomEE Core Server
>Affects Versions: 7.0.3
>Reporter: Svetlin Zarev
> Attachments: sample.zip
>
>
> @Transactional CDI bean methods annotated with 
> @Transactional(dontRollbackOn = SomeException.class) do not commit the 
> transaction at the end of the request/response cycle when the SomeException 
> exception is thrown. As a result the thread local transaction object is 
> preserved across requests which makes unrelated requests to fail with "Nested 
> transactions are not supported".
> Sample application that reproduces the issue is attached to the ticket. Just 
> request the application several times and observe how the output is changing.
> Sample valve that can be used to demonstrate the issue: 
> {code}
> public final class LeakedTransactionDetectionValve extends ValveBase {
> private static final Logger logger = 
> Logger.getLogger(LeakedTransactionDetectionValve.class.getName());
> @Override
> public void invoke(Request request, Response response) throws 
> IOException, ServletException {
> boolean hasActiveTransaction = false;
> try {
> final Collection transactionsBeforeRequest = 
> getTransactions();
> for (Transaction transaction : transactionsBeforeRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> hasActiveTransaction = true;
> break;
> }
> }
> } catch (Exception ex) {
> //no-op
> }
> getNext().invoke(request, response);
> if (!hasActiveTransaction) {
> try {
> final Collection transactionsAfterRequest = 
> getTransactions();
> for (Transaction transaction : transactionsAfterRequest) {
> if (transaction.getStatus() == Status.STATUS_ACTIVE) {
> logger.log(Level.SEVERE, "Found active transaction: "
> + request.getRequestURI()
> + "?"
> + request.getQueryString()
> );
> }
> }
> } catch (Exception ex) {
> logger.log(Level.SEVERE, "Failed to determine thread local 
> transaction status.", ex);
> }
> }
> }
> Collection getTransactions() throws NoSuchFieldException, 
> IllegalAccessException {
> final Field threadLocalsField = 
> Thread.class.getDeclaredField("threadLocals");
> threadLocalsField.setAccessible(true);
> final Object threadLocals = 
> threadLocalsField.get(Thread.currentThread());
> final Field tableField = 
> threadLocals.getClass().getDeclaredField("table");
> tableField.setAccessible(true);
> final Object table = tableField.get(threadLocals);
> final Collection transactions = new LinkedList<>();
> for (int i = 0; i < Array.getLength(table); i++) {
> final Object entry = Array.get(table, i);
> if (null != entry) {
> final Field valueField = 
> entry.getClass().getDeclaredField("value");
> valueField.setAccessible(true);
> final Object value = valueField.get(entry);
> if (value instanceof Transaction) {
> transactions.add((Transaction) value);
> }
> }
> }
> return transactions;
> }
> {code}
> PS: in addition to the issue above, the 
> org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
> exception specified in the "donotRollbackOn" attribute inside 
> TransactionalException



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


[jira] [Updated] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)

 [ 
https://issues.apache.org/jira/browse/TOMEE-2043?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Svetlin Zarev updated TOMEE-2043:
-
Description: 
@Transactional CDI bean methods annotated with 
@Transactional(dontRollbackOn = SomeException.class) do not commit the 
transaction at the end of the request/response cycle when the SomeException 
exception is thrown. As a result the thread local transaction object is 
preserved across requests which makes unrelated requests to fail with "Nested 
transactions are not supported".

Sample application that reproduces the issue is attached to the ticket. Just 
request the application several times and observe how the output is changing.

Sample valve that can be used to demonstrate the issue: 

{code}
public final class LeakedTransactionDetectionValve extends ValveBase {
private static final Logger logger = 
Logger.getLogger(LeakedTransactionDetectionValve.class.getName());

@Override
public void invoke(Request request, Response response) throws IOException, 
ServletException {
boolean hasActiveTransaction = false;
try {
final Collection transactionsBeforeRequest = 
getTransactions();
for (Transaction transaction : transactionsBeforeRequest) {
if (transaction.getStatus() == Status.STATUS_ACTIVE) {
hasActiveTransaction = true;
break;
}
}
} catch (Exception ex) {
//no-op
}

getNext().invoke(request, response);

if (!hasActiveTransaction) {
try {
final Collection transactionsAfterRequest = 
getTransactions();
for (Transaction transaction : transactionsAfterRequest) {
if (transaction.getStatus() == Status.STATUS_ACTIVE) {
logger.log(Level.SEVERE, "Found active transaction: "
+ request.getRequestURI()
+ "?"
+ request.getQueryString()
);
}
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to determine thread local 
transaction status.", ex);
}
}
}

Collection getTransactions() throws NoSuchFieldException, 
IllegalAccessException {
final Field threadLocalsField = 
Thread.class.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
final Object threadLocals = 
threadLocalsField.get(Thread.currentThread());

final Field tableField = 
threadLocals.getClass().getDeclaredField("table");
tableField.setAccessible(true);
final Object table = tableField.get(threadLocals);

final Collection transactions = new LinkedList<>();
for (int i = 0; i < Array.getLength(table); i++) {
final Object entry = Array.get(table, i);
if (null != entry) {
final Field valueField = 
entry.getClass().getDeclaredField("value");
valueField.setAccessible(true);

final Object value = valueField.get(entry);
if (value instanceof Transaction) {
transactions.add((Transaction) value);
}
}
}

return transactions;
}
{code}

PS: in addition to the issue above, the 
org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
exception specified in the "donotRollbackOn" attribute inside 
TransactionalException


  was:
@Transactional CDI bean methods annotated with 
@Transactional(dontRollbackOn = SomeException.class) do not commit the 
transaction at the end of the request/response cycle when the SomeException 
exception is thrown. As a result the thread local transaction object is 
preserved across requests which makes unrelated requests to fail with "Nested 
transactions are not supported".

Sample application that reproduces the issue is attached to the ticket.
Sample valve that can be used to demonstrate the issue: 

{code}
public final class LeakedTransactionDetectionValve extends ValveBase {
private static final Logger logger = 
Logger.getLogger(LeakedTransactionDetectionValve.class.getName());

@Override
public void invoke(Request request, Response response) throws IOException, 
ServletException {
boolean hasActiveTransaction = false;
try {
final Collection transactionsBeforeRequest = 
getTransactions();
for (Transaction transaction : transactionsBeforeRequest) {
if (transaction.getStatus() == Status.STATUS_ACTIVE) {
hasActiveTransaction = true;
break;
}
}
} catch (Exception ex) {
//no-op
}

getNext().invoke(request, response);

if 

tomee git commit: TOMEE-2043 test dontRollbackOn @Transactional config

2017-06-01 Thread rmannibucau
Repository: tomee
Updated Branches:
  refs/heads/master 4e4311162 -> 85635cd8c


TOMEE-2043 test dontRollbackOn @Transactional config


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/85635cd8
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/85635cd8
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/85635cd8

Branch: refs/heads/master
Commit: 85635cd8ca5e7256d3295bbaa5cc88674eebcfca
Parents: 4e43111
Author: rmannibucau 
Authored: Thu Jun 1 11:23:35 2017 +0200
Committer: rmannibucau 
Committed: Thu Jun 1 11:23:35 2017 +0200

--
 .../cdi/transactional/TransactionalTest.java   | 17 +
 1 file changed, 17 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/tomee/blob/85635cd8/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
--
diff --git 
a/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
 
b/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
index d63b7af..265e5b2 100644
--- 
a/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
+++ 
b/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
@@ -47,6 +47,7 @@ import static 
javax.transaction.Transactional.TxType.REQUIRES_NEW;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -61,6 +62,17 @@ public class TransactionalTest {
 @Inject
 private TxBean bean;
 
+@Test
+public void dontRollbackCommits() throws SystemException {
+assertNull(OpenEJB.getTransactionManager().getTransaction());
+try {
+bean.dontRollback();
+} catch (final TransactionalException e) {
+// expected
+}
+assertNull(OpenEJB.getTransactionManager().getTransaction());
+}
+
 @Test(expected = TransactionalException.class)
 public void mandatoryKO() {
 for (int i = 0; i < 2; i++) {
@@ -361,6 +373,11 @@ public class TransactionalTest {
 }
 }
 
+@Transactional(dontRollbackOn = AnException.class)
+public void dontRollback() {
+throw new AnException();
+}
+
 @Transactional(value = MANDATORY, rollbackOn = AnException.class)
 public void anException() {
 throw new AnException();



[jira] [Created] (TOMEE-2043) Thread local transactions are left open across requests

2017-06-01 Thread Svetlin Zarev (JIRA)
Svetlin Zarev created TOMEE-2043:


 Summary: Thread local transactions are left open across requests
 Key: TOMEE-2043
 URL: https://issues.apache.org/jira/browse/TOMEE-2043
 Project: TomEE
  Issue Type: Bug
  Components: TomEE Core Server
Affects Versions: 7.0.3
Reporter: Svetlin Zarev
 Attachments: sample.zip

@Transactional CDI bean methods annotated with 
@Transactional(dontRollbackOn = SomeException.class) do not commit the 
transaction at the end of the request/response cycle when the SomeException 
exception is thrown. As a result the thread local transaction object is 
preserved across requests which makes unrelated requests to fail with "Nested 
transactions are not supported".

Sample application that reproduces the issue is attached to the ticket.
Sample valve that can be used to demonstrate the issue: 

{code}
public final class LeakedTransactionDetectionValve extends ValveBase {
private static final Logger logger = 
Logger.getLogger(LeakedTransactionDetectionValve.class.getName());

@Override
public void invoke(Request request, Response response) throws IOException, 
ServletException {
boolean hasActiveTransaction = false;
try {
final Collection transactionsBeforeRequest = 
getTransactions();
for (Transaction transaction : transactionsBeforeRequest) {
if (transaction.getStatus() == Status.STATUS_ACTIVE) {
hasActiveTransaction = true;
break;
}
}
} catch (Exception ex) {
//no-op
}

getNext().invoke(request, response);

if (!hasActiveTransaction) {
try {
final Collection transactionsAfterRequest = 
getTransactions();
for (Transaction transaction : transactionsAfterRequest) {
if (transaction.getStatus() == Status.STATUS_ACTIVE) {
logger.log(Level.SEVERE, "Found active transaction: "
+ request.getRequestURI()
+ "?"
+ request.getQueryString()
);
}
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to determine thread local 
transaction status.", ex);
}
}
}

Collection getTransactions() throws NoSuchFieldException, 
IllegalAccessException {
final Field threadLocalsField = 
Thread.class.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
final Object threadLocals = 
threadLocalsField.get(Thread.currentThread());

final Field tableField = 
threadLocals.getClass().getDeclaredField("table");
tableField.setAccessible(true);
final Object table = tableField.get(threadLocals);

final Collection transactions = new LinkedList<>();
for (int i = 0; i < Array.getLength(table); i++) {
final Object entry = Array.get(table, i);
if (null != entry) {
final Field valueField = 
entry.getClass().getDeclaredField("value");
valueField.setAccessible(true);

final Object value = valueField.get(entry);
if (value instanceof Transaction) {
transactions.add((Transaction) value);
}
}
}

return transactions;
}
{code}

PS: in addition to the issue above, the 
org.apache.openejb.cdi.transactional.InterceptorBase must not wrap the 
exception specified in the "donotRollbackOn" attribute inside 
TransactionalException




--
This message was sent by Atlassian JIRA
(v6.3.15#6346)