Skip to content

Commit da06dd5

Browse files
authored
Excluding Spring-JMS specific Runnable from the concurrent plugin (#1496)
1 parent feebf1a commit da06dd5

File tree

23 files changed

+123
-34
lines changed

23 files changed

+123
-34
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ endif::[]
5454
* Fix `IllegalAccessError: Module 'java.base' no access to: package 'java.lang'...` in J9 VMs of Java version >= 9 -
5555
{pull}1468[#1468]
5656
* Fix JVM version parsing on HP-UX {pull}1477[#1477]
57+
* Fix Spring-JMS transactions lifecycle management when using multiple concurrent consumers - {pull}1496[#1496]
5758
5859
===== Refactors
5960
* Migrate some plugins to indy dispatcher {pull}1404[1404] {pull}1411[1411]

apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/AbstractSpan.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ public boolean isReferenced() {
194194
return references.get() > 0;
195195
}
196196

197+
public boolean isFinished() {
198+
return finished;
199+
}
200+
197201
/**
198202
* How long the transaction took to complete, in µs
199203
*/

apm-agent-plugins/apm-java-concurrent-plugin/src/main/java/co/elastic/apm/agent/concurrent/JavaConcurrent.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
import java.util.ArrayList;
3636
import java.util.Collection;
3737
import java.util.Collections;
38+
import java.util.HashSet;
3839
import java.util.List;
40+
import java.util.Set;
3941
import java.util.concurrent.Callable;
4042
import java.util.concurrent.ForkJoinTask;
4143

@@ -46,13 +48,29 @@ public class JavaConcurrent {
4648
<Class<? extends ElasticApmInstrumentation>>singletonList(RunnableCallableForkJoinTaskInstrumentation.class);
4749
static final ThreadLocal<Boolean> needsContext = new ThreadLocal<>();
4850

51+
private static final Set<String> EXCLUDED_EXECUTABLE_TYPES;
52+
53+
static {
54+
EXCLUDED_EXECUTABLE_TYPES = new HashSet<String>();
55+
EXCLUDED_EXECUTABLE_TYPES.add(RunnableLambdaWrapper.class.getName());
56+
EXCLUDED_EXECUTABLE_TYPES.add(CallableLambdaWrapper.class.getName());
57+
// Spring-JMS polling mechanism that translates to passive onMessage handling
58+
EXCLUDED_EXECUTABLE_TYPES.add("org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker");
59+
}
60+
4961
private static void removeContext(Object o) {
5062
AbstractSpan<?> context = contextMap.remove(o);
5163
if (context != null) {
5264
context.decrementReferences();
5365
}
5466
}
5567

68+
private static boolean shouldAvoidContextPropagation(@Nullable Object executable) {
69+
return executable == null ||
70+
EXCLUDED_EXECUTABLE_TYPES.contains(executable.getClass().getName()) ||
71+
needsContext.get() == Boolean.FALSE;
72+
}
73+
5674
@Nullable
5775
public static AbstractSpan<?> restoreContext(Object o, Tracer tracer) {
5876
// When an Executor executes directly on the current thread we need to enable this thread for context propagation again
@@ -76,7 +94,7 @@ public static AbstractSpan<?> restoreContext(Object o, Tracer tracer) {
7694
*/
7795
@Nullable
7896
public static Runnable withContext(@Nullable Runnable runnable, Tracer tracer) {
79-
if (runnable instanceof RunnableLambdaWrapper || runnable == null || needsContext.get() == Boolean.FALSE) {
97+
if (shouldAvoidContextPropagation(runnable)) {
8098
return runnable;
8199
}
82100
needsContext.set(Boolean.FALSE);
@@ -104,7 +122,7 @@ private static void captureContext(Object task, AbstractSpan<?> active) {
104122
*/
105123
@Nullable
106124
public static <T> Callable<T> withContext(@Nullable Callable<T> callable, Tracer tracer) {
107-
if (callable instanceof CallableLambdaWrapper || callable == null || needsContext.get() == Boolean.FALSE) {
125+
if (shouldAvoidContextPropagation(callable)) {
108126
return callable;
109127
}
110128
needsContext.set(Boolean.FALSE);
@@ -121,7 +139,7 @@ public static <T> Callable<T> withContext(@Nullable Callable<T> callable, Tracer
121139

122140
@Nullable
123141
public static <T> ForkJoinTask<T> withContext(@Nullable ForkJoinTask<T> task, Tracer tracer) {
124-
if (task == null || needsContext.get() == Boolean.FALSE) {
142+
if (shouldAvoidContextPropagation(task)) {
125143
return task;
126144
}
127145
needsContext.set(Boolean.FALSE);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<artifactId>apm-jms-plugin</artifactId>
8+
<groupId>co.elastic.apm</groupId>
9+
<version>1.18.2-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>apm-jms-plugin-base</artifactId>
13+
<name>${project.groupId}:${project.artifactId}</name>
14+
15+
<properties>
16+
<apm-agent-parent.base.dir>${project.basedir}/../../..</apm-agent-parent.base.dir>
17+
</properties>
18+
19+
</project>
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ public JmsMessageListenerInstrumentation(ElasticApmTracer tracer) {
6161

6262
@Override
6363
public ElementMatcher<? super TypeDescription> getTypeMatcher() {
64-
return not(isInterface())
65-
.and(
66-
hasSuperType(named("javax.jms.MessageListener"))
67-
.or(hasSuperType(named("org.springframework.jms.listener.SessionAwareMessageListener")))
68-
);
64+
return not(isInterface()).and(hasSuperType(named("javax.jms.MessageListener")));
6965
}
7066

7167
@Override

0 commit comments

Comments
 (0)