Move liblttng-ust-java* to 'src/lib/'
authorMichael Jeanson <mjeanson@efficios.com>
Fri, 9 Apr 2021 18:30:00 +0000 (14:30 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 13 Apr 2021 18:06:52 +0000 (14:06 -0400)
Move all public libraries under 'src/lib/'.

This is part of an effort to standardize our autotools setup across
projects to simplify maintenance.

Change-Id: I98ed0e9da28c111e62b189f26b0a225b5aa500e1
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
119 files changed:
.gitignore
configure.ac
doc/examples/Makefile.am
doc/examples/java-jul/run
doc/examples/java-log4j/run
src/Makefile.am
src/lib/Makefile.am
src/lib/lttng-ust-java-agent/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Manifest.txt [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Manifest.txt [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngHandler.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/LTTngAgent.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngAgentResponse.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableAppContextCommand.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableAppContextCommand.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoManager.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoSerializer.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/IContextInfoRetriever.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/LttngContextApi.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/FilterChangeNotifier.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/IFilterChangeListener.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/EventRule.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/LogLevelSelector.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/utils/LttngUstAgentLogger.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Manifest.txt [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulAgent.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulApi.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngLogHandler.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Manifest.txt [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jAgent.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jApi.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLogAppender.java [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/common/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/common/lttng_ust_context.c [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/common/lttng_ust_context.h [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/jul/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/jul/lttng_ust_jul.c [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/jul/lttng_ust_jul.h [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j.c [new file with mode: 0644]
src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j.h [new file with mode: 0644]
src/lib/lttng-ust-java/.gitignore [new file with mode: 0644]
src/lib/lttng-ust-java/LTTngUst.c [new file with mode: 0644]
src/lib/lttng-ust-java/Makefile.am [new file with mode: 0644]
src/lib/lttng-ust-java/README [new file with mode: 0644]
src/lib/lttng-ust-java/lttng_ust_java.h [new file with mode: 0644]
src/lib/lttng-ust-java/org/lttng/ust/LTTngUst.java [new file with mode: 0644]
src/liblttng-ust-java-agent/Makefile.am [deleted file]
src/liblttng-ust-java-agent/java/Makefile.am [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Makefile.am [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Manifest.txt [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Manifest.txt [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngHandler.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/LTTngAgent.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngAgentResponse.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableAppContextCommand.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableAppContextCommand.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoManager.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoSerializer.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/IContextInfoRetriever.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/LttngContextApi.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/FilterChangeNotifier.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/IFilterChangeListener.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/EventRule.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/LogLevelSelector.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/utils/LttngUstAgentLogger.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile.am [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Manifest.txt [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulAgent.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulApi.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngLogHandler.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile.am [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Manifest.txt [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jAgent.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jApi.java [deleted file]
src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLogAppender.java [deleted file]
src/liblttng-ust-java-agent/jni/Makefile.am [deleted file]
src/liblttng-ust-java-agent/jni/common/Makefile.am [deleted file]
src/liblttng-ust-java-agent/jni/common/lttng_ust_context.c [deleted file]
src/liblttng-ust-java-agent/jni/common/lttng_ust_context.h [deleted file]
src/liblttng-ust-java-agent/jni/jul/Makefile.am [deleted file]
src/liblttng-ust-java-agent/jni/jul/lttng_ust_jul.c [deleted file]
src/liblttng-ust-java-agent/jni/jul/lttng_ust_jul.h [deleted file]
src/liblttng-ust-java-agent/jni/log4j/Makefile.am [deleted file]
src/liblttng-ust-java-agent/jni/log4j/lttng_ust_log4j.c [deleted file]
src/liblttng-ust-java-agent/jni/log4j/lttng_ust_log4j.h [deleted file]
src/liblttng-ust-java/.gitignore [deleted file]
src/liblttng-ust-java/LTTngUst.c [deleted file]
src/liblttng-ust-java/Makefile.am [deleted file]
src/liblttng-ust-java/README [deleted file]
src/liblttng-ust-java/lttng_ust_java.h [deleted file]
src/liblttng-ust-java/org/lttng/ust/LTTngUst.java [deleted file]

index 88f36282e48cedc1909e887ff1a30a5109f4408b..0ad9442d86af4dc5bdc1478d7f386cfc215afa8c 100644 (file)
@@ -93,21 +93,21 @@ cscope.*
 /tests/unit/ust-utils/test_ust_utils_cxx
 
 # Java agent library
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-all/*.jar
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/classnoinst.stamp
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/context-jni-header.stamp
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/*.jar
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/classnoinst.stamp
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/jul-jni-header.stamp
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/*.jar
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/classnoinst.stamp
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/log4j-jni-header.stamp
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/*.jar
-/src/liblttng-ust-java-agent/jni/common/org_lttng_ust_agent_context_LttngContextApi.h
-/src/liblttng-ust-java-agent/jni/jul/org_lttng_ust_agent_jul_LttngJulApi.h
-/src/liblttng-ust-java-agent/jni/log4j/org_lttng_ust_agent_log4j_LttngLog4jApi.h
-/src/liblttng-ust-java/classnoinst.stamp
-/src/liblttng-ust-java/jni-header.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/*.jar
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/classnoinst.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/context-jni-header.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/*.jar
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/classnoinst.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/jul-jni-header.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/*.jar
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/classnoinst.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/log4j-jni-header.stamp
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/*.jar
+/src/lib/lttng-ust-java-agent/jni/common/org_lttng_ust_agent_context_LttngContextApi.h
+/src/lib/lttng-ust-java-agent/jni/jul/org_lttng_ust_agent_jul_LttngJulApi.h
+/src/lib/lttng-ust-java-agent/jni/log4j/org_lttng_ust_agent_log4j_LttngLog4jApi.h
+/src/lib/lttng-ust-java/classnoinst.stamp
+/src/lib/lttng-ust-java/jni-header.stamp
 
 # Python agent
 /src/python-lttngust/lttngust/version.py
@@ -132,17 +132,17 @@ cscope.*
 /src/lib/lttng-ust-dl/Makefile
 /src/lib/lttng-ust-fd/Makefile
 /src/lib/lttng-ust-fork/Makefile
-/src/liblttng-ust-java-agent/Makefile
-/src/liblttng-ust-java-agent/java/Makefile
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Makefile
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile
-/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile
-/src/liblttng-ust-java-agent/jni/Makefile
-/src/liblttng-ust-java-agent/jni/common/Makefile
-/src/liblttng-ust-java-agent/jni/jul/Makefile
-/src/liblttng-ust-java-agent/jni/log4j/Makefile
-/src/liblttng-ust-java/Makefile
+/src/lib/lttng-ust-java-agent/Makefile
+/src/lib/lttng-ust-java-agent/java/Makefile
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Makefile
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Makefile
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile
+/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile
+/src/lib/lttng-ust-java-agent/jni/Makefile
+/src/lib/lttng-ust-java-agent/jni/common/Makefile
+/src/lib/lttng-ust-java-agent/jni/jul/Makefile
+/src/lib/lttng-ust-java-agent/jni/log4j/Makefile
+/src/lib/lttng-ust-java/Makefile
 /src/lib/lttng-ust-libc-wrapper/Makefile
 /src/lib/lttng-ust-python-agent/Makefile
 /src/lib/Makefile
index 8b6fb56251c204570ca775a68c1185212a56a32e..d705ecb6650116ec6be9d47fee1282d7c443fae3 100644 (file)
@@ -526,17 +526,17 @@ AC_CONFIG_FILES([
   src/lib/lttng-ust-dl/Makefile
   src/lib/lttng-ust-fd/Makefile
   src/lib/lttng-ust-fork/Makefile
-  src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Makefile
-  src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile
-  src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile
-  src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile
-  src/liblttng-ust-java-agent/java/Makefile
-  src/liblttng-ust-java-agent/jni/common/Makefile
-  src/liblttng-ust-java-agent/jni/jul/Makefile
-  src/liblttng-ust-java-agent/jni/log4j/Makefile
-  src/liblttng-ust-java-agent/jni/Makefile
-  src/liblttng-ust-java-agent/Makefile
-  src/liblttng-ust-java/Makefile
+  src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Makefile
+  src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Makefile
+  src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile
+  src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile
+  src/lib/lttng-ust-java-agent/java/Makefile
+  src/lib/lttng-ust-java-agent/jni/common/Makefile
+  src/lib/lttng-ust-java-agent/jni/jul/Makefile
+  src/lib/lttng-ust-java-agent/jni/log4j/Makefile
+  src/lib/lttng-ust-java-agent/jni/Makefile
+  src/lib/lttng-ust-java-agent/Makefile
+  src/lib/lttng-ust-java/Makefile
   src/lib/lttng-ust-libc-wrapper/Makefile
   src/liblttng-ust/Makefile
   src/lib/lttng-ust-python-agent/Makefile
index 06e40662f1004e8aa6a0234330bb79584c280fbe..ce517922d06f01bcdeff7cee4e7574b22aea6a2f 100644 (file)
@@ -155,8 +155,8 @@ all-local:
                                cd $$subdir && \
                                $(MAKE) all \
                                        CLASSPATH="$(CLASSPATH)" \
-                                       JAVA_CLASSPATH_OVERRIDE_JUL="../../../src/liblttng-ust-java-agent/java/lttng-ust-agent-jul" \
-                                       JAVA_CLASSPATH_OVERRIDE_COMMON="../../../src/liblttng-ust-java-agent/java/lttng-ust-agent-common" \
+                                       JAVA_CLASSPATH_OVERRIDE_JUL="../../../src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul" \
+                                       JAVA_CLASSPATH_OVERRIDE_COMMON="../../../src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common" \
                                        $(AM_MAKEFLAGS) \
                        ) || exit 1; \
                done; \
@@ -167,8 +167,8 @@ all-local:
                                cd $$subdir && \
                                $(MAKE) all \
                                        CLASSPATH="$(CLASSPATH)" \
-                                       JAVA_CLASSPATH_OVERRIDE_LOG4J="../../../src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j" \
-                                       JAVA_CLASSPATH_OVERRIDE_COMMON="../../../src/liblttng-ust-java-agent/java/lttng-ust-agent-common" \
+                                       JAVA_CLASSPATH_OVERRIDE_LOG4J="../../../src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j" \
+                                       JAVA_CLASSPATH_OVERRIDE_COMMON="../../../src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common" \
                                        $(AM_MAKEFLAGS) \
                        ) || exit 1; \
                done; \
index 03a5fd6fe78d909164cd392d29fe9a697f0ea51c..911b04cab4e86c6f01f0ef59cfa22b618552b93d 100755 (executable)
@@ -15,9 +15,9 @@ JAVA_OPTIONS=""
 cd $DIR
 
 if [ -f "$DIR/.intree" ]; then
-       CLASSPATH="../../../liblttng-ust-java-agent/java/lttng-ust-agent-common/$JARFILE_COMMON"
-       CLASSPATH="$CLASSPATH:../../../liblttng-ust-java-agent/java/lttng-ust-agent-jul/$JARFILE_JUL"
-       LIBPATH="../../../liblttng-ust-java-agent/jni/jul/.libs"
+       CLASSPATH="../../../lib/lttng-ust-java-agent/java/lttng-ust-agent-common/$JARFILE_COMMON"
+       CLASSPATH="$CLASSPATH:../../../lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/$JARFILE_JUL"
+       LIBPATH="../../../lib/lttng-ust-java-agent/jni/jul/.libs"
 else
        CLASSPATH="/usr/local/share/java/$JARFILE_COMMON:/usr/share/java/$JARFILE_COMMON"
        CLASSPATH="$CLASSPATH:/usr/local/share/java/$JARFILE_JUL:/usr/share/java/$JARFILE_JUL"
index 056ea67f3300a3178bfbd95cc15c9de4de40d9d6..d6e5afa4be7dcb8c16fc71c1b43337c218a3e705 100755 (executable)
@@ -21,9 +21,9 @@ fi
 cd $DIR
 
 if [ -f "$DIR/.intree" ]; then
-       CLASSPATH="$CLASSPATH:../../../liblttng-ust-java-agent/java/lttng-ust-agent-common/$JARFILE_COMMON"
-       CLASSPATH="$CLASSPATH:../../../liblttng-ust-java-agent/java/lttng-ust-agent-log4j/$JARFILE_LOG4J"
-       LIBPATH="../../../liblttng-ust-java-agent/jni/log4j/.libs"
+       CLASSPATH="$CLASSPATH:../../../lib/lttng-ust-java-agent/java/lttng-ust-agent-common/$JARFILE_COMMON"
+       CLASSPATH="$CLASSPATH:../../../lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/$JARFILE_LOG4J"
+       LIBPATH="../../../lib/lttng-ust-java-agent/jni/log4j/.libs"
 else
        CLASSPATH="$CLASSPATH:/usr/local/share/java/$JARFILE_COMMON:/usr/share/java/$JARFILE_COMMON"
        CLASSPATH="$CLASSPATH:/usr/local/share/java/$JARFILE_LOG4J:/usr/share/java/$JARFILE_LOG4J"
index f51694ec2f4e198820372ce0be0b879f4938d72d..7facaf2bf20365e0575a0ae247b5e25c6e99c356 100644 (file)
@@ -9,14 +9,6 @@ SUBDIRS = \
        liblttng-ust-ctl \
        lib
 
-if ENABLE_JNI_INTERFACE
-SUBDIRS += liblttng-ust-java
-endif
-
-if ENABLE_JAVA_AGENT
-SUBDIRS += liblttng-ust-java-agent
-endif
-
 if ENABLE_PYTHON_AGENT
 SUBDIRS += python-lttngust
 endif
index 0b33906e751615a085bfa1a8e61b90688a3eed75..ec0b4538af45db5843613c0bd56ac7b88a7f86be 100644 (file)
@@ -10,6 +10,14 @@ if ENABLE_UST_DL
 SUBDIRS += lttng-ust-dl
 endif
 
+if ENABLE_JNI_INTERFACE
+SUBDIRS += lttng-ust-java
+endif
+
+if ENABLE_JAVA_AGENT
+SUBDIRS += lttng-ust-java-agent
+endif
+
 if ENABLE_PYTHON_AGENT
 SUBDIRS += lttng-ust-python-agent
 endif
diff --git a/src/lib/lttng-ust-java-agent/Makefile.am b/src/lib/lttng-ust-java-agent/Makefile.am
new file mode 100644 (file)
index 0000000..ad47256
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+SUBDIRS = java jni
diff --git a/src/lib/lttng-ust-java-agent/java/Makefile.am b/src/lib/lttng-ust-java-agent/java/Makefile.am
new file mode 100644 (file)
index 0000000..96d575a
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+SUBDIRS = lttng-ust-agent-common lttng-ust-agent-all
+
+if ENABLE_JAVA_AGENT_WITH_JUL
+SUBDIRS += lttng-ust-agent-jul
+endif
+
+if ENABLE_JAVA_AGENT_WITH_LOG4J
+SUBDIRS += lttng-ust-agent-log4j
+endif
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Makefile.am b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Makefile.am
new file mode 100644 (file)
index 0000000..b6cf9aa
--- /dev/null
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+JAVAROOT = .
+
+jarfile_version = 1.0.0
+jarfile_manifest = $(srcdir)/Manifest.txt
+jarfile_symlink = lttng-ust-agent-all.jar
+jarfile = lttng-ust-agent-all-$(jarfile_version).jar
+
+# Compatibility symlink provided for applications expecting the agent
+# jar file installed by UST 2.7.
+jarfile_compat_symlink = liblttng-ust-agent.jar
+
+jardir = $(datadir)/java
+
+dist_noinst_DATA = $(jarfile_manifest)
+
+jar_DATA = $(jarfile)
+
+$(jarfile):
+       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) \
+               && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink) \
+               && rm -f $(jarfile_compat_symlink) && $(LN_S) $(jarfile_symlink) $(jarfile_compat_symlink)
+
+install-data-hook:
+       cd $(DESTDIR)/$(jardir) \
+               && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink) \
+               && rm -f $(jarfile_compat_symlink) && $(LN_S) $(jarfile_symlink) $(jarfile_compat_symlink)
+
+uninstall-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && rm -f $(jarfile_compat_symlink)
+
+CLEANFILES = *.jar
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Manifest.txt b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-all/Manifest.txt
new file mode 100644 (file)
index 0000000..e09c85e
--- /dev/null
@@ -0,0 +1,8 @@
+Name: org/lttng/ust/agent/all/
+Specification-Title: LTTng UST All Java Agents
+Specification-Version: 1.0.0
+Specification-Vendor: LTTng Project
+Implementation-Title: org.lttng.ust.agent.all
+Implementation-Version: 1.0.0
+Implementation-Vendor: LTTng Project
+Class-Path: lttng-ust-agent-common.jar lttng-ust-agent-jul.jar lttng-ust-agent-log4j.jar
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am
new file mode 100644 (file)
index 0000000..473e872
--- /dev/null
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+JAVAROOT = .
+
+pkgpath = org/lttng/ust/agent
+
+jarfile_version = 1.0.0
+jarfile_manifest = $(srcdir)/Manifest.txt
+jarfile_symlink = lttng-ust-agent-common.jar
+jarfile = lttng-ust-agent-common-$(jarfile_version).jar
+
+jardir = $(datadir)/java
+jnioutdir = ../../jni/common
+
+dist_noinst_JAVA = $(pkgpath)/AbstractLttngAgent.java \
+                                  $(pkgpath)/EventNamePattern.java \
+                                  $(pkgpath)/ILttngAgent.java \
+                                  $(pkgpath)/ILttngHandler.java \
+                                  $(pkgpath)/LTTngAgent.java \
+                                  $(pkgpath)/client/ILttngTcpClientListener.java \
+                                  $(pkgpath)/client/SessiondCommand.java \
+                                  $(pkgpath)/client/LttngAgentResponse.java \
+                                  $(pkgpath)/client/LttngTcpSessiondClient.java \
+                                  $(pkgpath)/client/SessiondCommandHeader.java \
+                                  $(pkgpath)/client/SessiondDisableAppContextCommand.java \
+                                  $(pkgpath)/client/SessiondDisableEventCommand.java \
+                                  $(pkgpath)/client/SessiondEnableAppContextCommand.java \
+                                  $(pkgpath)/client/SessiondEnableEventCommand.java \
+                                  $(pkgpath)/client/SessiondListLoggersCommand.java \
+                                  $(pkgpath)/context/LttngContextApi.java \
+                                  $(pkgpath)/context/ContextInfoManager.java \
+                                  $(pkgpath)/context/ContextInfoSerializer.java \
+                                  $(pkgpath)/context/IContextInfoRetriever.java \
+                                  $(pkgpath)/filter/FilterChangeNotifier.java \
+                                  $(pkgpath)/filter/IFilterChangeListener.java \
+                                  $(pkgpath)/session/EventRule.java \
+                                  $(pkgpath)/session/LogLevelSelector.java \
+                                  $(pkgpath)/utils/LttngUstAgentLogger.java
+
+
+dist_noinst_DATA = $(jarfile_manifest)
+
+jar_DATA = $(jarfile)
+
+classes = $(pkgpath)/*.class \
+                 $(pkgpath)/client/*.class \
+                 $(pkgpath)/context/*.class \
+                 $(pkgpath)/filter/*.class \
+                 $(pkgpath)/session/*.class \
+                 $(pkgpath)/utils/*.class
+
+$(jarfile): classnoinst.stamp
+       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
+
+if !HAVE_JAVAH
+# If we don't have javah, assume we are running openjdk >= 10 and use javac
+# to generate the jni header file.
+AM_JAVACFLAGS = -h $(jnioutdir)
+else
+context-jni-header.stamp: $(dist_noinst_JAVA)
+       $(JAVAH) -classpath $(CLASSPATH):$(srcdir) -d $(jnioutdir) $(JAVAHFLAGS) org.lttng.ust.agent.context.LttngContextApi && \
+       echo "Context API JNI header generated" > context-jni-header.stamp
+
+all-local: context-jni-header.stamp
+endif
+
+install-data-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink)
+
+uninstall-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
+
+CLEANFILES = *.jar \
+                        $(pkgpath)/*.class \
+                        $(pkgpath)/client/*.class \
+                        $(pkgpath)/context/*.class \
+                        $(pkgpath)/filter/*.class \
+                        $(pkgpath)/session/*.class \
+                        $(pkgpath)/utils/*.class \
+                        context-jni-header.stamp \
+                        $(jnioutdir)/org_lttng_ust_agent_context_LttngContextApi.h
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Manifest.txt b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/Manifest.txt
new file mode 100644 (file)
index 0000000..d3c7e26
--- /dev/null
@@ -0,0 +1,7 @@
+Name: org/lttng/ust/agent/
+Specification-Title: LTTng UST Java Agent
+Specification-Version: 1.0.0
+Specification-Vendor: LTTng Project
+Implementation-Title: org.lttng.ust.agent
+Implementation-Version: 1.0.0
+Implementation-Vendor: LTTng Project
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java
new file mode 100644 (file)
index 0000000..acbdc4f
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Matcher;
+
+import org.lttng.ust.agent.client.ILttngTcpClientListener;
+import org.lttng.ust.agent.client.LttngTcpSessiondClient;
+import org.lttng.ust.agent.filter.FilterChangeNotifier;
+import org.lttng.ust.agent.session.EventRule;
+import org.lttng.ust.agent.utils.LttngUstAgentLogger;
+
+/**
+ * Base implementation of a {@link ILttngAgent}.
+ *
+ * @author Alexandre Montplaisir
+ * @param <T>
+ *            The type of logging handler that should register to this agent
+ */
+public abstract class AbstractLttngAgent<T extends ILttngHandler>
+               implements ILttngAgent<T>, ILttngTcpClientListener {
+
+       private static final int INIT_TIMEOUT = 3; /* Seconds */
+
+       /** The handlers registered to this agent */
+       private final Set<T> registeredHandlers = new HashSet<T>();
+
+       /**
+        * The trace events currently enabled in the sessions.
+        *
+        * The key is the {@link EventNamePattern} that comes from the event name.
+        * The value is the ref count (how many different sessions currently have
+        * this event enabled). Once the ref count falls to 0, this means we can
+        * avoid sending log events through JNI because nobody wants them.
+        *
+        * Its accesses should be protected by the {@link #enabledEventNamesLock}
+        * below.
+        */
+       private final Map<EventNamePattern, Integer> enabledPatterns = new HashMap<EventNamePattern, Integer>();
+
+       /**
+        * Cache of already-checked event names. As long as enabled/disabled events
+        * don't change in the session, we can avoid re-checking events that were
+        * previously checked against all known enabled patterns.
+        *
+        * Its accesses should be protected by the {@link #enabledEventNamesLock}
+        * below, with the exception of concurrent get operations.
+        */
+       private final Map<String, Boolean> enabledEventNamesCache = new ConcurrentHashMap<String, Boolean>();
+
+       /**
+        * Lock protecting accesses to the {@link #enabledPatterns} and
+        * {@link #enabledEventNamesCache} maps.
+        */
+       private final Lock enabledEventNamesLock = new ReentrantLock();
+
+       /**
+        * The application contexts currently enabled in the tracing sessions.
+        *
+        * It is first indexed by context retriever, then by context name. This
+        * allows to efficiently query all the contexts for a given retriever.
+        *
+        * Works similarly as {@link #enabledEvents}, but for app contexts (and with
+        * an extra degree of indexing).
+        *
+        * TODO Could be changed to a Guava Table once/if we start using it.
+        */
+       private final Map<String, Map<String, Integer>> enabledAppContexts = new ConcurrentHashMap<String, Map<String, Integer>>();
+
+       /** Tracing domain. Defined by the sub-classes via the constructor. */
+       private final Domain domain;
+
+       /* Lazy-loaded sessiond clients and their thread objects */
+       private LttngTcpSessiondClient rootSessiondClient = null;
+       private LttngTcpSessiondClient userSessiondClient = null;
+       private Thread rootSessiondClientThread = null;
+       private Thread userSessiondClientThread = null;
+
+       /** Indicates if this agent has been initialized. */
+       private boolean initialized = false;
+
+       /**
+        * Constructor. Should only be called by sub-classes via super(...);
+        *
+        * @param domain
+        *            The tracing domain of this agent.
+        */
+       protected AbstractLttngAgent(Domain domain) {
+               this.domain = domain;
+       }
+
+       @Override
+       public Domain getDomain() {
+               return domain;
+       }
+
+       @Override
+       public void registerHandler(T handler) {
+               synchronized (registeredHandlers) {
+                       if (registeredHandlers.isEmpty()) {
+                               /*
+                                * This is the first handler that registers, we will initialize
+                                * the agent.
+                                */
+                               init();
+                       }
+                       registeredHandlers.add(handler);
+               }
+       }
+
+       @Override
+       public void unregisterHandler(T handler) {
+               synchronized (registeredHandlers) {
+                       registeredHandlers.remove(handler);
+                       if (registeredHandlers.isEmpty()) {
+                               /* There are no more registered handlers, close the connection. */
+                               dispose();
+                       }
+               }
+       }
+
+       private void init() {
+               /*
+                * Only called from a synchronized (registeredHandlers) block, should
+                * not need additional synchronization.
+                */
+               if (initialized) {
+                       return;
+               }
+
+               LttngUstAgentLogger.log(AbstractLttngAgent.class, "Initializing Agent for domain: " + domain.name());
+
+               String rootClientThreadName = "Root sessiond client started by agent: " + this.getClass().getSimpleName();
+
+               rootSessiondClient = new LttngTcpSessiondClient(this, getDomain().value(), true);
+               rootSessiondClientThread = new Thread(rootSessiondClient, rootClientThreadName);
+               rootSessiondClientThread.setDaemon(true);
+               rootSessiondClientThread.start();
+
+               String userClientThreadName = "User sessiond client started by agent: " + this.getClass().getSimpleName();
+
+               userSessiondClient = new LttngTcpSessiondClient(this, getDomain().value(), false);
+               userSessiondClientThread = new Thread(userSessiondClient, userClientThreadName);
+               userSessiondClientThread.setDaemon(true);
+               userSessiondClientThread.start();
+
+               /* Give the threads' registration a chance to end. */
+               if (!rootSessiondClient.waitForConnection(INIT_TIMEOUT)) {
+                       userSessiondClient.waitForConnection(INIT_TIMEOUT);
+               }
+
+               initialized = true;
+       }
+
+       /**
+        * Dispose the agent
+        */
+       private void dispose() {
+               LttngUstAgentLogger.log(AbstractLttngAgent.class, "Disposing Agent for domain: " + domain.name());
+
+               /*
+                * Only called from a synchronized (registeredHandlers) block, should
+                * not need additional synchronization.
+                */
+               rootSessiondClient.close();
+               userSessiondClient.close();
+
+               try {
+                       rootSessiondClientThread.join();
+                       userSessiondClientThread.join();
+
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+               rootSessiondClient = null;
+               rootSessiondClientThread = null;
+               userSessiondClient = null;
+               userSessiondClientThread = null;
+
+               /*
+                * Send filter change notifications for all event rules currently
+                * active, then clear them.
+                */
+               FilterChangeNotifier fcn = FilterChangeNotifier.getInstance();
+
+               enabledEventNamesLock.lock();
+               try {
+                       for (Map.Entry<EventNamePattern, Integer> entry : enabledPatterns.entrySet()) {
+                               String eventName = entry.getKey().getEventName();
+                               Integer nb = entry.getValue();
+                               for (int i = 0; i < nb.intValue(); i++) {
+                                       fcn.removeEventRules(eventName);
+                               }
+                       }
+                       enabledPatterns.clear();
+                       enabledEventNamesCache.clear();
+               } finally {
+                       enabledEventNamesLock.unlock();
+               }
+
+               /*
+                * Also clear tracked app contexts (no filter notifications sent for
+                * those currently).
+                */
+               enabledAppContexts.clear();
+
+               initialized = false;
+       }
+
+       @Override
+       public boolean eventEnabled(EventRule eventRule) {
+               /* Notify the filter change manager of the command */
+               FilterChangeNotifier.getInstance().addEventRule(eventRule);
+
+               String eventName = eventRule.getEventName();
+               EventNamePattern pattern = new EventNamePattern(eventName);
+
+               enabledEventNamesLock.lock();
+               try {
+                       boolean ret = incrementRefCount(pattern, enabledPatterns);
+                       enabledEventNamesCache.clear();
+                       return ret;
+               } finally {
+                       enabledEventNamesLock.unlock();
+               }
+       }
+
+       @Override
+       public boolean eventDisabled(String eventName) {
+               /* Notify the filter change manager of the command */
+               FilterChangeNotifier.getInstance().removeEventRules(eventName);
+
+               EventNamePattern pattern = new EventNamePattern(eventName);
+
+               enabledEventNamesLock.lock();
+               try {
+                       boolean ret = decrementRefCount(pattern, enabledPatterns);
+                       enabledEventNamesCache.clear();
+                       return ret;
+               } finally {
+                       enabledEventNamesLock.unlock();
+               }
+       }
+
+       @Override
+       public boolean appContextEnabled(String contextRetrieverName, String contextName) {
+               synchronized (enabledAppContexts) {
+                       Map<String, Integer> retrieverMap = enabledAppContexts.get(contextRetrieverName);
+                       if (retrieverMap == null) {
+                               /* There is no submap for this retriever, let's create one. */
+                               retrieverMap = new ConcurrentHashMap<String, Integer>();
+                               enabledAppContexts.put(contextRetrieverName, retrieverMap);
+                       }
+
+                       return incrementRefCount(contextName, retrieverMap);
+               }
+       }
+
+       @Override
+       public boolean appContextDisabled(String contextRetrieverName, String contextName) {
+               synchronized (enabledAppContexts) {
+                       Map<String, Integer> retrieverMap = enabledAppContexts.get(contextRetrieverName);
+                       if (retrieverMap == null) {
+                               /* There was no submap for this retriever, invalid command? */
+                               return false;
+                       }
+
+                       boolean ret = decrementRefCount(contextName, retrieverMap);
+
+                       /* If the submap is now empty we can remove it from the main map. */
+                       if (retrieverMap.isEmpty()) {
+                               enabledAppContexts.remove(contextRetrieverName);
+                       }
+
+                       return ret;
+               }
+       }
+
+       /*
+        * Implementation of this method is domain-specific.
+        */
+       @Override
+       public abstract Collection<String> listAvailableEvents();
+
+       @Override
+       public boolean isEventEnabled(String eventName) {
+               Boolean cachedEnabled = enabledEventNamesCache.get(eventName);
+               if (cachedEnabled != null) {
+                       /* We have seen this event previously */
+                       /*
+                        * Careful! enabled == null could also mean that the null value is
+                        * associated with the key. But we should have never inserted null
+                        * values in the map.
+                        */
+                       return cachedEnabled.booleanValue();
+               }
+
+               /*
+                * We have not previously checked this event. Run it against all known
+                * enabled event patterns to determine if it should pass or not.
+                */
+               enabledEventNamesLock.lock();
+               try {
+                       boolean enabled = false;
+                       for (EventNamePattern enabledPattern : enabledPatterns.keySet()) {
+                               Matcher matcher = enabledPattern.getPattern().matcher(eventName);
+                               if (matcher.matches()) {
+                                       enabled = true;
+                                       break;
+                               }
+                       }
+
+                       /* Add the result to the cache */
+                       enabledEventNamesCache.put(eventName, Boolean.valueOf(enabled));
+                       return enabled;
+
+               } finally {
+                       enabledEventNamesLock.unlock();
+               }
+       }
+
+       @Override
+       public Collection<Map.Entry<String, Map<String, Integer>>> getEnabledAppContexts() {
+               return enabledAppContexts.entrySet();
+       }
+
+       private static <T> boolean incrementRefCount(T key, Map<T, Integer> refCountMap) {
+               synchronized (refCountMap) {
+                       Integer count = refCountMap.get(key);
+                       if (count == null) {
+                               /* This is the first instance of this event being enabled */
+                               refCountMap.put(key, Integer.valueOf(1));
+                               return true;
+                       }
+                       if (count.intValue() <= 0) {
+                               /* It should not have been in the map in the first place! */
+                               throw new IllegalStateException();
+                       }
+                       /* The event was already enabled, increment its refcount */
+                       refCountMap.put(key, Integer.valueOf(count.intValue() + 1));
+                       return true;
+               }
+       }
+
+       private static <T> boolean decrementRefCount(T key, Map<T, Integer> refCountMap) {
+               synchronized (refCountMap) {
+                       Integer count = refCountMap.get(key);
+                       if (count == null || count.intValue() <= 0) {
+                               /*
+                                * The sessiond asked us to disable an event that was not
+                                * enabled previously. Command error?
+                                */
+                               return false;
+                       }
+                       if (count.intValue() == 1) {
+                               /*
+                                * This is the last instance of this event being disabled,
+                                * remove it from the map so that we stop sending it.
+                                */
+                               refCountMap.remove(key);
+                               return true;
+                       }
+                       /*
+                        * Other sessions are still looking for this event, simply decrement
+                        * its refcount.
+                        */
+                       refCountMap.put(key, Integer.valueOf(count.intValue() - 1));
+                       return true;
+               }
+       }
+}
+
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java
new file mode 100644 (file)
index 0000000..ada5c95
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2017 EfficiOS Inc.
+ * Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+ */
+
+package org.lttng.ust.agent;
+
+import java.util.regex.Pattern;
+
+/**
+ * Class encapsulating an event name from the session daemon, and its
+ * corresponding {@link Pattern}. This allows referring back to the original
+ * event name, for example when we receive a disable command.
+ *
+ * @author Philippe Proulx
+ * @author Alexandre Montplaisir
+ */
+class EventNamePattern {
+
+       private final String originalEventName;
+
+       /*
+        * Note that two Patterns coming from the exact same String will not be
+        * equals()! As such, it would be confusing to make the pattern part of this
+        * class's equals/hashCode
+        */
+       private final transient Pattern pattern;
+
+       public EventNamePattern(String eventName) {
+               if (eventName == null) {
+                       throw new IllegalArgumentException();
+               }
+
+               originalEventName = eventName;
+               pattern = patternFromEventName(eventName);
+       }
+
+       public String getEventName() {
+               return originalEventName;
+       }
+
+       public Pattern getPattern() {
+               return pattern;
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + originalEventName.hashCode();
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj) {
+                       return true;
+               }
+               if (obj == null) {
+                       return false;
+               }
+               if (getClass() != obj.getClass()) {
+                       return false;
+               }
+               EventNamePattern other = (EventNamePattern) obj;
+               if (!originalEventName.equals(other.originalEventName)) {
+                       return false;
+               }
+               return true;
+       }
+
+       private static Pattern patternFromEventName(String eventName) {
+               /*
+                * The situation here is that `\*` means a literal `*` in the event
+                * name, and `*` is a wildcard star. We check the event name one
+                * character at a time and create a list of tokens to be converter to
+                * partial patterns.
+                */
+               StringBuilder bigBuilder = new StringBuilder("^");
+               StringBuilder smallBuilder = new StringBuilder();
+
+               for (int i = 0; i < eventName.length(); i++) {
+                       char c = eventName.charAt(i);
+
+                       switch (c) {
+                       case '*':
+                               /* Add current quoted builder's string if not empty. */
+                               if (smallBuilder.length() > 0) {
+                                       bigBuilder.append(Pattern.quote(smallBuilder.toString()));
+                                       smallBuilder.setLength(0);
+                               }
+
+                               /* Append the equivalent regex which is `.*`. */
+                               bigBuilder.append(".*");
+                               continue;
+
+                       case '\\':
+                               /* We only escape `*` and `\` here. */
+                               if (i < (eventName.length() - 1)) {
+                                       char nextChar = eventName.charAt(i + 1);
+
+                                       if (nextChar == '*' || nextChar == '\\') {
+                                               smallBuilder.append(nextChar);
+                                       } else {
+                                               smallBuilder.append(c);
+                                               smallBuilder.append(nextChar);
+                                       }
+
+                                       i++;
+                                       continue;
+                               }
+                               break;
+
+                       default:
+                               break;
+                       }
+
+                       smallBuilder.append(c);
+               }
+
+               /* Add current quoted builder's string if not empty. */
+               if (smallBuilder.length() > 0) {
+                       bigBuilder.append(Pattern.quote(smallBuilder.toString()));
+               }
+
+               bigBuilder.append("$");
+
+               return Pattern.compile(bigBuilder.toString());
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java
new file mode 100644 (file)
index 0000000..ca2358a
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Interface to define LTTng Java agents.
+ *
+ * An "agent" is a representative of an LTTng session daemon in the Java world.
+ * It tracks the settings of a tracing session as they defined in the session
+ * daemon.
+ *
+ * It also track the current logging handlers that are sending events to UST.
+ *
+ * @author Alexandre Montplaisir
+ *
+ * @param <T>
+ *            The type of logging handler that should register to this agent
+ */
+public interface ILttngAgent<T extends ILttngHandler> {
+
+       // ------------------------------------------------------------------------
+       // Agent configuration elements
+       // ------------------------------------------------------------------------
+
+       /**
+        * Tracing domains. Corresponds to domains defined by LTTng Tools.
+        */
+       enum Domain {
+               JUL(3), LOG4J(4);
+               private int value;
+
+               private Domain(int value) {
+                       this.value = value;
+               }
+
+               public int value() {
+                       return value;
+               }
+       }
+
+       /**
+        * The tracing domain of this agent.
+        *
+        * @return The tracing domain.
+        */
+       Domain getDomain();
+
+       // ------------------------------------------------------------------------
+       // Log handler registering
+       // ------------------------------------------------------------------------
+
+       /**
+        * Register a handler to this agent.
+        *
+        * @param handler
+        *            The handler to register
+        */
+       void registerHandler(T handler);
+
+       /**
+        * Deregister a handler from this agent.
+        *
+        * @param handler
+        *            The handler to deregister.
+        */
+       void unregisterHandler(T handler);
+
+       // ------------------------------------------------------------------------
+       // Tracing session parameters
+       // ------------------------------------------------------------------------
+
+       /**
+        * Query if a given event is currently enabled in a current tracing session,
+        * meaning it should be sent to UST.
+        *
+        * @param eventName
+        *            The name of the event to check.
+        * @return True if the event is currently enabled, false if it is not.
+        */
+       boolean isEventEnabled(String eventName);
+
+       /**
+        * Return the list of application contexts enabled in the tracing sessions.
+        *
+        * @return The application contexts, first indexed by retriever name, then
+        *         by context name
+        */
+       Collection<Map.Entry<String, Map<String, Integer>>> getEnabledAppContexts();
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngHandler.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngHandler.java
new file mode 100644 (file)
index 0000000..0d1bd79
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent;
+
+/**
+ * Simple interface to organize all LTTng log handlers under one type.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface ILttngHandler {
+
+       /**
+        * Get the number of events logged by this handler since its inception.
+        * 
+        * @return The number of logged events
+        */
+       long getEventCount();
+
+       /**
+        * Close the log handler. Should be called once the application is done
+        * logging through it.
+        */
+       void close();
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/LTTngAgent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/LTTngAgent.java
new file mode 100644 (file)
index 0000000..f6aae35
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.logging.Handler;
+import java.util.logging.Logger;
+
+/**
+ * The central agent managing the JUL and Log4j handlers.
+ *
+ * @author David Goulet
+ * @deprecated Applications are now expected to manage their Logger and Handler
+ *             objects.
+ */
+@Deprecated
+public class LTTngAgent {
+
+       private static LTTngAgent instance = null;
+
+       /**
+        * Public getter to acquire a reference to this singleton object.
+        *
+        * @return The agent instance
+        */
+       public static synchronized LTTngAgent getLTTngAgent() {
+               if (instance == null) {
+                       instance = new LTTngAgent();
+               }
+               return instance;
+       }
+
+       /**
+        * Dispose the agent. Applications should call this once they are done
+        * logging. This dispose function is non-static for backwards
+        * compatibility purposes.
+        */
+       @SuppressWarnings("static-method")
+       public void dispose() {
+               synchronized (LTTngAgent.class) {
+                       if (instance != null) {
+                               instance.disposeInstance();
+                               instance = null;
+                       }
+               }
+               return;
+       }
+
+       private ILttngHandler julHandler = null;
+       private ILttngHandler log4jAppender = null;
+
+       /**
+        * Private constructor. This is a singleton and a reference should be
+        * acquired using {@link #getLTTngAgent()}.
+        */
+       private LTTngAgent() {
+               initJulHandler();
+               initLog4jAppender();
+       }
+
+       /**
+        * "Destructor" method.
+        */
+       private void disposeInstance() {
+               disposeJulHandler();
+               disposeLog4jAppender();
+       }
+
+       /**
+        * Create a LTTng-JUL handler, and attach it to the JUL root logger.
+        */
+       private void initJulHandler() {
+               try {
+                       Class<?> julHandlerClass = Class.forName("org.lttng.ust.agent.jul.LttngLogHandler");
+                       /*
+                        * It is safer to use Constructor.newInstance() rather than
+                        * Class.newInstance(), because it will catch the exceptions thrown
+                        * by the constructor below (which happens if the Java library is
+                        * present, but the matching JNI one is not).
+                        */
+                       Constructor<?> julHandlerCtor = julHandlerClass.getConstructor();
+                       julHandler = (ILttngHandler) julHandlerCtor.newInstance();
+
+                       /* Attach the handler to the root JUL logger */
+                       Logger.getLogger("").addHandler((Handler) julHandler);
+
+                       /*
+                        * If any of the following exceptions happen, it means we could not
+                        * find or initialize LTTng JUL classes. We will not setup LTTng JUL
+                        * tracing in this case.
+                        */
+               } catch (SecurityException e) {
+               } catch (IllegalAccessException e) {
+               } catch (IllegalArgumentException e) {
+               } catch (ClassNotFoundException e) {
+               } catch (NoSuchMethodException e) {
+               } catch (InstantiationException e) {
+               } catch (InvocationTargetException e) {
+               }
+       }
+
+       /**
+        * Create a LTTng-logj4 appender, and attach it to the log4j root logger.
+        */
+       private void initLog4jAppender() {
+               /*
+                * Since Log4j is a 3rd party library, we first need to check if we can
+                * load any of its classes.
+                */
+               if (!testLog4jClasses()) {
+                       return;
+               }
+
+               try {
+                       Class<?> log4jAppenderClass = Class.forName("org.lttng.ust.agent.log4j.LttngLogAppender");
+                       Constructor<?> log4jAppendCtor = log4jAppenderClass.getConstructor();
+                       log4jAppender = (ILttngHandler) log4jAppendCtor.newInstance();
+
+                       /*
+                        * If any of the following exceptions happen, it means we could not
+                        * find or initialize LTTng log4j classes. We will not setup LTTng
+                        * log4j tracing in this case.
+                        */
+               } catch (SecurityException e) {
+                       return;
+               } catch (ClassNotFoundException e) {
+                       return;
+               } catch (NoSuchMethodException e) {
+                       return;
+               } catch (IllegalArgumentException e) {
+                       return;
+               } catch (InstantiationException e) {
+                       return;
+               } catch (IllegalAccessException e) {
+                       return;
+               } catch (InvocationTargetException e) {
+                       return;
+               }
+
+               /*
+                * Attach the appender to the root Log4j logger. Slightly more tricky
+                * here, as log4j.Logger is not in the base Java library, and we do not
+                * want the "common" package to depend on log4j. So we have to obtain it
+                * through reflection too.
+                */
+               try {
+                       Class<?> loggerClass = Class.forName("org.apache.log4j.Logger");
+                       Class<?> appenderClass = Class.forName("org.apache.log4j.Appender");
+
+                       Method getRootLoggerMethod = loggerClass.getMethod("getRootLogger", (Class<?>[]) null);
+                       Method addAppenderMethod = loggerClass.getMethod("addAppender", appenderClass);
+
+                       Object rootLogger = getRootLoggerMethod.invoke(null, (Object[]) null);
+                       addAppenderMethod.invoke(rootLogger, log4jAppender);
+
+                       /*
+                        * We have checked for the log4j library version previously, none of
+                        * the following exceptions should happen.
+                        */
+               } catch (SecurityException e) {
+                       throw new IllegalStateException(e);
+               } catch (ClassNotFoundException e) {
+                       throw new IllegalStateException(e);
+               } catch (NoSuchMethodException e) {
+                       throw new IllegalStateException(e);
+               } catch (IllegalArgumentException e) {
+                       throw new IllegalStateException(e);
+               } catch (IllegalAccessException e) {
+                       throw new IllegalStateException(e);
+               } catch (InvocationTargetException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       /**
+        * Check if log4j >= 1.2.15 library is present.
+        */
+       private static boolean testLog4jClasses() {
+               Class<?> loggingEventClass;
+
+               try {
+                       loggingEventClass = Class.forName("org.apache.log4j.spi.LoggingEvent");
+               } catch (ClassNotFoundException e) {
+                       /*
+                        * Log4j classes not found, no need to create the relevant objects
+                        */
+                       return false;
+               }
+
+               /*
+                * Detect capabilities of the log4j library. We only support log4j >=
+                * 1.2.15. The getTimeStamp() method was introduced in log4j 1.2.15, so
+                * verify that it is available.
+                *
+                * We can't rely on the getPackage().getImplementationVersion() call
+                * that would retrieves information from the manifest file found in the
+                * JAR since the manifest file shipped from upstream is known to be
+                * broken in several versions of the library.
+                *
+                * More info: https://issues.apache.org/bugzilla/show_bug.cgi?id=44370
+                */
+               try {
+                       loggingEventClass.getDeclaredMethod("getTimeStamp");
+               } catch (NoSuchMethodException e) {
+                       System.err.println(
+                                       "Warning: The loaded log4j library is too old. Log4j tracing with LTTng will be disabled.");
+                       return false;
+               } catch (SecurityException e) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Detach the JUL handler from its logger and close it.
+        */
+       private void disposeJulHandler() {
+               if (julHandler == null) {
+                       /* The JUL handler was not activated, we have nothing to do */
+                       return;
+               }
+               Logger.getLogger("").removeHandler((Handler) julHandler);
+               julHandler.close();
+               julHandler = null;
+       }
+
+       /**
+        * Detach the log4j appender from its logger and close it.
+        */
+       private void disposeLog4jAppender() {
+               if (log4jAppender == null) {
+                       /* The log4j appender was not active, we have nothing to do */
+                       return;
+               }
+
+               /*
+                * Detach the appender from the log4j root logger. Again, we have to do
+                * this via reflection.
+                */
+               try {
+                       Class<?> loggerClass = Class.forName("org.apache.log4j.Logger");
+                       Class<?> appenderClass = Class.forName("org.apache.log4j.Appender");
+
+                       Method getRootLoggerMethod = loggerClass.getMethod("getRootLogger", (Class<?>[]) null);
+                       Method removeAppenderMethod = loggerClass.getMethod("removeAppender", appenderClass);
+
+                       Object rootLogger = getRootLoggerMethod.invoke(null, (Object[]) null);
+                       removeAppenderMethod.invoke(rootLogger, log4jAppender);
+
+                       /*
+                        * We were able to attach the appender previously, we should not
+                        * have problems here either!
+                        */
+               } catch (SecurityException e) {
+                       throw new IllegalStateException(e);
+               } catch (ClassNotFoundException e) {
+                       throw new IllegalStateException(e);
+               } catch (NoSuchMethodException e) {
+                       throw new IllegalStateException(e);
+               } catch (IllegalArgumentException e) {
+                       throw new IllegalStateException(e);
+               } catch (IllegalAccessException e) {
+                       throw new IllegalStateException(e);
+               } catch (InvocationTargetException e) {
+                       throw new IllegalStateException(e);
+               }
+
+               /* Close the appender */
+               log4jAppender.close();
+               log4jAppender = null;
+       }
+
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java
new file mode 100644 (file)
index 0000000..e6edb56
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.util.Collection;
+
+import org.lttng.ust.agent.session.EventRule;
+
+/**
+ * TCP client listener interface.
+ *
+ * This interface contains callbacks that are called when the TCP client
+ * receives commands from the session daemon. These callbacks will define what
+ * do to with each command.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface ILttngTcpClientListener {
+
+       /**
+        * Callback for the TCP client to notify the listener agent that a request
+        * for enabling an event rule was sent from the session daemon.
+        *
+        * @param eventRule
+        *            The event rule that was requested to be enabled
+        * @return Since we do not track individual sessions, right now this command
+        *         cannot fail. It will always return true.
+        */
+       boolean eventEnabled(EventRule eventRule);
+
+       /**
+        * Callback for the TCP client to notify the listener agent that a request
+        * for disabling an event was sent from the session daemon.
+        *
+        * @param eventName
+        *            The name of the event that was requested to be disabled.
+        * @return True if the command completed successfully, false if we should
+        *         report an error (event was not enabled, etc.)
+        */
+       boolean eventDisabled(String eventName);
+
+       /**
+        * Callback for the TCP client to notify the listener agent that a request
+        * for enabling an application-specific context was sent from the session
+        * daemon.
+        *
+        * @param contextRetrieverName
+        *            The name of the retriever in which the context is present.
+        *            This is used to namespace the contexts.
+        * @param contextName
+        *            The name of the context that was requested to be enabled
+        * @return Since we do not track individual sessions, right now this command
+        *         cannot fail. It will always return true.
+        */
+       boolean appContextEnabled(String contextRetrieverName, String contextName);
+
+       /**
+        * Callback for the TCP client to notify the listener agent that a request
+        * for disabling an application-specific context was sent from the session
+        * daemon.
+        *
+        * @param contextRetrieverName
+        *            The name of the retriever in which the context is present.
+        *            This is used to namespace the contexts.
+        * @param contextName
+        *            The name of the context that was requested to be disabled.
+        * @return True if the command completed successfully, false if we should
+        *         report an error (context was not previously enabled for example)
+        */
+       boolean appContextDisabled(String contextRetrieverName, String contextName);
+
+       /**
+        * List the events that are available in the agent's tracing domain.
+        *
+        * In Java terms, this means loggers that have at least one LTTng log
+        * handler of their corresponding domain attached.
+        *
+        * @return The list of available events
+        */
+       Collection<String> listAvailableEvents();
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngAgentResponse.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngAgentResponse.java
new file mode 100644 (file)
index 0000000..4ffeccd
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Interface for all response messages sent from the Java agent to the sessiond
+ * daemon. Normally sent after a command coming from the session daemon was
+ * executed.
+ *
+ * @author Alexandre Montplaisir
+ */
+abstract class LttngAgentResponse {
+
+       private static final int INT_SIZE = 4;
+
+       public static final LttngAgentResponse SUCESS_RESPONSE = new LttngAgentResponse() {
+               @Override
+               public ReturnCode getReturnCode() {
+                       return ReturnCode.CODE_SUCCESS_CMD;
+               }
+       };
+
+       public static final LttngAgentResponse FAILURE_RESPONSE = new LttngAgentResponse() {
+               @Override
+               public ReturnCode getReturnCode() {
+                       return ReturnCode.CODE_INVALID_CMD;
+               }
+       };
+
+       /**
+        * Return codes used in agent responses, to indicate success or different
+        * types of failures of the commands.
+        */
+       protected enum ReturnCode {
+
+               CODE_SUCCESS_CMD(1, "sucess"),
+               CODE_INVALID_CMD(2, "invalid"),
+               CODE_UNKNOWN_LOGGER_NAME(3, "unknown logger name");
+
+               private final int code;
+               private final String toString;
+
+               private ReturnCode(int c, String str) {
+                       code = c;
+                       toString = str;
+               }
+
+               public int getCode() {
+                       return code;
+               }
+
+               /**
+                * Mainly used for debugging. The strings are not sent through the
+                * socket.
+                */
+               @Override
+               public String toString() {
+                       return toString;
+               }
+       }
+
+       /**
+        * Get the {@link ReturnCode} that goes with this response. It is expected
+        * by the session daemon, but some commands may require more than this
+        * in their response.
+        *
+        * @return The return code
+        */
+       public abstract ReturnCode getReturnCode();
+
+       /**
+        * Gets a byte array of the response so that it may be streamed.
+        *
+        * @return The byte array of the response
+        */
+       public byte[] getBytes() {
+               byte data[] = new byte[INT_SIZE];
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               buf.order(ByteOrder.BIG_ENDIAN);
+               buf.putInt(getReturnCode().getCode());
+               return data;
+       }
+
+       @Override
+       public String toString() {
+               return "LttngAgentResponse["
+                               + "code=" + getReturnCode().getCode()
+                               + ", " + getReturnCode().toString()
+                               + "]";
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java
new file mode 100644 (file)
index 0000000..9fa8c3a
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015-2016 EfficiOS Inc.
+ * Copyright (C) 2015-2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.lttng.ust.agent.utils.LttngUstAgentLogger;
+
+/**
+ * Client for agents to connect to a local session daemon, using a TCP socket.
+ *
+ * @author David Goulet
+ */
+public class LttngTcpSessiondClient implements Runnable {
+
+       private static final String SESSION_HOST = "127.0.0.1";
+       private static final String ROOT_PORT_FILE = "/var/run/lttng/agent.port";
+       private static final String USER_PORT_FILE = "/.lttng/agent.port";
+       private static final Charset PORT_FILE_ENCODING = Charset.forName("UTF-8");
+
+       private static final int PROTOCOL_MAJOR_VERSION = 2;
+       private static final int PROTOCOL_MINOR_VERSION = 0;
+
+       /** Command header from the session deamon. */
+       private final CountDownLatch registrationLatch = new CountDownLatch(1);
+
+       private Socket sessiondSock;
+       private volatile boolean quit = false;
+
+       private DataInputStream inFromSessiond;
+       private DataOutputStream outToSessiond;
+
+       private final ILttngTcpClientListener logAgent;
+       private final int domainValue;
+       private final boolean isRoot;
+
+       /**
+        * Constructor
+        *
+        * @param logAgent
+        *            The listener this client will operate on, typically an LTTng
+        *            agent.
+        * @param domainValue
+        *            The integer to send to the session daemon representing the
+        *            tracing domain to handle.
+        * @param isRoot
+        *            True if this client should connect to the root session daemon,
+        *            false if it should connect to the user one.
+        */
+       public LttngTcpSessiondClient(ILttngTcpClientListener logAgent, int domainValue, boolean isRoot) {
+               this.logAgent = logAgent;
+               this.domainValue = domainValue;
+               this.isRoot = isRoot;
+       }
+
+       /**
+        * Wait until this client has successfully established a connection to its
+        * target session daemon.
+        *
+        * @param seconds
+        *            A timeout in seconds after which this method will return
+        *            anyway.
+        * @return True if the the client actually established the connection, false
+        *         if we returned because the timeout has elapsed or the thread was
+        *         interrupted.
+        */
+       public boolean waitForConnection(int seconds) {
+               try {
+                       return registrationLatch.await(seconds, TimeUnit.SECONDS);
+               } catch (InterruptedException e) {
+                       return false;
+               }
+       }
+
+       @Override
+       public void run() {
+               for (;;) {
+                       if (this.quit) {
+                               break;
+                       }
+
+                       try {
+
+                               /*
+                                * Connect to the session daemon before anything else.
+                                */
+                               log("Connecting to sessiond");
+                               connectToSessiond();
+
+                               /*
+                                * Register to the session daemon as the Java component of the
+                                * UST application.
+                                */
+                               log("Registering to sessiond");
+                               registerToSessiond();
+
+                               /*
+                                * Block on socket receive and wait for command from the
+                                * session daemon. This will return if and only if there is a
+                                * fatal error or the socket closes.
+                                */
+                               log("Waiting on sessiond commands...");
+                               handleSessiondCmd();
+                       } catch (UnknownHostException uhe) {
+                               uhe.printStackTrace();
+                               /*
+                                * Terminate agent thread.
+                                */
+                               close();
+                       } catch (IOException ioe) {
+                               /*
+                                * I/O exception may have been triggered by a session daemon
+                                * closing the socket. Close our own socket and
+                                * retry connecting after a delay.
+                                */
+                               try {
+                                       if (this.sessiondSock != null) {
+                                               this.sessiondSock.close();
+                                       }
+                                       Thread.sleep(3000);
+                               } catch (InterruptedException e) {
+                                       /*
+                                        * Retry immediately if sleep is interrupted.
+                                        */
+                               } catch (IOException closeioe) {
+                                       closeioe.printStackTrace();
+                                       /*
+                                        * Terminate agent thread.
+                                        */
+                                       close();
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Dispose this client and close any socket connection it may hold.
+        */
+       public void close() {
+               log("Closing client");
+               this.quit = true;
+
+               try {
+                       if (this.sessiondSock != null) {
+                               this.sessiondSock.close();
+                       }
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       private void connectToSessiond() throws IOException {
+               int rootPort = getPortFromFile(ROOT_PORT_FILE);
+               int userPort = getPortFromFile(getHomePath() + USER_PORT_FILE);
+
+               /*
+                * Check for the edge case of both files existing but pointing to the
+                * same port. In this case, let the root client handle it.
+                */
+               if ((rootPort != 0) && (rootPort == userPort) && (!isRoot)) {
+                       log("User and root config files both point to port " + rootPort +
+                                       ". Letting the root client handle it.");
+                       throw new IOException();
+               }
+
+               int portToUse = (isRoot ? rootPort : userPort);
+
+               if (portToUse == 0) {
+                       /* No session daemon available. Stop and retry later. */
+                       throw new IOException();
+               }
+
+               this.sessiondSock = new Socket(SESSION_HOST, portToUse);
+               this.inFromSessiond = new DataInputStream(sessiondSock.getInputStream());
+               this.outToSessiond = new DataOutputStream(sessiondSock.getOutputStream());
+       }
+
+       private static String getHomePath() {
+               /*
+                * The environment variable LTTNG_HOME overrides HOME if
+                * defined.
+                */
+               String homePath = System.getenv("LTTNG_HOME");
+
+               if (homePath == null) {
+                       homePath = System.getProperty("user.home");
+               }
+               return homePath;
+       }
+
+       /**
+        * Read port number from file created by the session daemon.
+        *
+        * @return port value if found else 0.
+        */
+       private static int getPortFromFile(String path) throws IOException {
+               BufferedReader br = null;
+
+               try {
+                       br = new BufferedReader(new InputStreamReader(new FileInputStream(path), PORT_FILE_ENCODING));
+                       String line = br.readLine();
+                       if (line == null) {
+                               /* File exists but is empty. */
+                               return 0;
+                       }
+
+                       int port = Integer.parseInt(line, 10);
+                       if (port < 0 || port > 65535) {
+                               /* Invalid value. Ignore. */
+                               port = 0;
+                       }
+                       return port;
+
+               } catch (NumberFormatException e) {
+                       /* File contained something that was not a number. */
+                       return 0;
+               } catch (FileNotFoundException e) {
+                       /* No port available. */
+                       return 0;
+               } finally {
+                       if (br != null) {
+                               br.close();
+                       }
+               }
+       }
+
+       private void registerToSessiond() throws IOException {
+               byte data[] = new byte[16];
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
+
+               buf.putInt(domainValue);
+               buf.putInt(Integer.parseInt(pid));
+               buf.putInt(PROTOCOL_MAJOR_VERSION);
+               buf.putInt(PROTOCOL_MINOR_VERSION);
+               this.outToSessiond.write(data, 0, data.length);
+               this.outToSessiond.flush();
+       }
+
+       /**
+        * Handle session command from the session daemon.
+        */
+       private void handleSessiondCmd() throws IOException {
+               /* Data read from the socket */
+               byte inputData[] = null;
+               /* Reply data written to the socket, sent to the sessiond */
+               LttngAgentResponse response;
+
+               while (true) {
+                       /* Get header from session daemon. */
+                       SessiondCommandHeader cmdHeader = recvHeader();
+
+                       if (cmdHeader.getDataSize() > 0) {
+                               inputData = recvPayload(cmdHeader);
+                       }
+
+                       switch (cmdHeader.getCommandType()) {
+                       case CMD_REG_DONE:
+                       {
+                               /*
+                                * Countdown the registration latch, meaning registration is
+                                * done and we can proceed to continue tracing.
+                                */
+                               registrationLatch.countDown();
+                               /*
+                                * We don't send any reply to the registration done command.
+                                * This just marks the end of the initial session setup.
+                                */
+                               log("Registration done");
+                               continue;
+                       }
+                       case CMD_LIST:
+                       {
+                               SessiondCommand listLoggerCmd = new SessiondListLoggersCommand();
+                               response = listLoggerCmd.execute(logAgent);
+                               log("Received list loggers command");
+                               break;
+                       }
+                       case CMD_EVENT_ENABLE:
+                       {
+                               if (inputData == null) {
+                                       /* Invalid command */
+                                       response = LttngAgentResponse.FAILURE_RESPONSE;
+                                       break;
+                               }
+                               SessiondCommand enableEventCmd = new SessiondEnableEventCommand(inputData);
+                               response = enableEventCmd.execute(logAgent);
+                               log("Received enable event command: " + enableEventCmd.toString());
+                               break;
+                       }
+                       case CMD_EVENT_DISABLE:
+                       {
+                               if (inputData == null) {
+                                       /* Invalid command */
+                                       response = LttngAgentResponse.FAILURE_RESPONSE;
+                                       break;
+                               }
+                               SessiondCommand disableEventCmd = new SessiondDisableEventCommand(inputData);
+                               response = disableEventCmd.execute(logAgent);
+                               log("Received disable event command: " + disableEventCmd.toString());
+                               break;
+                       }
+                       case CMD_APP_CTX_ENABLE:
+                       {
+                               if (inputData == null) {
+                                       /* This commands expects a payload, invalid command */
+                                       response = LttngAgentResponse.FAILURE_RESPONSE;
+                                       break;
+                               }
+                               SessiondCommand enableAppCtxCmd = new SessiondEnableAppContextCommand(inputData);
+                               response = enableAppCtxCmd.execute(logAgent);
+                               log("Received enable app-context command");
+                               break;
+                       }
+                       case CMD_APP_CTX_DISABLE:
+                       {
+                               if (inputData == null) {
+                                       /* This commands expects a payload, invalid command */
+                                       response = LttngAgentResponse.FAILURE_RESPONSE;
+                                       break;
+                               }
+                               SessiondCommand disableAppCtxCmd = new SessiondDisableAppContextCommand(inputData);
+                               response = disableAppCtxCmd.execute(logAgent);
+                               log("Received disable app-context command");
+                               break;
+                       }
+                       default:
+                       {
+                               /* Unknown command, send empty reply */
+                               response = null;
+                               log("Received unknown command, ignoring");
+                               break;
+                       }
+                       }
+
+                       /* Send response to the session daemon. */
+                       byte[] responseData;
+                       if (response == null) {
+                               responseData = new byte[4];
+                               ByteBuffer buf = ByteBuffer.wrap(responseData);
+                               buf.order(ByteOrder.BIG_ENDIAN);
+                       } else {
+                               log("Sending response: " + response.toString());
+                               responseData = response.getBytes();
+                       }
+                       this.outToSessiond.write(responseData, 0, responseData.length);
+                       this.outToSessiond.flush();
+               }
+       }
+
+       /**
+        * Receive header data from the session daemon using the LTTng command
+        * static buffer of the right size.
+        */
+       private SessiondCommandHeader recvHeader() throws IOException {
+               byte data[] = new byte[SessiondCommandHeader.HEADER_SIZE];
+               int bytesLeft = data.length;
+               int bytesOffset = 0;
+
+               while (bytesLeft > 0) {
+                       int bytesRead = this.inFromSessiond.read(data, bytesOffset, bytesLeft);
+
+                       if (bytesRead < 0) {
+                               throw new IOException();
+                       }
+                       bytesLeft -= bytesRead;
+                       bytesOffset += bytesRead;
+               }
+               return new SessiondCommandHeader(data);
+       }
+
+       /**
+        * Receive payload from the session daemon. This MUST be done after a
+        * recvHeader() so the header value of a command are known.
+        *
+        * The caller SHOULD use isPayload() before which returns true if a payload
+        * is expected after the header.
+        */
+       private byte[] recvPayload(SessiondCommandHeader headerCmd) throws IOException {
+               byte payload[] = new byte[(int) headerCmd.getDataSize()];
+               int bytesLeft = payload.length;
+               int bytesOffset = 0;
+
+               /* Failsafe check so we don't waste our time reading 0 bytes. */
+               if (bytesLeft == 0) {
+                       return null;
+               }
+
+               while (bytesLeft > 0) {
+                       int bytesRead = inFromSessiond.read(payload, bytesOffset, bytesLeft);
+
+                       if (bytesRead < 0) {
+                               throw new IOException();
+                       }
+                       bytesLeft -= bytesRead;
+                       bytesOffset += bytesRead;
+               }
+               return payload;
+       }
+
+       /**
+        * Wrapper for this class's logging, adds the connection's characteristics
+        * to help differentiate between multiple TCP clients.
+        */
+       private void log(String message) {
+               LttngUstAgentLogger.log(getClass(),
+                               "(root=" + isRoot + ", domain=" + domainValue + ") " + message);
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java
new file mode 100644 (file)
index 0000000..27aba23
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015-2016 EfficiOS Inc.
+ * Copyright (C) 2015-2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * Base class to represent all commands sent from the session daemon to the Java
+ * agent. The agent is then expected to execute the command and provide a
+ * response.
+ *
+ * @author Alexandre Montplaisir
+ */
+abstract class SessiondCommand {
+
+       /**
+        * Encoding that should be used for the strings in the sessiond agent
+        * protocol on the socket.
+        */
+       protected static final Charset SESSIOND_PROTOCOL_CHARSET = Charset.forName("UTF-8");
+
+       enum CommandType {
+               /** List logger(s). */
+               CMD_LIST(1),
+               /** Enable logger by name. */
+               CMD_EVENT_ENABLE(2),
+               /** Disable logger by name. */
+               CMD_EVENT_DISABLE(3),
+               /** Registration done */
+               CMD_REG_DONE(4),
+               /** Enable application context */
+               CMD_APP_CTX_ENABLE(5),
+               /** Disable application context */
+               CMD_APP_CTX_DISABLE(6);
+
+               private int code;
+
+               private CommandType(int c) {
+                       code = c;
+               }
+
+               public int getCommandType() {
+                       return code;
+               }
+       }
+
+       /**
+        * Execute the command handler's action on the specified tracing agent.
+        *
+        * @param agent
+        *            The agent on which to execute the command
+        * @return If the command completed successfully or not
+        */
+       public abstract LttngAgentResponse execute(ILttngTcpClientListener agent);
+
+       /**
+        * Utility method to read agent-protocol strings passed on the socket. The
+        * buffer will contain a 32-bit integer representing the length, immediately
+        * followed by the string itself.
+        *
+        * @param buffer
+        *            The ByteBuffer from which to read. It should already be setup
+        *            and positioned where the read should begin.
+        * @return The string that was read, or <code>null</code> if it was badly
+        *         formatted.
+        */
+       protected static String readNextString(ByteBuffer buffer) {
+               int nbBytes = buffer.getInt();
+               if (nbBytes < 0) {
+                       /* The string length should be positive */
+                       return null;
+               }
+               if (nbBytes == 0) {
+                       /* The string is explicitly an empty string */
+                       return "";
+               }
+
+               byte[] stringBytes = new byte[nbBytes];
+               buffer.get(stringBytes);
+               return new String(stringBytes, SESSIOND_PROTOCOL_CHARSET).trim();
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java
new file mode 100644 (file)
index 0000000..845109d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import org.lttng.ust.agent.client.SessiondCommand.CommandType;
+
+/**
+ * Header of session daemon commands.
+ *
+ * @author Alexandre Montplaisir
+ * @author David Goulet
+ */
+class SessiondCommandHeader {
+
+       /** ABI size of command header. */
+       public static final int HEADER_SIZE = 16;
+
+       /** Payload size in bytes following this header. */
+       private final long dataSize;
+
+       /** Command type. */
+       private final CommandType cmd;
+
+       public SessiondCommandHeader(byte[] data) {
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               buf.order(ByteOrder.BIG_ENDIAN);
+
+               dataSize = buf.getLong();
+               cmd = CommandType.values()[buf.getInt() - 1];
+               buf.getInt(); // command version, currently unused
+       }
+
+       public long getDataSize() {
+               return dataSize;
+       }
+
+       public CommandType getCommandType() {
+               return cmd;
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableAppContextCommand.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableAppContextCommand.java
new file mode 100644 (file)
index 0000000..4ac991a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Session daemon command indicating to the Java agent that an
+ * application-specific context was disabled in the tracing session.
+ *
+ * @author Alexandre Montplaisir
+ */
+class SessiondDisableAppContextCommand extends SessiondCommand {
+
+       private final String retrieverName;
+       private final String contextName;
+
+       private final boolean commandIsValid;
+
+       public SessiondDisableAppContextCommand(byte[] data) {
+               if (data == null) {
+                       throw new IllegalArgumentException();
+               }
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               buf.order(ByteOrder.BIG_ENDIAN);
+
+               /*
+                * The buffer contains the retriever name first, followed by the
+                * context's name.
+                */
+               retrieverName = readNextString(buf);
+               contextName = readNextString(buf);
+
+               /* If any of these strings were null then the command was invalid */
+               commandIsValid = ((retrieverName != null) && (contextName != null));
+       }
+
+       @Override
+       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
+               if (!commandIsValid) {
+                       return LttngAgentResponse.FAILURE_RESPONSE;
+               }
+
+               boolean success = agent.appContextDisabled(retrieverName, contextName);
+               return (success ? LttngAgentResponse.SUCESS_RESPONSE : DISABLE_APP_CONTEXT_FAILURE_RESPONSE);
+       }
+
+       /**
+        * Response sent when the disable-context command asks to disable an
+        * unknown context name.
+        */
+       private static final LttngAgentResponse DISABLE_APP_CONTEXT_FAILURE_RESPONSE = new LttngAgentResponse() {
+               @Override
+               public ReturnCode getReturnCode() {
+                       /* Same return code used for unknown event/logger names */
+                       return ReturnCode.CODE_UNKNOWN_LOGGER_NAME;
+               }
+       };
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java
new file mode 100644 (file)
index 0000000..ff8eff3
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Session daemon command indicating to the Java agent that some events were
+ * disabled in the tracing session.
+ *
+ * @author Alexandre Montplaisir
+ * @author David Goulet
+ */
+class SessiondDisableEventCommand extends SessiondCommand {
+
+       /**
+        * Response sent when the disable-event command asks to disable an
+        * unknown event.
+        */
+       private static final LttngAgentResponse DISABLE_EVENT_FAILURE_RESPONSE = new LttngAgentResponse() {
+               @Override
+               public ReturnCode getReturnCode() {
+                       return ReturnCode.CODE_UNKNOWN_LOGGER_NAME;
+               }
+       };
+
+       /** Event name to disable from the tracing session */
+       private final String eventName;
+
+       public SessiondDisableEventCommand(byte[] data) {
+               if (data == null) {
+                       throw new IllegalArgumentException();
+               }
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               buf.order(ByteOrder.BIG_ENDIAN);
+               eventName = new String(data, SESSIOND_PROTOCOL_CHARSET).trim();
+       }
+
+       @Override
+       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
+               boolean success = agent.eventDisabled(this.eventName);
+               return (success ? LttngAgentResponse.SUCESS_RESPONSE : DISABLE_EVENT_FAILURE_RESPONSE);
+       }
+
+       @Override
+       public String toString() {
+               return "SessiondDisableEventCommand["
+                               + "eventName=" + eventName
+                               +"]";
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableAppContextCommand.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableAppContextCommand.java
new file mode 100644 (file)
index 0000000..d0be8cf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Session daemon command indicating to the Java agent that an
+ * application-specific context was enabled in the tracing session.
+ *
+ * @author Alexandre Montplaisir
+ */
+class SessiondEnableAppContextCommand extends SessiondCommand {
+
+       private final String retrieverName;
+       private final String contextName;
+
+       private final boolean commandIsValid;
+
+       public SessiondEnableAppContextCommand(byte[] data) {
+               if (data == null) {
+                       throw new IllegalArgumentException();
+               }
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               buf.order(ByteOrder.BIG_ENDIAN);
+
+               /*
+                * The buffer contains the retriever name first, followed by the
+                * context's name.
+                */
+               retrieverName = readNextString(buf);
+               contextName = readNextString(buf);
+
+               /* If any of these strings were null then the command was invalid */
+               commandIsValid = ((retrieverName != null) && (contextName != null));
+       }
+
+       @Override
+       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
+               if (!commandIsValid) {
+                       return LttngAgentResponse.FAILURE_RESPONSE;
+               }
+
+               boolean success = agent.appContextEnabled(retrieverName, contextName);
+               return (success ? LttngAgentResponse.SUCESS_RESPONSE : LttngAgentResponse.FAILURE_RESPONSE);
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java
new file mode 100644 (file)
index 0000000..35029c9
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import org.lttng.ust.agent.session.EventRule;
+import org.lttng.ust.agent.session.LogLevelSelector;
+
+/**
+ * Session daemon command indicating to the Java agent that some events were
+ * enabled in the tracing session.
+ *
+ * @author Alexandre Montplaisir
+ * @author David Goulet
+ */
+class SessiondEnableEventCommand extends SessiondCommand {
+
+       /** Fixed event name length. Value defined by the lttng agent protocol. */
+       private static final int EVENT_NAME_LENGTH = 256;
+
+       private final boolean commandIsValid;
+
+       /* Parameters of the event rule being enabled */
+       private final String eventName;
+       private final LogLevelSelector logLevelFilter;
+       private final String filterString;
+
+       public SessiondEnableEventCommand(byte[] data) {
+               if (data == null) {
+                       throw new IllegalArgumentException();
+               }
+               ByteBuffer buf = ByteBuffer.wrap(data);
+               buf.order(ByteOrder.BIG_ENDIAN);
+               int logLevel = buf.getInt();
+               int logLevelType = buf.getInt();
+               logLevelFilter = new LogLevelSelector(logLevel, logLevelType);
+
+               /* Read the event name */
+               byte[] eventNameBytes = new byte[EVENT_NAME_LENGTH];
+               buf.get(eventNameBytes);
+               eventName = new String(eventNameBytes, SESSIOND_PROTOCOL_CHARSET).trim();
+
+               /* Read the filter string */
+               filterString = readNextString(buf);
+
+               /* The command was invalid if the string could not be read correctly */
+               commandIsValid = (filterString != null);
+       }
+
+       @Override
+       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
+               if (!commandIsValid) {
+                       return LttngAgentResponse.FAILURE_RESPONSE;
+               }
+
+               EventRule rule = new EventRule(eventName, logLevelFilter, filterString);
+               boolean success = agent.eventEnabled(rule);
+               return (success ? LttngAgentResponse.SUCESS_RESPONSE : LttngAgentResponse.FAILURE_RESPONSE);
+       }
+
+       @Override
+       public String toString() {
+               return "SessiondEnableEventCommand["
+                               + "eventName=" + eventName
+                               + ", logLevel=" + logLevelFilter.toString()
+                               + ", filterString=" + filterString
+                               +"]";
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java
new file mode 100644 (file)
index 0000000..0500055
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.client;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Collection;
+
+/**
+ * Session daemon command asking the Java agent to list its registered loggers,
+ * which corresponds to event names in the tracing session.
+ *
+ * @author Alexandre Montplaisir
+ * @author David Goulet
+ */
+class SessiondListLoggersCommand extends SessiondCommand {
+
+       @Override
+       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
+               final Collection<String> loggerList = agent.listAvailableEvents();
+               return new SessiondListLoggersResponse(loggerList);
+       }
+
+       private static class SessiondListLoggersResponse extends LttngAgentResponse {
+
+               private final static int SIZE = 12;
+
+               private final Collection<String> loggers;
+
+               public SessiondListLoggersResponse(Collection<String> loggers) {
+                       this.loggers = loggers;
+               }
+
+               @Override
+               public ReturnCode getReturnCode() {
+                       /* This command can't really fail */
+                       return ReturnCode.CODE_SUCCESS_CMD;
+               }
+
+               @Override
+               public byte[] getBytes() {
+                       /*
+                        * Compute the data size, which is the number of bytes of each
+                        * encoded string, +1 per string for the \0
+                        */
+                       int dataSize = 0;
+                       for (String logger : loggers) {
+                               dataSize += logger.getBytes(SESSIOND_PROTOCOL_CHARSET).length + 1;
+                       }
+
+                       /* Prepare the buffer */
+                       byte data[] = new byte[SIZE + dataSize];
+                       ByteBuffer buf = ByteBuffer.wrap(data);
+                       buf.order(ByteOrder.BIG_ENDIAN);
+
+                       /* Write the header section of the response */
+                       buf.putInt(getReturnCode().getCode());
+                       buf.putInt(dataSize);
+                       buf.putInt(loggers.size());
+
+                       /* Write the payload */
+                       for (String logger : loggers) {
+                               buf.put(logger.getBytes(SESSIOND_PROTOCOL_CHARSET));
+                               /* NULL terminated byte after the logger name. */
+                               buf.put((byte) 0x0);
+                       }
+                       return data;
+               }
+       }
+
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoManager.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoManager.java
new file mode 100644 (file)
index 0000000..22efe02
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.context;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The singleton manager of {@link IContextInfoRetriever} objects.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class ContextInfoManager {
+
+       private static final String SHARED_LIBRARY_NAME = "lttng-ust-context-jni";
+
+       private static final Pattern VALID_CONTEXT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_\\.]+$");
+
+       private static ContextInfoManager instance;
+
+       private final Map<String, IContextInfoRetriever> contextInfoRetrievers = new ConcurrentHashMap<String, IContextInfoRetriever>();
+       private final Map<String, Long> contextInforRetrieverRefs = new HashMap<String, Long>();
+
+       /**
+        * Lock used to keep the two maps above in sync when retrievers are
+        * registered or unregistered.
+        */
+       private final Object retrieverLock = new Object();
+
+       /** Singleton class, constructor should not be accessed directly */
+       private ContextInfoManager() {
+       }
+
+       /**
+        * Get the singleton instance.
+        *
+        * <p>
+        * Usage of this class requires the "liblttng-ust-context-jni.so" native
+        * library to be present on the system and available (passing
+        * -Djava.library.path=path to the JVM may be needed).
+        * </p>
+        *
+        * @return The singleton instance
+        * @throws IOException
+        *             If the shared library cannot be found.
+        * @throws SecurityException
+        *             We will forward any SecurityExcepion that may be thrown when
+        *             trying to load the JNI library.
+        */
+       public static synchronized ContextInfoManager getInstance() throws IOException, SecurityException {
+               if (instance == null) {
+                       try {
+                               System.loadLibrary(SHARED_LIBRARY_NAME);
+                       } catch (UnsatisfiedLinkError e) {
+                               throw new IOException(e);
+                       }
+                       instance = new ContextInfoManager();
+               }
+               return instance;
+       }
+
+       /**
+        * Register a new context info retriever.
+        *
+        * <p>
+        * Each context info retriever is registered with a given "retriever name",
+        * which specifies the namespace of the context elements. This name is
+        * specified separately from the retriever objects, which would allow
+        * register the same retriever under different namespaces for example.
+        * </p>
+        *
+        * <p>
+        * If the method returns false (indicating registration failure), then the
+        * retriever object will *not* be used for context information.
+        * </p>
+        *
+        * @param retrieverName
+        *            The name to register to the context retriever object with.
+        * @param contextInfoRetriever
+        *            The context info retriever to register
+        * @return True if the retriever was successfully registered, false if there
+        *         was an error, for example if a retriever is already registered
+        *         with that name.
+        */
+       public boolean registerContextInfoRetriever(String retrieverName, IContextInfoRetriever contextInfoRetriever) {
+               synchronized (retrieverLock) {
+                       if (!validateRetrieverName(retrieverName)) {
+                               return false;
+                       }
+
+                       if (contextInfoRetrievers.containsKey(retrieverName)) {
+                               /*
+                                * There is already a retriever registered with that name,
+                                * refuse the new registration.
+                                */
+                               return false;
+                       }
+                       /*
+                        * Inform LTTng-UST of the new retriever. The names have to start
+                        * with "$app." on the UST side!
+                        */
+                       long ref = LttngContextApi.registerProvider("$app." + retrieverName);
+                       if (ref == 0) {
+                               return false;
+                       }
+
+                       contextInfoRetrievers.put(retrieverName, contextInfoRetriever);
+                       contextInforRetrieverRefs.put(retrieverName, Long.valueOf(ref));
+
+                       return true;
+               }
+       }
+
+       /**
+        * Unregister a previously added context info retriever.
+        *
+        * This method has no effect if the retriever was not already registered.
+        *
+        * @param retrieverName
+        *            The context info retriever to unregister
+        * @return True if unregistration was successful, false if there was an
+        *         error
+        */
+       public boolean unregisterContextInfoRetriever(String retrieverName) {
+               synchronized (retrieverLock) {
+                       if (!contextInfoRetrievers.containsKey(retrieverName)) {
+                               /*
+                                * There was no retriever registered with that name.
+                                */
+                               return false;
+                       }
+                       contextInfoRetrievers.remove(retrieverName);
+                       long ref = contextInforRetrieverRefs.remove(retrieverName).longValue();
+
+                       /* Unregister the retriever on the UST side too */
+                       LttngContextApi.unregisterProvider(ref);
+
+                       return true;
+               }
+       }
+
+       /**
+        * Return the context info retriever object registered with the given name.
+        *
+        * @param retrieverName
+        *            The retriever name to look for
+        * @return The corresponding retriever object, or <code>null</code> if there
+        *         was none
+        */
+       public IContextInfoRetriever getContextInfoRetriever(String retrieverName) {
+               /*
+                * Note that this method does not take the retrieverLock, it lets
+                * concurrent threads access the ConcurrentHashMap directly.
+                *
+                * It's fine for a get() to happen during a registration or
+                * unregistration, it's first-come-first-serve.
+                */
+               return contextInfoRetrievers.get(retrieverName);
+       }
+
+       /**
+        * Validate that the given retriever name contains only the allowed
+        * characters, which are alphanumerical characters, period "." and
+        * underscore "_". The name must also not start with a number.
+        */
+       private static boolean validateRetrieverName(String contextName) {
+               if (contextName.isEmpty()) {
+                       return false;
+               }
+
+               /* First character must not be a number */
+               if (Character.isDigit(contextName.charAt(0))) {
+                       return false;
+               }
+
+               /* Validate the other characters of the string */
+               Matcher matcher = VALID_CONTEXT_NAME_PATTERN.matcher(contextName);
+               return matcher.matches();
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoSerializer.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoSerializer.java
new file mode 100644 (file)
index 0000000..ae65060
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.util.Collection;
+import java.util.Map;
+
+import org.lttng.ust.agent.utils.LttngUstAgentLogger;
+
+/**
+ * This class is used to serialize the list of "context info" objects to pass
+ * through JNI.
+ *
+ * The protocol expects two byte array parameters, which are contained here in
+ * the {@link SerializedContexts} inner class.
+ *
+ * The first byte array is called the "entries array", and contains fixed-size
+ * entries, one per context element.
+ *
+ * The second one is the "strings array", it is of variable length and used to
+ * hold the variable-length strings. Each one of these strings is formatted as a
+ * UTF-8 C-string, meaning in will end with a "\0" byte to indicate its end.
+ * Entries in the first array may refer to offsets in the second array to point
+ * to relevant strings.
+ *
+ * The fixed-size entries in the entries array contain the following elements
+ * (size in bytes in parentheses):
+ *
+ * <ul>
+ * <li>The offset in the strings array pointing to the full context name, like
+ * "$app.myprovider:mycontext" (4)</li>
+ * <li>The context value type (1)</li>
+ * <li>The context value itself (8)</li>
+ * </ul>
+ *
+ * The context value type will indicate how many bytes are used for the value.
+ * If the it is of String type, then we use 4 bytes to represent the offset in
+ * the strings array.
+ *
+ * So the total size of each entry is 13 bytes. All unused bytes (for context
+ * values shorter than 8 bytes for example) will be zero'ed.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class ContextInfoSerializer {
+
+       private enum DataType {
+               NULL(0),
+               INTEGER(1),
+               LONG(2),
+               DOUBLE(3),
+               FLOAT(4),
+               BYTE(5),
+               SHORT(6),
+               BOOLEAN(7),
+               STRING(8);
+
+               private final byte value;
+
+               private DataType(int value) {
+                       this.value = (byte) value;
+               }
+
+               public byte getValue() {
+                       return value;
+               }
+       }
+
+       /**
+        * Class used to wrap the two byte arrays returned by
+        * {@link #queryAndSerializeRequestedContexts}.
+        */
+       public static class SerializedContexts {
+
+               private final byte[] contextEntries;
+               private final byte[] contextStrings;
+
+               /**
+                * Constructor
+                *
+                * @param entries
+                *            Arrays for the fixed-size context entries.
+                * @param strings
+                *            Arrays for variable-length strings
+                */
+               public SerializedContexts(byte[] entries, byte[] strings) {
+                       contextEntries = entries;
+                       contextStrings = strings;
+               }
+
+               /**
+                * @return The entries array
+                */
+               public byte[] getEntriesArray() {
+                       return contextEntries;
+               }
+
+               /**
+                * @return The strings array
+                */
+               public byte[] getStringsArray() {
+                       return contextStrings;
+               }
+       }
+
+       private static final String UST_APP_CTX_PREFIX = "$app.";
+       private static final int ENTRY_LENGTH = 13;
+       private static final ByteOrder NATIVE_ORDER = ByteOrder.nativeOrder();
+       private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
+       private static final SerializedContexts EMPTY_CONTEXTS = new SerializedContexts(new byte[0], new byte[0]);
+
+       /**
+        * From the list of requested contexts in the tracing session, look them up
+        * in the {@link ContextInfoManager}, retrieve the available ones, and
+        * serialize them into a byte array.
+        *
+        * @param enabledContexts
+        *            The contexts that are enabled in the tracing session (indexed
+        *            first by retriever name, then by index names). Should come
+        *            from the LTTng Agent.
+        * @return The byte array representing the intersection of the requested and
+        *         available contexts.
+        */
+       public static SerializedContexts queryAndSerializeRequestedContexts(Collection<Map.Entry<String, Map<String, Integer>>> enabledContexts) {
+               if (enabledContexts.isEmpty()) {
+                       /* Early return if there is no requested context information */
+                       return EMPTY_CONTEXTS;
+               }
+
+               ContextInfoManager contextManager;
+               try {
+                       contextManager = ContextInfoManager.getInstance();
+               } catch (IOException e) {
+                       /*
+                        * The JNI library is not available, do not send any context
+                        * information. No retriever could have been defined anyways.
+                        */
+                       return EMPTY_CONTEXTS;
+               }
+
+               /* Compute the total number of contexts (flatten the map) */
+               int totalArraySize = 0;
+               for (Map.Entry<String, Map<String, Integer>> contexts : enabledContexts) {
+                       totalArraySize += contexts.getValue().size() * ENTRY_LENGTH;
+               }
+
+               /* Prepare the ByteBuffer that will generate the "entries" array */
+               ByteBuffer entriesBuffer = ByteBuffer.allocate(totalArraySize);
+               entriesBuffer.order(NATIVE_ORDER);
+               entriesBuffer.clear();
+
+               /* Prepare the streams that will generate the "strings" array */
+               ByteArrayOutputStream stringsBaos = new ByteArrayOutputStream();
+               DataOutputStream stringsDos = new DataOutputStream(stringsBaos);
+
+               try {
+                       for (Map.Entry<String, Map<String, Integer>> entry : enabledContexts) {
+                               String requestedRetrieverName = entry.getKey();
+                               Map<String, Integer> requestedContexts = entry.getValue();
+
+                               IContextInfoRetriever retriever = contextManager.getContextInfoRetriever(requestedRetrieverName);
+
+                               for (String requestedContext : requestedContexts.keySet()) {
+                                       Object contextInfo;
+                                       if (retriever == null) {
+                                               contextInfo = null;
+                                       } else {
+                                               contextInfo = retriever.retrieveContextInfo(requestedContext);
+                                               /*
+                                                * 'contextInfo' can still be null here, which would
+                                                * indicate the retriever does not supply this context.
+                                                * We will still write this information so that the
+                                                * tracer can know about it.
+                                                */
+                                       }
+
+                                       /* Serialize the result to the buffers */
+                                       // FIXME Eventually pass the retriever name only once?
+                                       String fullContextName = (UST_APP_CTX_PREFIX + requestedRetrieverName + ':' + requestedContext);
+                                       byte[] strArray = fullContextName.getBytes(UTF8_CHARSET);
+
+                                       entriesBuffer.putInt(stringsDos.size());
+                                       stringsDos.write(strArray);
+                                       stringsDos.writeChar('\0');
+
+                                       LttngUstAgentLogger.log(ContextInfoSerializer.class,
+                                                       "ContextInfoSerializer: Context to be sent through JNI: " + fullContextName + '=' +
+                                                                       (contextInfo == null ? "null" : contextInfo.toString()));
+
+                                       serializeContextInfo(entriesBuffer, stringsDos, contextInfo);
+                               }
+                       }
+
+                       stringsDos.flush();
+                       stringsBaos.flush();
+
+               } catch (IOException e) {
+                       /*
+                        * Should not happen because we are wrapping a
+                        * ByteArrayOutputStream, which writes to memory
+                        */
+                       e.printStackTrace();
+               }
+
+               byte[] entriesArray = entriesBuffer.array();
+               byte[] stringsArray = stringsBaos.toByteArray();
+               return new SerializedContexts(entriesArray, stringsArray);
+       }
+
+       private static final int CONTEXT_VALUE_LENGTH = 8;
+
+       private static void serializeContextInfo(ByteBuffer entriesBuffer, DataOutputStream stringsDos, Object contextInfo) throws IOException {
+               int remainingBytes;
+               if (contextInfo == null) {
+                       entriesBuffer.put(DataType.NULL.getValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH;
+
+               } else if (contextInfo instanceof Integer) {
+                       entriesBuffer.put(DataType.INTEGER.getValue());
+                       entriesBuffer.putInt(((Integer) contextInfo).intValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 4;
+
+               } else if (contextInfo instanceof Long) {
+                       entriesBuffer.put(DataType.LONG.getValue());
+                       entriesBuffer.putLong(((Long) contextInfo).longValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 8;
+
+               } else if (contextInfo instanceof Double) {
+                       entriesBuffer.put(DataType.DOUBLE.getValue());
+                       entriesBuffer.putDouble(((Double) contextInfo).doubleValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 8;
+
+               } else if (contextInfo instanceof Float) {
+                       entriesBuffer.put(DataType.FLOAT.getValue());
+                       entriesBuffer.putFloat(((Float) contextInfo).floatValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 4;
+
+               } else if (contextInfo instanceof Byte) {
+                       entriesBuffer.put(DataType.BYTE.getValue());
+                       entriesBuffer.put(((Byte) contextInfo).byteValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 1;
+
+               } else if (contextInfo instanceof Short) {
+                       entriesBuffer.put(DataType.SHORT.getValue());
+                       entriesBuffer.putShort(((Short) contextInfo).shortValue());
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 2;
+
+               } else if (contextInfo instanceof Boolean) {
+                       entriesBuffer.put(DataType.BOOLEAN.getValue());
+                       boolean b = ((Boolean) contextInfo).booleanValue();
+                       /* Converted to one byte, write 1 for true, 0 for false */
+                       entriesBuffer.put((byte) (b ? 1 : 0));
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 1;
+
+               } else {
+                       /* Also includes the case of Character. */
+                       /*
+                        * We'll write the object as a string, into the strings array. We
+                        * will write the corresponding offset to the entries array.
+                        */
+                       String str = contextInfo.toString();
+                       byte[] strArray = str.getBytes(UTF8_CHARSET);
+
+                       entriesBuffer.put(DataType.STRING.getValue());
+
+                       entriesBuffer.putInt(stringsDos.size());
+                       stringsDos.write(strArray);
+                       stringsDos.writeChar('\0');
+
+                       remainingBytes = CONTEXT_VALUE_LENGTH - 4;
+               }
+               entriesBuffer.position(entriesBuffer.position() + remainingBytes);
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/IContextInfoRetriever.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/IContextInfoRetriever.java
new file mode 100644 (file)
index 0000000..235a30a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.context;
+
+/**
+ * Context-retrieving object specified by the application to extract
+ * application-specific context information, which can then be passed on to the
+ * Java agents and saved to a trace.
+ *
+ * Retriever objects should be registered to the {@link ContextInfoManager} to
+ * make them available to the LTTng agents.
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface IContextInfoRetriever {
+
+       /**
+        * Retrieve a piece of context information from the application, identified
+        * by a key.
+        *
+        * @param key
+        *            The key identifying the context information
+        * @return The context information.
+        */
+       Object retrieveContextInfo(String key);
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/LttngContextApi.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/LttngContextApi.java
new file mode 100644 (file)
index 0000000..a60d80e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.context;
+
+/**
+ * Virtual class containing the Java side of the LTTng-UST context provider
+ * registering/unregistering methods.
+ *
+ * @author Alexandre Montplaisir
+ */
+final class LttngContextApi {
+
+       private LttngContextApi() {}
+
+       /**
+        * Register a context provider to UST.
+        *
+        * The callbacks are the same for all providers, and are defined in the .c
+        * file. The only needed information is the retriever (which is called
+        * "provider" from UST'S point of view) name.
+        *
+        * @param provider_name
+        *            The name of the provider
+        * @return The pointer to the created provider object. It's useless in the
+        *         Java space, but will be needed for
+        *         {@link #unregisterProvider(long)}.
+        */
+       static native long registerProvider(String provider_name);
+
+       /**
+        * Unregister a previously-registered context provider from UST.
+        *
+        * @param provider_ref
+        *            The pointer to the provider object, obtained from
+        *            {@link #registerProvider}
+        */
+       static native void unregisterProvider(long provider_ref);
+}
+
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/FilterChangeNotifier.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/FilterChangeNotifier.java
new file mode 100644 (file)
index 0000000..e1c96e1
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.filter;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.lttng.ust.agent.session.EventRule;
+
+/**
+ * Singleton class managing the filter notifications.
+ *
+ * Applications can register a {@link IFilterChangeListener} to be notified when
+ * event filtering rules change in the tracing sessions.
+ *
+ * @author Alexandre Montplaisir
+ */
+public final class FilterChangeNotifier {
+
+       /** Lazy-loaded singleton instance object */
+       private static FilterChangeNotifier instance = null;
+
+       private final Map<EventRule, Integer> enabledEventRules = new HashMap<EventRule, Integer>();
+       private final Collection<IFilterChangeListener> registeredListeners = new LinkedList<IFilterChangeListener>();
+
+
+       /**
+        * Private constructor, singleton class should not be instantiated directly.
+        */
+       private FilterChangeNotifier() {
+       }
+
+       /**
+        * Get the singleton instance, initializing it if needed.
+        *
+        * @return The singleton instance
+        */
+       public static synchronized FilterChangeNotifier getInstance() {
+               if (instance == null) {
+                       instance = new FilterChangeNotifier();
+               }
+               return instance;
+       }
+
+       /**
+        * Notify the filter manager that a new rule was enabled in a tracing
+        * session ("lttng enable-event ...")
+        *
+        * This is meant to be called by the LTTng Agent only. External Java
+        * applications should not call this.
+        *
+        * @param rule
+        *            The rule that was added
+        */
+       public synchronized void addEventRule(EventRule rule) {
+               Integer count = enabledEventRules.get(rule);
+               if (count == null) {
+                       /*
+                        * This is the first instance of this rule being enabled. Add it to
+                        * the map and send notifications to the registered notifiers.
+                        */
+                       enabledEventRules.put(rule, Integer.valueOf(1));
+                       notifyForAddedRule(rule);
+                       return;
+               }
+               if (count.intValue() <= 0) {
+                       /* It should not have been in the map! */
+                       throw new IllegalStateException();
+               }
+               /*
+                * This exact event rule was already enabled, just increment its
+                * refcount without sending notifications
+                */
+               enabledEventRules.put(rule, Integer.valueOf(count.intValue() + 1));
+       }
+
+       /**
+        * Notify the filter manager that an event name was disabled in the tracing
+        * sessions ("lttng disable-event ...").
+        *
+        * The "disable-event" only specifies an event name. This means all the
+        * rules containing this event name are to be disabled.
+        *
+        * This is meant to be called by the LTTng Agent only. External Java
+        * applications should not call this.
+        *
+        * @param eventName
+        *            The event name to disable
+        */
+       public synchronized void removeEventRules(String eventName) {
+               List<EventRule> rulesToRemove = new LinkedList<EventRule>();
+
+               for (EventRule eventRule : enabledEventRules.keySet()) {
+                       if (eventRule.getEventName().equals(eventName)) {
+                               rulesToRemove.add(eventRule);
+                       }
+               }
+               /*
+                * We cannot modify the map while iterating on it. We have to do the
+                * removal separately from the iteration above.
+                */
+               for (EventRule rule : rulesToRemove) {
+                       removeEventRule(rule);
+               }
+       }
+
+       private synchronized void removeEventRule(EventRule eventRule) {
+               Integer count = enabledEventRules.get(eventRule);
+               if (count == null || count.intValue() <= 0) {
+                       /*
+                        * We were asked us to disable an event rule that was not enabled
+                        * previously. Command error?
+                        */
+                       throw new IllegalStateException();
+               }
+               if (count.intValue() == 1) {
+                       /*
+                        * This is the last instance of this event rule being disabled,
+                        * remove it from the map and send notifications of this rule being
+                        * gone.
+                        */
+                       enabledEventRules.remove(eventRule);
+                       notifyForRemovedRule(eventRule);
+                       return;
+               }
+               /*
+                * Other sessions/daemons are still looking for this event rule, simply
+                * decrement its refcount, and do not send notifications.
+                */
+               enabledEventRules.put(eventRule, Integer.valueOf(count.intValue() - 1));
+
+       }
+
+       /**
+        * Register a new listener to the manager.
+        *
+        * @param listener
+        *            The listener to add
+        */
+       public synchronized void registerListener(IFilterChangeListener listener) {
+               registeredListeners.add(listener);
+
+               /* Send the current rules to the new listener ("statedump") */
+               for (EventRule rule : enabledEventRules.keySet()) {
+                       listener.eventRuleAdded(rule);
+               }
+       }
+
+       /**
+        * Unregister a listener from the manager.
+        *
+        * @param listener
+        *            The listener to remove
+        */
+       public synchronized void unregisterListener(IFilterChangeListener listener) {
+               registeredListeners.remove(listener);
+       }
+
+       private void notifyForAddedRule(final EventRule rule) {
+               for (IFilterChangeListener notifier : registeredListeners) {
+                       notifier.eventRuleAdded(rule);
+               }
+       }
+
+       private void notifyForRemovedRule(final EventRule rule) {
+               for (IFilterChangeListener notifier : registeredListeners) {
+                       notifier.eventRuleRemoved(rule);
+               }
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/IFilterChangeListener.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/IFilterChangeListener.java
new file mode 100644 (file)
index 0000000..e222b22
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.filter;
+
+import org.lttng.ust.agent.session.EventRule;
+
+/**
+ * Filter notification listener interface.
+ * <p>
+ * Applications wanting to be notified of event filtering rule changes should
+ * implement this interface, then register their listener using
+ * {@link FilterChangeNotifier#registerListener}.
+ * </p>
+ * <p>
+ * The callbacks defined in this interface will be called whenever an event rule
+ * is added or removed. The manager will take care of the reference-counting in
+ * case multiple tracing sessions enable the exact same rules. For example, the
+ * {@link #eventRuleRemoved} callback is only called when there are no more
+ * session interested into it.
+ * </p>
+ * <p>
+ * Do not forget to unregister the listener after use, using
+ * {@link FilterChangeNotifier#unregisterListener}. If you do not, or if
+ * you use an anonymous listener for example, these will remain attached until
+ * the complete shutdown of the application.
+ * </p>
+ * <p>
+ * Only one thread is used to dispatch notifications, sequentially. This means
+ * that if a callback hangs it will prevent other listeners from receiving
+ * notifications. Please take care of not blocking inside the listener
+ * callbacks, and use separate threads for potentially long or blocking
+ * operations.
+ * </p>
+ *
+ * @author Alexandre Montplaisir
+ */
+public interface IFilterChangeListener {
+
+       /**
+        * Notification that a new event rule is now enabled in the tracing
+        * sessions.
+        *
+        * @param rule
+        *            The event rule that was enabled
+        */
+       void eventRuleAdded(EventRule rule);
+
+       /**
+        * Notification that an existing event rule is now disabled in the tracing
+        * sessions.
+        *
+        * @param rule
+        *            The event rule that was disabled
+        */
+       void eventRuleRemoved(EventRule rule);
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/EventRule.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/EventRule.java
new file mode 100644 (file)
index 0000000..dcf05a7
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.session;
+
+/**
+ * Event filtering rule present in a tracing session.
+ *
+ * It typically comes from a "lttng enable-event" command, and contains a
+ * domain, event name, log level and filter string.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class EventRule {
+
+       private final String eventName;
+       private final LogLevelSelector logLevelSelector;
+       private final String filterString;
+
+       /**
+        * Constructor.
+        *
+        * @param eventName
+        *            The name of the tracepoint
+        * @param logLevelSelector
+        *            The log level of the event rule
+        * @param filterString
+        *            The filtering string. May be null if there is no extra filter.
+        */
+       public EventRule(String eventName, LogLevelSelector logLevelSelector, String filterString) {
+               this.eventName = eventName;
+               this.logLevelSelector = logLevelSelector;
+               this.filterString = filterString;
+       }
+
+       /**
+        * Get the event name of this rule.
+        *
+        * @return The event name
+        */
+       public String getEventName() {
+               return eventName;
+       }
+
+       /**
+        * Get the log level filter configuration of the rule.
+        *
+        * @return The log level selector
+        */
+       public LogLevelSelector getLogLevelSelector() {
+               return logLevelSelector;
+       }
+
+       /**
+        * Get the filter string associated with this rule.
+        *
+        * @return The filter string, may be null for no filter string.
+        */
+       public String getFilterString() {
+               return filterString;
+       }
+
+       // ------------------------------------------------------------------------
+       // Methods from Object
+       // ------------------------------------------------------------------------
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((eventName == null) ? 0 : eventName.hashCode());
+               result = prime * result + ((filterString == null) ? 0 : filterString.hashCode());
+               result = prime * result + ((logLevelSelector == null) ? 0 : logLevelSelector.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj) {
+                       return true;
+               }
+               if (obj == null) {
+                       return false;
+               }
+               if (getClass() != obj.getClass()) {
+                       return false;
+               }
+               EventRule other = (EventRule) obj;
+
+               if (eventName == null) {
+                       if (other.eventName != null) {
+                               return false;
+                       }
+               } else if (!eventName.equals(other.eventName)) {
+                       return false;
+               }
+               /* else, continue */
+
+               if (filterString == null) {
+                       if (other.filterString != null) {
+                               return false;
+                       }
+               } else if (!filterString.equals(other.filterString)) {
+                       return false;
+               }
+               /* else, continue */
+
+               if (logLevelSelector == null) {
+                       if (other.logLevelSelector != null) {
+                               return false;
+                       }
+               } else if (!logLevelSelector.equals(other.logLevelSelector)) {
+                       return false;
+               }
+               /* else, continue */
+
+               return true;
+       }
+
+       @Override
+       public String toString() {
+               return "Event name = " + getEventName() +
+               ", Log level selector = (" + getLogLevelSelector().toString() + ")" +
+               ", Filter string = " + getFilterString();
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/LogLevelSelector.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/LogLevelSelector.java
new file mode 100644 (file)
index 0000000..c25ec81
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.session;
+
+/**
+ * Log level filtering element, which is part of an {@link EventRule}.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class LogLevelSelector {
+
+       /**
+        * The type of log level filter that is enabled.
+        *
+        * Defined from lttng-tools' include/lttng/event.h.
+        */
+       public enum LogLevelType {
+               /**
+                * All log levels are enabled. This overrides the value of
+                * {@link LogLevelSelector#getLogLevel}.
+                */
+               LTTNG_EVENT_LOGLEVEL_ALL(0),
+
+               /** This log level along with all log levels of higher severity are enabled. */
+               LTTNG_EVENT_LOGLEVEL_RANGE(1),
+
+               /** Only this exact log level is enabled. */
+               LTTNG_EVENT_LOGLEVEL_SINGLE(2);
+
+               private final int value;
+
+               private LogLevelType(int value) {
+                       this.value = value;
+               }
+
+               /**
+                * Get the numerical (int) value representing this log level type in the
+                * communication protocol.
+                *
+                * @return The int value
+                */
+               public int getValue() {
+                       return value;
+               }
+
+               static LogLevelType fromValue(int val) {
+                       switch (val) {
+                       case 0:
+                               return LTTNG_EVENT_LOGLEVEL_ALL;
+                       case 1:
+                               return LTTNG_EVENT_LOGLEVEL_RANGE;
+                       case 2:
+                               return LTTNG_EVENT_LOGLEVEL_SINGLE;
+                       default:
+                               throw new IllegalArgumentException();
+                       }
+               }
+       }
+
+       private final int logLevel;
+       private final LogLevelType logLevelType;
+
+       /**
+        * Constructor using numerical values straight from the communication
+        * protocol.
+        *
+        * @param logLevel
+        *            The numerical value of the log level. The exact value depends
+        *            on the tracing domain, see include/lttng/event.h in the
+        *            lttng-tools tree for the complete enumeration.
+        * @param logLevelType
+        *            The numerical value of the log level type. It will be
+        *            converted to a {@link LogLevelType} by this constructor.
+        * @throws IllegalArgumentException
+        *             If the 'logLevelType' does not correspond to a valid value.
+        */
+       public LogLevelSelector(int logLevel, int logLevelType) {
+               this.logLevel = logLevel;
+               this.logLevelType = LogLevelType.fromValue(logLevelType);
+       }
+
+       /**
+        * "Manual" constructor, specifying the {@link LogLevelType} directly.
+        *
+        * @param logLevel
+        *            The numerical value of the log level. The exact value depends
+        *            on the tracing domain, see include/lttng/event.h in the
+        *            lttng-tools tree for the complete enumeration.
+        * @param type
+        *            The log level filter type.
+        */
+       public LogLevelSelector(int logLevel, LogLevelType type) {
+               this.logLevel = logLevel;
+               this.logLevelType = type;
+       }
+
+       /**
+        * Get the numerical value of the log level element. Does not apply if
+        * {@link #getLogLevelType} returns
+        * {@link LogLevelType#LTTNG_EVENT_LOGLEVEL_ALL}.
+        *
+        * @return The numerical value of the log level
+        */
+       public int getLogLevel() {
+               return logLevel;
+       }
+
+       /**
+        * Get the log level filter type.
+        *
+        * @return The log level filter type
+        */
+       public LogLevelType getLogLevelType() {
+               return logLevelType;
+       }
+
+       /**
+        * Helper method to determine if an event with the given log level should be
+        * traced when considering this filter.
+        *
+        * For example, if this filter object represents "higher severity than 5",
+        * and the log level passed in parameter is "8", it will return that it
+        * matches (higher value means higher severity).
+        *
+        * @param targetLogLevel
+        *            The log level value of the event to check for
+        * @return Should this event be traced, or not
+        */
+       public boolean matches(int targetLogLevel) {
+               switch (logLevelType) {
+               case LTTNG_EVENT_LOGLEVEL_ALL:
+                       return true;
+               case LTTNG_EVENT_LOGLEVEL_RANGE:
+                       return (targetLogLevel >= logLevel);
+               case LTTNG_EVENT_LOGLEVEL_SINGLE:
+                       return (targetLogLevel == logLevel);
+               default:
+                       throw new IllegalStateException();
+               }
+       }
+
+       // ------------------------------------------------------------------------
+       // Methods from Object
+       // ------------------------------------------------------------------------
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + logLevel;
+               result = prime * result + ((logLevelType == null) ? 0 : logLevelType.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj) {
+                       return true;
+               }
+               if (obj == null) {
+                       return false;
+               }
+               if (getClass() != obj.getClass()) {
+                       return false;
+               }
+               LogLevelSelector other = (LogLevelSelector) obj;
+
+               if (logLevel != other.logLevel) {
+                       return false;
+               }
+               if (logLevelType != other.logLevelType) {
+                       return false;
+               }
+               return true;
+       }
+
+       @Override
+       public String toString() {
+               if (getLogLevelType() == LogLevelType.LTTNG_EVENT_LOGLEVEL_ALL) {
+                       return LogLevelType.LTTNG_EVENT_LOGLEVEL_ALL.toString();
+               }
+               return String.valueOf(getLogLevel()) + ", " + getLogLevelType().toString();
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/utils/LttngUstAgentLogger.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/utils/LttngUstAgentLogger.java
new file mode 100644 (file)
index 0000000..3e78553
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.utils;
+
+/**
+ * Logging infrastructure for the lttng-ust Java agent. It prints log messages
+ * to stderr but only when the environment variable LTTNG_UST_DEBUG is defined.
+ *
+ * @author Alexandre Montplaisir
+ */
+public class LttngUstAgentLogger {
+
+       private static final String ENV_VAR_NAME = "LTTNG_UST_DEBUG";
+       private static final boolean LOGGING_ENABLED = (System.getenv(ENV_VAR_NAME) == null ? false : true);
+
+       /**
+        * Log event. Will be printed to stderr if the environment variable
+        * "LTTNG_UST_DEBUG" is defined.
+        *
+        * @param c
+        *            The class logging the message (should normally be called with
+        *            {@link #getClass()}).
+        * @param message
+        *            The message to print
+        */
+       public static void log(Class<?> c, String message) {
+               if (LOGGING_ENABLED) {
+                       System.err.println(c.getSimpleName() + ": " + message);
+               }
+       }
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile.am b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile.am
new file mode 100644 (file)
index 0000000..91ac203
--- /dev/null
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+JAVAROOT = .
+AM_JAVACFLAGS = -classpath $(CLASSPATH):$(builddir)/../lttng-ust-agent-common/lttng-ust-agent-common.jar
+
+pkgpath = org/lttng/ust/agent/jul
+
+jarfile_version = 1.0.0
+jarfile_manifest = $(srcdir)/Manifest.txt
+jarfile_symlink = lttng-ust-agent-jul.jar
+jarfile = lttng-ust-agent-jul-$(jarfile_version).jar
+
+jardir = $(datadir)/java
+
+juljniout = ../../jni/jul
+
+dist_noinst_JAVA = $(pkgpath)/LttngJulAgent.java \
+                                  $(pkgpath)/LttngJulApi.java \
+                                  $(pkgpath)/LttngLogHandler.java
+
+dist_noinst_DATA = $(jarfile_manifest)
+
+jar_DATA = $(jarfile)
+
+stamp = jul-jni-header.stamp
+classes = $(pkgpath)/*.class
+
+$(jarfile): classnoinst.stamp
+       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
+
+if !HAVE_JAVAH
+# If we don't have javah, assume we are running openjdk >= 10 and use javac
+# to generate the jni header file.
+AM_JAVACFLAGS += -h $(juljniout)
+else
+jul-jni-header.stamp: $(dist_noinst_JAVA)
+       $(JAVAH) -classpath $(CLASSPATH):$(srcdir) -d $(juljniout) $(JAVAHFLAGS) org.lttng.ust.agent.jul.LttngJulApi && \
+       echo "JUL JNI header generated" > jul-jni-header.stamp
+
+all-local: $(stamp)
+endif
+
+install-data-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink)
+
+uninstall-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
+
+CLEANFILES = *.jar \
+       $(pkgpath)/*.class \
+       jul-jni-header.stamp \
+       $(juljniout)/org_lttng_ust_agent_jul_LttngJulApi.h
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Manifest.txt b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/Manifest.txt
new file mode 100644 (file)
index 0000000..4aba360
--- /dev/null
@@ -0,0 +1,8 @@
+Name: org/lttng/ust/agent/jul/
+Specification-Title: LTTng UST Java Agent JUL Integration
+Specification-Version: 1.0.0
+Specification-Vendor: LTTng Project
+Implementation-Title: org.lttng.ust.agent.jul
+Implementation-Version: 1.0.0
+Implementation-Vendor: LTTng Project
+Class-Path: lttng-ust-agent-common.jar
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulAgent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulAgent.java
new file mode 100644 (file)
index 0000000..99c5fde
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.jul;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.logging.Handler;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+import org.lttng.ust.agent.AbstractLttngAgent;
+
+/**
+ * Agent implementation for tracing from JUL loggers.
+ *
+ * @author Alexandre Montplaisir
+ */
+class LttngJulAgent extends AbstractLttngAgent<LttngLogHandler> {
+
+       private static LttngJulAgent instance = null;
+
+       private LttngJulAgent() {
+               super(Domain.JUL);
+       }
+
+       public static synchronized LttngJulAgent getInstance() {
+               if (instance == null) {
+                       instance = new LttngJulAgent();
+               }
+               return instance;
+       }
+
+       @Override
+       public Collection<String> listAvailableEvents() {
+               Set<String> ret = new TreeSet<String>();
+
+               List<String> loggersNames = Collections.list(LogManager.getLogManager().getLoggerNames());
+               for (String name : loggersNames) {
+                       /*
+                        * Skip the root logger. An empty string is not a valid event name
+                        * in LTTng.
+                        */
+                       if (name.equals("") || name.equals("global")) {
+                               continue;
+                       }
+
+                       /*
+                        * Check if that logger has at least one LTTng JUL handler attached.
+                        */
+                       Logger logger = Logger.getLogger(name);
+                       if (hasLttngHandlerAttached(logger)) {
+                               ret.add(name);
+                       }
+               }
+
+               return ret;
+       }
+
+       private static boolean hasLttngHandlerAttached(Logger logger) {
+               for (Handler handler : logger.getHandlers()) {
+                       if (handler instanceof LttngLogHandler) {
+                               return true;
+                       }
+               }
+
+               /*
+                * A parent logger, if any, may be connected to an LTTng handler. In
+                * this case, we will want to include this child logger in the output,
+                * since it will be accessible by LTTng.
+                */
+               Logger parent = logger.getParent();
+               if (parent != null) {
+                       return hasLttngHandlerAttached(parent);
+               }
+
+               /*
+                * We have reached the root logger and have not found any LTTng handler,
+                * this event will not be accessible.
+                */
+               return false;
+       }
+
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulApi.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulApi.java
new file mode 100644 (file)
index 0000000..07b0cde
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.jul;
+
+/**
+ * Virtual class containing the Java side of the LTTng-JUL JNI API methods.
+ *
+ * @author Alexandre Montplaisir
+ */
+final class LttngJulApi {
+
+       private LttngJulApi() {}
+
+       static native void tracepoint(String msg,
+                       String logger_name,
+                       String class_name,
+                       String method_name,
+                       long millis,
+                       int log_level,
+                       int thread_id);
+
+       static native void tracepointWithContext(String msg,
+                       String logger_name,
+                       String class_name,
+                       String method_name,
+                       long millis,
+                       int log_level,
+                       int thread_id,
+                       byte[] contextEntries,
+                       byte[] contextStrings);
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngLogHandler.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngLogHandler.java
new file mode 100644 (file)
index 0000000..42bea9c
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
+ */
+
+package org.lttng.ust.agent.jul;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+
+import org.lttng.ust.agent.ILttngAgent;
+import org.lttng.ust.agent.ILttngHandler;
+import org.lttng.ust.agent.context.ContextInfoSerializer;
+
+/**
+ * LTTng-UST JUL log handler.
+ *
+ * Applications can attach this handler to their
+ * {@link java.util.logging.Logger} to have it generate UST events from logging
+ * events received through the logger.
+ *
+ * It sends its events to UST via the JNI library "liblttng-ust-jul-jni.so".
+ * Make sure this library is available before using this handler.
+ *
+ * @author Alexandre Montplaisir
+ * @author David Goulet
+ */
+public class LttngLogHandler extends Handler implements ILttngHandler {
+
+       private static final String SHARED_OBJECT_NAME = "lttng-ust-jul-jni";
+
+       /**
+        * Dummy Formatter object, so we can use its
+        * {@link Formatter#formatMessage(LogRecord)} method.
+        */
+       private static final Formatter FORMATTER = new Formatter() {
+               @Override
+               public String format(LogRecord record) {
+                       throw new UnsupportedOperationException();
+               }
+       };
+
+       private final ILttngAgent<LttngLogHandler> agent;
+
+       /** Number of events logged (really sent through JNI) by this handler */
+       private final AtomicLong eventCount = new AtomicLong(0);
+
+       /**
+        * Constructor
+        *
+        * @throws IOException
+        *             This handler requires the lttng-ust-jul-jni.so native
+        *             library, through which it will send the trace events. This
+        *             exception is throw is this library cannot be found.
+        * @throws SecurityException
+        *             We will forward any SecurityExcepion that may be thrown when
+        *             trying to load the JNI library.
+        */
+       public LttngLogHandler() throws IOException, SecurityException {
+               super();
+               /* Initialize LTTng UST tracer. */
+               try {
+                       System.loadLibrary(SHARED_OBJECT_NAME); //$NON-NLS-1$
+               } catch (UnsatisfiedLinkError e) {
+                       throw new IOException(e);
+               }
+
+               /** Register to the relevant agent */
+               agent = LttngJulAgent.getInstance();
+               agent.registerHandler(this);
+       }
+
+       @Override
+       public synchronized void close() {
+               agent.unregisterHandler(this);
+       }
+
+       /**
+        * Get the number of events logged by this handler so far. This means the
+        * number of events actually sent through JNI to UST.
+        *
+        * @return The number of events logged so far
+        */
+       @Override
+       public long getEventCount() {
+               return eventCount.get();
+       }
+
+       @Override
+       public void flush() {
+       }
+
+       @Override
+       public void publish(LogRecord record) {
+               /*
+                * Check if the current message should be logged, according to the UST
+                * session settings.
+                */
+               if (!agent.isEventEnabled(record.getLoggerName())) {
+                       return;
+               }
+
+               String formattedMessage = FORMATTER.formatMessage(record);
+
+               /* Retrieve all the requested context information we can find */
+               Collection<Entry<String, Map<String, Integer>>> enabledContexts = agent.getEnabledAppContexts();
+               ContextInfoSerializer.SerializedContexts contextInfo = ContextInfoSerializer.queryAndSerializeRequestedContexts(enabledContexts);
+
+               eventCount.incrementAndGet();
+
+               /*
+                * Specific tracepoint designed for JUL events. The source class of the
+                * caller is used for the event name, the raw message is taken, the
+                * loglevel of the record and the thread ID.
+                */
+               LttngJulApi.tracepointWithContext(formattedMessage,
+                               record.getLoggerName(),
+                               record.getSourceClassName(),
+                               record.getSourceMethodName(),
+                               record.getMillis(),
+                               record.getLevel().intValue(),
+                               record.getThreadID(),
+                               contextInfo.getEntriesArray(),
+                               contextInfo.getStringsArray());
+       }
+
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile.am b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile.am
new file mode 100644 (file)
index 0000000..009f141
--- /dev/null
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+JAVAROOT = .
+AM_JAVACFLAGS = -classpath $(CLASSPATH):$(builddir)/../lttng-ust-agent-common/lttng-ust-agent-common.jar
+
+pkgpath = org/lttng/ust/agent/log4j
+
+jarfile_version = 1.0.0
+jarfile_manifest = $(srcdir)/Manifest.txt
+jarfile_symlink = lttng-ust-agent-log4j.jar
+jarfile = lttng-ust-agent-log4j-$(jarfile_version).jar
+
+jardir = $(datadir)/java
+
+log4jjniout = ../../jni/log4j
+
+dist_noinst_JAVA = $(pkgpath)/LttngLog4jAgent.java \
+                                  $(pkgpath)/LttngLog4jApi.java \
+                                  $(pkgpath)/LttngLogAppender.java
+
+dist_noinst_DATA = $(jarfile_manifest)
+
+jar_DATA = $(jarfile)
+
+stamp = log4j-jni-header.stamp
+classes = $(pkgpath)/*.class
+
+$(jarfile): classnoinst.stamp
+       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
+
+if !HAVE_JAVAH
+# If we don't have javah, assume we are running openjdk >= 10 and use javac
+# to generate the jni header file.
+AM_JAVACFLAGS += -h $(log4jjniout)
+else
+log4j-jni-header.stamp: $(dist_noinst_JAVA)
+       $(JAVAH) -classpath $(CLASSPATH):$(srcdir) -d $(log4jjniout) $(JAVAHFLAGS) org.lttng.ust.agent.log4j.LttngLog4jApi && \
+       echo "Log4j JNI header generated" > log4j-jni-header.stamp
+
+all-local: $(stamp)
+endif
+
+install-data-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink)
+
+uninstall-hook:
+       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
+
+CLEANFILES = *.jar \
+       $(pkgpath)/*.class \
+       log4j-jni-header.stamp \
+       $(log4jjniout)/org_lttng_ust_agent_log4j_LttngLog4jApi.h
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Manifest.txt b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/Manifest.txt
new file mode 100644 (file)
index 0000000..d7b98f4
--- /dev/null
@@ -0,0 +1,8 @@
+Name: org/lttng/ust/agent/log4j/
+Specification-Title: LTTng UST Java Agent Log4J 1.x Integration
+Specification-Version: 1.0.0
+Specification-Vendor: LTTng Project
+Implementation-Title: org.lttng.ust.agent.log4j
+Implementation-Version: 1.0.0
+Implementation-Vendor: LTTng Project
+Class-Path: lttng-ust-agent-common.jar
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jAgent.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jAgent.java
new file mode 100644 (file)
index 0000000..bb5deb3
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.log4j;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.Category;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.lttng.ust.agent.AbstractLttngAgent;
+
+/**
+ * Agent implementation for using the Log4j logger, connecting to a root session
+ * daemon.
+ *
+ * @author Alexandre Montplaisir
+ */
+class LttngLog4jAgent extends AbstractLttngAgent<LttngLogAppender> {
+
+       private static LttngLog4jAgent instance = null;
+
+       private LttngLog4jAgent() {
+               super(Domain.LOG4J);
+       }
+
+       public static synchronized LttngLog4jAgent getInstance() {
+               if (instance == null) {
+                       instance = new LttngLog4jAgent();
+               }
+               return instance;
+       }
+
+       @Override
+       public Collection<String> listAvailableEvents() {
+               Set<String> ret = new TreeSet<String>();
+
+               @SuppressWarnings("unchecked")
+               List<Logger> loggers = Collections.list(LogManager.getCurrentLoggers());
+               for (Logger logger : loggers) {
+                       if (logger == null) {
+                               continue;
+                       }
+
+                       /*
+                        * Check if that logger has at least one LTTng log4j appender
+                        * attached.
+                        */
+                       if (hasLttngAppenderAttached(logger)) {
+                               ret.add(logger.getName());
+                       }
+               }
+
+               return ret;
+       }
+
+       private static boolean hasLttngAppenderAttached(Category logger) {
+               @SuppressWarnings("unchecked")
+               Enumeration<Appender> appenders = logger.getAllAppenders();
+               if (appenders != null) {
+                       for (Appender appender : Collections.list(appenders)) {
+                               if (appender instanceof LttngLogAppender) {
+                                       return true;
+                               }
+                       }
+               }
+
+               /*
+                * A parent logger, if any, may be connected to an LTTng handler. In
+                * this case, we will want to include this child logger in the output,
+                * since it will be accessible by LTTng.
+                */
+               Category parent = logger.getParent();
+               if (parent != null) {
+                       return hasLttngAppenderAttached(parent);
+               }
+
+               /*
+                * We have reached the root logger and have not found any LTTng handler,
+                * this event will not be accessible.
+                */
+               return false;
+       }
+
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jApi.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jApi.java
new file mode 100644 (file)
index 0000000..c3e76ee
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+package org.lttng.ust.agent.log4j;
+
+/**
+ * Virtual class containing the Java side of the LTTng-log4j JNI API methods.
+ *
+ * @author Alexandre Montplaisir
+ */
+final class LttngLog4jApi {
+
+       private LttngLog4jApi() {}
+
+       static native void tracepoint(String msg,
+                       String logger_name,
+                       String class_name,
+                       String method_name,
+                       String file_name,
+                       int line_number,
+                       long timestamp,
+                       int loglevel,
+                       String thread_name);
+
+       static native void tracepointWithContext(String msg,
+                       String logger_name,
+                       String class_name,
+                       String method_name,
+                       String file_name,
+                       int line_number,
+                       long timestamp,
+                       int loglevel,
+                       String thread_name,
+                       byte[] contextEntries,
+                       byte[] contextStrings);
+}
diff --git a/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLogAppender.java b/src/lib/lttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLogAppender.java
new file mode 100644 (file)
index 0000000..c232fb8
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2014 Christian Babeux <christian.babeux@efficios.com>
+ */
+
+package org.lttng.ust.agent.log4j;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.spi.LoggingEvent;
+import org.lttng.ust.agent.ILttngAgent;
+import org.lttng.ust.agent.ILttngHandler;
+import org.lttng.ust.agent.context.ContextInfoSerializer;
+
+/**
+ * LTTng-UST Log4j 1.x log handler.
+ *
+ * Applications can attach this appender to their
+ * {@link org.apache.log4j.Logger} to have it generate UST events from logging
+ * events received through the logger.
+ *
+ * It sends its events to UST via the JNI library "liblttng-ust-log4j-jni.so".
+ * Make sure this library is available before using this appender.
+ *
+ * @author Alexandre Montplaisir
+ * @author Christian Babeux
+ */
+public class LttngLogAppender extends AppenderSkeleton implements ILttngHandler {
+
+       private static final String SHARED_OBJECT_NAME = "lttng-ust-log4j-jni";
+
+       private final AtomicLong eventCount = new AtomicLong(0);
+
+       private final ILttngAgent<LttngLogAppender> agent;
+
+
+       /**
+        * Constructor
+        *
+        * @throws IOException
+        *             This handler requires the lttng-ust-log4j-jni.so native
+        *             library, through which it will send the trace events. This
+        *             exception is throw is this library cannot be found.
+        * @throws SecurityException
+        *             We will forward any SecurityExcepion that may be thrown when
+        *             trying to load the JNI library.
+        */
+       public LttngLogAppender() throws IOException, SecurityException {
+               super();
+               /* Initialize LTTng UST tracer. */
+               try {
+                       System.loadLibrary(SHARED_OBJECT_NAME); // $NON-NLS-1$
+               } catch (UnsatisfiedLinkError e) {
+                       throw new IOException(e);
+               }
+
+               /** Register to the relevant agent */
+               agent = LttngLog4jAgent.getInstance();
+               agent.registerHandler(this);
+       }
+
+       @Override
+       public synchronized void close() {
+               agent.unregisterHandler(this);
+       }
+
+       /**
+        * Get the number of events logged by this handler so far. This means the
+        * number of events actually sent through JNI to UST.
+        *
+        * @return The number of events logged so far
+        */
+       @Override
+       public long getEventCount() {
+               return eventCount.get();
+       }
+
+       @Override
+       public boolean requiresLayout() {
+               return false;
+       }
+
+       @Override
+       protected void append(LoggingEvent event) {
+               /*
+                * Check if the current message should be logged, according to the UST
+                * session settings.
+                */
+               if (!agent.isEventEnabled(event.getLoggerName())) {
+                       return;
+               }
+
+               /*
+                * The line number returned from LocationInformation is a string. At
+                * least try to convert to a proper int.
+                */
+               int line;
+               try {
+                       String lineString = event.getLocationInformation().getLineNumber();
+                       line = Integer.parseInt(lineString);
+               } catch (NumberFormatException n) {
+                       line = -1;
+               }
+
+               /* Retrieve all the requested context information we can find */
+               Collection<Entry<String, Map<String, Integer>>> enabledContexts = agent.getEnabledAppContexts();
+               ContextInfoSerializer.SerializedContexts contextInfo = ContextInfoSerializer.queryAndSerializeRequestedContexts(enabledContexts);
+
+               eventCount.incrementAndGet();
+
+               LttngLog4jApi.tracepointWithContext(event.getRenderedMessage(),
+                               event.getLoggerName(),
+                               event.getLocationInformation().getClassName(),
+                               event.getLocationInformation().getMethodName(),
+                               event.getLocationInformation().getFileName(),
+                               line,
+                               event.getTimeStamp(),
+                               event.getLevel().toInt(),
+                               event.getThreadName(),
+                               contextInfo.getEntriesArray(),
+                               contextInfo.getStringsArray());
+       }
+
+}
diff --git a/src/lib/lttng-ust-java-agent/jni/Makefile.am b/src/lib/lttng-ust-java-agent/jni/Makefile.am
new file mode 100644 (file)
index 0000000..711fd47
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+SUBDIRS = common
+
+if ENABLE_JAVA_AGENT_WITH_JUL
+SUBDIRS += jul
+endif
+
+if ENABLE_JAVA_AGENT_WITH_LOG4J
+SUBDIRS += log4j
+endif
diff --git a/src/lib/lttng-ust-java-agent/jni/common/Makefile.am b/src/lib/lttng-ust-java-agent/jni/common/Makefile.am
new file mode 100644 (file)
index 0000000..c066157
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
+
+lib_LTLIBRARIES = liblttng-ust-context-jni.la
+liblttng_ust_context_jni_la_SOURCES = lttng_ust_context.c lttng_ust_context.h
+
+nodist_liblttng_ust_context_jni_la_SOURCES = org_lttng_ust_agent_context_LttngContextApi.h
+
+liblttng_ust_context_jni_la_LIBADD = -lc \
+       $(top_builddir)/src/liblttng-ust/liblttng-ust.la
diff --git a/src/lib/lttng-ust-java-agent/jni/common/lttng_ust_context.c b/src/lib/lttng-ust-java-agent/jni/common/lttng_ust_context.c
new file mode 100644 (file)
index 0000000..8570b21
--- /dev/null
@@ -0,0 +1,397 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#include "org_lttng_ust_agent_context_LttngContextApi.h"
+
+#include <string.h>
+#include <inttypes.h>
+#include <lttng/ust-events.h>
+#include <lttng/ringbuffer-context.h>
+#include <common/ust-context-provider.h>
+
+#include "common/macros.h"
+#include "lttng_ust_context.h"
+
+enum lttng_ust_jni_type {
+       JNI_TYPE_NULL = 0,
+       JNI_TYPE_INTEGER = 1,
+       JNI_TYPE_LONG = 2,
+       JNI_TYPE_DOUBLE = 3,
+       JNI_TYPE_FLOAT = 4,
+       JNI_TYPE_BYTE = 5,
+       JNI_TYPE_SHORT = 6,
+       JNI_TYPE_BOOLEAN = 7,
+       JNI_TYPE_STRING = 8,
+};
+
+struct lttng_ust_jni_ctx_entry {
+       int32_t context_name_offset;
+       char type;      /* enum lttng_ust_jni_type */
+       union {
+               int32_t _integer;
+               int64_t _long;
+               double _double;
+               float _float;
+               signed char _byte;
+               int16_t _short;
+               signed char _boolean;
+               int32_t _string_offset;
+       } value;
+} __attribute__((packed));
+
+struct lttng_ust_jni_provider {
+       struct lttng_ust_registered_context_provider *reg_provider;
+       char *name;
+       struct lttng_ust_context_provider provider;
+};
+
+/* TLS passing context info from JNI to callbacks. */
+__thread struct lttng_ust_jni_tls lttng_ust_context_info_tls;
+
+static const char *get_ctx_string_at_offset(int32_t offset)
+{
+       signed char *ctx_strings_array = lttng_ust_context_info_tls.ctx_strings;
+
+       if (offset < 0 || offset >= lttng_ust_context_info_tls.ctx_strings_len) {
+               return NULL;
+       }
+       return (const char *) (ctx_strings_array + offset);
+}
+
+static struct lttng_ust_jni_ctx_entry *lookup_ctx_by_name(const char *ctx_name)
+{
+       struct lttng_ust_jni_ctx_entry *ctx_entries_array = lttng_ust_context_info_tls.ctx_entries;
+       int i, len = lttng_ust_context_info_tls.ctx_entries_len / sizeof(struct lttng_ust_jni_ctx_entry);
+
+       for (i = 0; i < len; i++) {
+               int32_t offset = ctx_entries_array[i].context_name_offset;
+               const char *string = get_ctx_string_at_offset(offset);
+
+               if (string && strcmp(string, ctx_name) == 0) {
+                       return &ctx_entries_array[i];
+               }
+       }
+       return NULL;
+}
+
+static size_t get_size_cb(void *priv, size_t offset)
+{
+       struct lttng_ust_jni_ctx_entry *jctx;
+       size_t size = 0;
+       struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv;
+       const char *ctx_name = jni_provider->name;
+       enum lttng_ust_jni_type jni_type;
+
+       size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char));
+       size += sizeof(char);           /* tag */
+       jctx = lookup_ctx_by_name(ctx_name);
+       if (!jctx) {
+               jni_type = JNI_TYPE_NULL;
+       } else {
+               jni_type = jctx->type;
+       }
+       switch (jni_type) {
+       case JNI_TYPE_NULL:
+               break;
+       case JNI_TYPE_INTEGER:
+               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int32_t));
+               size += sizeof(int32_t);        /* variant */
+               break;
+       case JNI_TYPE_LONG:
+               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int64_t));
+               size += sizeof(int64_t);        /* variant */
+               break;
+       case JNI_TYPE_DOUBLE:
+               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(double));
+               size += sizeof(double);         /* variant */
+               break;
+       case JNI_TYPE_FLOAT:
+               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(float));
+               size += sizeof(float);          /* variant */
+               break;
+       case JNI_TYPE_SHORT:
+               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int16_t));
+               size += sizeof(int16_t);        /* variant */
+               break;
+       case JNI_TYPE_BYTE:             /* Fall-through. */
+       case JNI_TYPE_BOOLEAN:
+               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char));
+               size += sizeof(char);           /* variant */
+               break;
+       case JNI_TYPE_STRING:
+       {
+               /* The value is an offset, the string is in the "strings" array */
+               int32_t string_offset = jctx->value._string_offset;
+               const char *string = get_ctx_string_at_offset(string_offset);
+
+               if (string) {
+                       size += strlen(string) + 1;
+               }
+               break;
+       }
+       default:
+               abort();
+       }
+       return size;
+
+}
+
+static void record_cb(void *priv,
+                struct lttng_ust_lib_ring_buffer_ctx *ctx,
+                struct lttng_ust_channel_buffer *lttng_chan_buf)
+{
+       struct lttng_ust_jni_ctx_entry *jctx;
+       struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv;
+       const char *ctx_name = jni_provider->name;
+       enum lttng_ust_jni_type jni_type;
+       char sel_char;
+
+       jctx = lookup_ctx_by_name(ctx_name);
+       if (!jctx) {
+               jni_type = JNI_TYPE_NULL;
+       } else {
+               jni_type = jctx->type;
+       }
+
+       switch (jni_type) {
+       case JNI_TYPE_NULL:
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               break;
+       case JNI_TYPE_INTEGER:
+       {
+               int32_t v = jctx->value._integer;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_S32;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_LONG:
+       {
+               int64_t v = jctx->value._long;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_S64;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_DOUBLE:
+       {
+               double v = jctx->value._double;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_FLOAT:
+       {
+               float v = jctx->value._float;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_FLOAT;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_SHORT:
+       {
+               int16_t v = jctx->value._short;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_S16;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_BYTE:
+       {
+               char v = jctx->value._byte;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_S8;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_BOOLEAN:
+       {
+               char v = jctx->value._boolean;
+
+               sel_char = LTTNG_UST_DYNAMIC_TYPE_S8;
+               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
+               break;
+       }
+       case JNI_TYPE_STRING:
+       {
+                       int32_t offset = jctx->value._string_offset;
+                       const char *str = get_ctx_string_at_offset(offset);
+
+                       if (str) {
+                               sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING;
+                       } else {
+                               sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
+                       }
+                       lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
+                       if (str) {
+                               lttng_chan_buf->ops->event_write(ctx, str, strlen(str) + 1, 1);
+                       }
+                       break;
+       }
+       default:
+               abort();
+       }
+}
+
+static void get_value_cb(void *priv, struct lttng_ust_ctx_value *value)
+{
+       struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv;
+       struct lttng_ust_jni_ctx_entry *jctx;
+       const char *ctx_name = jni_provider->name;
+       enum lttng_ust_jni_type jni_type;
+
+       jctx = lookup_ctx_by_name(ctx_name);
+       if (!jctx) {
+               jni_type = JNI_TYPE_NULL;
+       } else {
+               jni_type = jctx->type;
+       }
+
+       switch (jni_type) {
+       case JNI_TYPE_NULL:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
+               break;
+       case JNI_TYPE_INTEGER:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
+               value->u.s64 = (int64_t) jctx->value._integer;
+               break;
+       case JNI_TYPE_LONG:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
+               value->u.s64 = jctx->value._long;
+               break;
+       case JNI_TYPE_DOUBLE:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
+               value->u.d = jctx->value._double;
+               break;
+       case JNI_TYPE_FLOAT:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
+               value->u.d = (double) jctx->value._float;
+               break;
+       case JNI_TYPE_SHORT:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
+               value->u.s64 = (int64_t) jctx->value._short;
+               break;
+       case JNI_TYPE_BYTE:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
+               value->u.s64 = (int64_t) jctx->value._byte;
+               break;
+       case JNI_TYPE_BOOLEAN:
+               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
+               value->u.s64 = (int64_t) jctx->value._boolean;
+               break;
+       case JNI_TYPE_STRING:
+       {
+               int32_t offset = jctx->value._string_offset;
+               const char *str = get_ctx_string_at_offset(offset);
+
+               if (str) {
+                       value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING;
+                       value->u.str = str;
+               } else {
+                       value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
+               }
+               break;
+       }
+       default:
+               abort();
+       }
+}
+
+/*
+ * Register a context provider to UST.
+ *
+ * Called from the Java side when an application registers a context retriever,
+ * so we create and register a corresponding provider on the C side.
+ */
+JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registerProvider(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring provider_name)
+{
+       jboolean iscopy;
+       const char *provider_name_jstr;
+       char *provider_name_cstr;
+       struct lttng_ust_context_provider *provider;
+       struct lttng_ust_jni_provider *jni_provider;
+       /*
+        * Note: a "jlong" is 8 bytes on all architectures, whereas a
+        * C "long" varies.
+        */
+       jlong provider_ref;
+
+       provider_name_jstr = (*env)->GetStringUTFChars(env, provider_name, &iscopy);
+       if (!provider_name_jstr) {
+               goto error_jstr;
+       }
+       /* Keep our own copy of the string so UST can use it. */
+       provider_name_cstr = strdup(provider_name_jstr);
+       (*env)->ReleaseStringUTFChars(env, provider_name, provider_name_jstr);
+       if (!provider_name_cstr) {
+               goto error_strdup;
+       }
+       jni_provider = zmalloc(sizeof(*jni_provider));
+       if (!jni_provider) {
+               goto error_provider;
+       }
+       provider = &jni_provider->provider;
+       provider->struct_size = sizeof(*provider);
+       jni_provider->name = provider_name_cstr;
+       provider->name = jni_provider->name;
+       provider->get_size = get_size_cb;
+       provider->record = record_cb;
+       provider->get_value = get_value_cb;
+       provider->priv = jni_provider;
+
+       jni_provider->reg_provider = lttng_ust_context_provider_register(provider);
+       if (!jni_provider->reg_provider) {
+               goto error_register;
+       }
+
+       provider_ref = (jlong) (long) jni_provider;
+       return provider_ref;
+
+       /* Error handling. */
+error_register:
+       free(jni_provider);
+error_provider:
+       free(provider_name_cstr);
+error_strdup:
+error_jstr:
+       return 0;
+}
+
+/*
+ * Unregister a previously-registered context provider.
+ *
+ * Called from the Java side when an application unregisters a context retriever,
+ * so we unregister and delete the corresponding provider on the C side.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_unregisterProvider(JNIEnv *env __attribute__((unused)),
+                                               jobject jobj __attribute__((unused)),
+                                               jlong provider_ref)
+{
+       struct lttng_ust_jni_provider *jni_provider =
+                       (struct lttng_ust_jni_provider *) (unsigned long) provider_ref;
+
+       if (!jni_provider) {
+               return;
+       }
+
+       lttng_ust_context_provider_unregister(jni_provider->reg_provider);
+
+       free(jni_provider->name);
+       free(jni_provider);
+}
diff --git a/src/lib/lttng-ust-java-agent/jni/common/lttng_ust_context.h b/src/lib/lttng-ust-java-agent/jni/common/lttng_ust_context.h
new file mode 100644 (file)
index 0000000..ab003c8
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ */
+
+#ifndef LIBLTTNG_UST_JAVA_AGENT_JNI_COMMON_LTTNG_UST_CONTEXT_H_
+#define LIBLTTNG_UST_JAVA_AGENT_JNI_COMMON_LTTNG_UST_CONTEXT_H_
+
+struct lttng_ust_jni_ctx_entry;
+
+struct lttng_ust_jni_tls {
+       struct lttng_ust_jni_ctx_entry *ctx_entries;
+       int32_t ctx_entries_len;
+       signed char *ctx_strings;
+       int32_t ctx_strings_len;
+};
+
+extern __thread struct lttng_ust_jni_tls lttng_ust_context_info_tls;
+
+#endif /* LIBLTTNG_UST_JAVA_AGENT_JNI_COMMON_LTTNG_UST_CONTEXT_H_ */
diff --git a/src/lib/lttng-ust-java-agent/jni/jul/Makefile.am b/src/lib/lttng-ust-java-agent/jni/jul/Makefile.am
new file mode 100644 (file)
index 0000000..295b033
--- /dev/null
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
+
+lib_LTLIBRARIES = liblttng-ust-jul-jni.la
+liblttng_ust_jul_jni_la_SOURCES = lttng_ust_jul.c \
+       lttng_ust_jul.h
+
+nodist_liblttng_ust_jul_jni_la_SOURCES = org_lttng_ust_agent_jul_LttngJulApi.h
+
+liblttng_ust_jul_jni_la_LIBADD = -lc \
+       $(top_builddir)/src/liblttng-ust/liblttng-ust.la \
+       $(top_builddir)/src/lib/lttng-ust-java-agent/jni/common/liblttng-ust-context-jni.la
diff --git a/src/lib/lttng-ust-java-agent/jni/jul/lttng_ust_jul.c b/src/lib/lttng-ust-java-agent/jni/jul/lttng_ust_jul.c
new file mode 100644 (file)
index 0000000..afc9f11
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#define _LGPL_SOURCE
+#include "org_lttng_ust_agent_jul_LttngJulApi.h"
+
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_CREATE_PROBES
+#include "lttng_ust_jul.h"
+#include "../common/lttng_ust_context.h"
+
+/*
+ * Deprecated function from before the context information was passed.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_agent_jul_LttngJulApi_tracepoint(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring msg,
+                                               jstring logger_name,
+                                               jstring class_name,
+                                               jstring method_name,
+                                               jlong millis,
+                                               jint log_level,
+                                               jint thread_id)
+{
+       jboolean iscopy;
+       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
+       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
+       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
+       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
+
+       tracepoint(lttng_jul, event, msg_cstr, logger_name_cstr,
+                       class_name_cstr, method_name_cstr, millis, log_level, thread_id);
+
+       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
+       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
+}
+
+/*
+ * Tracepoint used by Java applications using the JUL handler.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_agent_jul_LttngJulApi_tracepointWithContext(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring msg,
+                                               jstring logger_name,
+                                               jstring class_name,
+                                               jstring method_name,
+                                               jlong millis,
+                                               jint log_level,
+                                               jint thread_id,
+                                               jbyteArray context_info_entries,
+                                               jbyteArray context_info_strings)
+{
+       jboolean iscopy;
+       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
+       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
+       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
+       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
+       signed char *context_info_entries_array;
+       signed char *context_info_strings_array;
+
+       /*
+        * Write these to the TLS variables, so that the UST callbacks in
+        * lttng_ust_context.c can access them.
+        */
+       context_info_entries_array = (*env)->GetByteArrayElements(env, context_info_entries, &iscopy);
+       lttng_ust_context_info_tls.ctx_entries = (struct lttng_ust_jni_ctx_entry *) context_info_entries_array;
+       lttng_ust_context_info_tls.ctx_entries_len = (*env)->GetArrayLength(env, context_info_entries);
+       context_info_strings_array = (*env)->GetByteArrayElements(env, context_info_strings, &iscopy);
+       lttng_ust_context_info_tls.ctx_strings = context_info_strings_array;
+       lttng_ust_context_info_tls.ctx_strings_len = (*env)->GetArrayLength(env, context_info_strings);
+
+       tracepoint(lttng_jul, event, msg_cstr, logger_name_cstr,
+                       class_name_cstr, method_name_cstr, millis, log_level, thread_id);
+
+       lttng_ust_context_info_tls.ctx_entries = NULL;
+       lttng_ust_context_info_tls.ctx_entries_len = 0;
+       lttng_ust_context_info_tls.ctx_strings = NULL;
+       lttng_ust_context_info_tls.ctx_strings_len = 0;
+       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
+       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
+       (*env)->ReleaseByteArrayElements(env, context_info_entries, context_info_entries_array, 0);
+       (*env)->ReleaseByteArrayElements(env, context_info_strings, context_info_strings_array, 0);
+}
diff --git a/src/lib/lttng-ust-java-agent/jni/jul/lttng_ust_jul.h b/src/lib/lttng-ust-java-agent/jni/jul/lttng_ust_jul.h
new file mode 100644 (file)
index 0000000..13003bf
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER lttng_jul
+
+#if !defined(_TRACEPOINT_LTTNG_UST_JUL_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _TRACEPOINT_LTTNG_UST_JUL_H
+
+#include <lttng/tracepoint.h>
+
+/*
+ * Tracepoint used by Java applications using the JUL handler.
+ */
+TRACEPOINT_EVENT(lttng_jul, event,
+       TP_ARGS(
+               const char *, msg,
+               const char *, logger_name,
+               const char *, class_name,
+               const char *, method_name,
+               long, millis,
+               int, log_level,
+               int, thread_id),
+       TP_FIELDS(
+               ctf_string(msg, msg)
+               ctf_string(logger_name, logger_name)
+               ctf_string(class_name, class_name)
+               ctf_string(method_name, method_name)
+               ctf_integer(long, long_millis, millis)
+               ctf_integer(int, int_loglevel, log_level)
+               ctf_integer(int, int_threadid, thread_id)
+       )
+)
+
+#endif /* _TRACEPOINT_LTTNG_UST_JUL_H */
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./lttng_ust_jul.h"
+
+/* This part must be outside protection */
+#include <lttng/tracepoint-event.h>
diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am b/src/lib/lttng-ust-java-agent/jni/log4j/Makefile.am
new file mode 100644 (file)
index 0000000..029462e
--- /dev/null
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
+
+lib_LTLIBRARIES = liblttng-ust-log4j-jni.la
+liblttng_ust_log4j_jni_la_SOURCES = lttng_ust_log4j.c \
+       lttng_ust_log4j.h
+
+nodist_liblttng_ust_log4j_jni_la_SOURCES = org_lttng_ust_agent_log4j_LttngLog4jApi.h
+
+liblttng_ust_log4j_jni_la_LIBADD = -lc \
+       $(top_builddir)/src/liblttng-ust/liblttng-ust.la \
+       $(top_builddir)/src/lib/lttng-ust-java-agent/jni/common/liblttng-ust-context-jni.la
diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j.c b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j.c
new file mode 100644 (file)
index 0000000..e88235a
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2016 EfficiOS Inc.
+ * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#define _LGPL_SOURCE
+#include "org_lttng_ust_agent_log4j_LttngLog4jApi.h"
+
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_CREATE_PROBES
+#include "lttng_ust_log4j.h"
+#include "../common/lttng_ust_context.h"
+
+/*
+ * Deprecated function from before the context information was passed.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_agent_log4j_LttngLog4jApi_tracepoint(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring msg,
+                                               jstring logger_name,
+                                               jstring class_name,
+                                               jstring method_name,
+                                               jstring file_name,
+                                               jint line_number,
+                                               jlong timestamp,
+                                               jint loglevel,
+                                               jstring thread_name)
+{
+       jboolean iscopy;
+       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
+       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
+       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
+       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
+       const char *file_name_cstr = (*env)->GetStringUTFChars(env, file_name, &iscopy);
+       const char *thread_name_cstr = (*env)->GetStringUTFChars(env, thread_name, &iscopy);
+
+       tracepoint(lttng_log4j, event, msg_cstr, logger_name_cstr,
+                  class_name_cstr, method_name_cstr, file_name_cstr,
+                  line_number, timestamp, loglevel, thread_name_cstr);
+
+       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
+       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, file_name, file_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, thread_name, thread_name_cstr);
+}
+
+/*
+ * Tracepoint used by Java applications using the log4j handler.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_agent_log4j_LttngLog4jApi_tracepointWithContext(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring msg,
+                                               jstring logger_name,
+                                               jstring class_name,
+                                               jstring method_name,
+                                               jstring file_name,
+                                               jint line_number,
+                                               jlong timestamp,
+                                               jint loglevel,
+                                               jstring thread_name,
+                                               jbyteArray context_info_entries,
+                                               jbyteArray context_info_strings)
+{
+       jboolean iscopy;
+       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
+       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
+       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
+       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
+       const char *file_name_cstr = (*env)->GetStringUTFChars(env, file_name, &iscopy);
+       const char *thread_name_cstr = (*env)->GetStringUTFChars(env, thread_name, &iscopy);
+       signed char *context_info_entries_array;
+       signed char *context_info_strings_array;
+
+       /*
+        * Write these to the TLS variables, so that the UST callbacks in
+        * lttng_ust_context.c can access them.
+        */
+       context_info_entries_array = (*env)->GetByteArrayElements(env, context_info_entries, &iscopy);
+       lttng_ust_context_info_tls.ctx_entries = (struct lttng_ust_jni_ctx_entry *) context_info_entries_array;
+       lttng_ust_context_info_tls.ctx_entries_len = (*env)->GetArrayLength(env, context_info_entries);
+       context_info_strings_array = (*env)->GetByteArrayElements(env, context_info_strings, &iscopy);
+       lttng_ust_context_info_tls.ctx_strings = context_info_strings_array;
+       lttng_ust_context_info_tls.ctx_strings_len = (*env)->GetArrayLength(env, context_info_strings);
+
+       tracepoint(lttng_log4j, event, msg_cstr, logger_name_cstr,
+                  class_name_cstr, method_name_cstr, file_name_cstr,
+                  line_number, timestamp, loglevel, thread_name_cstr);
+
+       lttng_ust_context_info_tls.ctx_entries = NULL;
+       lttng_ust_context_info_tls.ctx_entries_len = 0;
+       lttng_ust_context_info_tls.ctx_strings = NULL;
+       lttng_ust_context_info_tls.ctx_strings_len = 0;
+       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
+       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, file_name, file_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, thread_name, thread_name_cstr);
+       (*env)->ReleaseByteArrayElements(env, context_info_entries, context_info_entries_array, 0);
+       (*env)->ReleaseByteArrayElements(env, context_info_strings, context_info_strings_array, 0);
+}
diff --git a/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j.h b/src/lib/lttng-ust-java-agent/jni/log4j/lttng_ust_log4j.h
new file mode 100644 (file)
index 0000000..c7d7d52
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER lttng_log4j
+
+#if !defined(_TRACEPOINT_LTTNG_UST_LOG4J_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _TRACEPOINT_LTTNG_UST_LOG4J_H
+
+#include <lttng/tracepoint.h>
+
+/*
+ * Tracepoint used by Java applications using the log4j log appender.
+ */
+TRACEPOINT_EVENT(lttng_log4j, event,
+       TP_ARGS(
+               const char *, msg,
+               const char *, logger_name,
+               const char *, class_name,
+               const char *, method_name,
+               const char *, file_name,
+               int, line_number,
+               long, timestamp,
+               int, log_level,
+               const char *, thread_name),
+       TP_FIELDS(
+               ctf_string(msg, msg)
+               ctf_string(logger_name, logger_name)
+               ctf_string(class_name, class_name)
+               ctf_string(method_name, method_name)
+               ctf_string(filename, file_name)
+               ctf_integer(int, line_number, line_number)
+               ctf_integer(long, timestamp, timestamp)
+               ctf_integer(int, int_loglevel, log_level)
+               ctf_string(thread_name, thread_name)
+       )
+)
+
+#endif /* _TRACEPOINT_LTTNG_UST_LOG4J_H */
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./lttng_ust_log4j.h"
+
+/* This part must be outside protection */
+#include <lttng/tracepoint-event.h>
diff --git a/src/lib/lttng-ust-java/.gitignore b/src/lib/lttng-ust-java/.gitignore
new file mode 100644 (file)
index 0000000..e07ee50
--- /dev/null
@@ -0,0 +1,3 @@
+org_lttng_ust_LTTngUst.h
+org/
+liblttng-ust-java.jar
diff --git a/src/lib/lttng-ust-java/LTTngUst.c b/src/lib/lttng-ust-java/LTTngUst.c
new file mode 100644 (file)
index 0000000..f5e0c96
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#define _LGPL_SOURCE
+#include "org_lttng_ust_LTTngUst.h"
+
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_CREATE_PROBES
+#include "lttng_ust_java.h"
+
+JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointInt(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring ev_name,
+                                               jint payload)
+{
+       jboolean iscopy;
+       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
+
+       tracepoint(lttng_ust_java, int_event, ev_name_cstr, payload);
+
+       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
+}
+
+JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointIntInt(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring ev_name,
+                                               jint payload1,
+                                               jint payload2)
+{
+       jboolean iscopy;
+       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
+
+       tracepoint(lttng_ust_java, int_int_event, ev_name_cstr, payload1, payload2);
+
+       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
+}
+
+JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env,
+                                               jobject jobj  __attribute__((unused)),
+                                               jstring ev_name,
+                                               jlong payload)
+{
+       jboolean iscopy;
+       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
+
+       tracepoint(lttng_ust_java, long_event, ev_name_cstr, payload);
+
+       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
+}
+
+JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLongLong(JNIEnv *env,
+                                               jobject jobj  __attribute__((unused)),
+                                               jstring ev_name,
+                                               jlong payload1,
+                                               jlong payload2)
+{
+       jboolean iscopy;
+       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
+
+       tracepoint(lttng_ust_java, long_long_event, ev_name_cstr, payload1, payload2);
+
+       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
+}
+
+JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointString(JNIEnv *env,
+                                               jobject jobj __attribute__((unused)),
+                                               jstring ev_name,
+                                               jstring payload)
+{
+       jboolean iscopy;
+       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
+       const char *payload_cstr = (*env)->GetStringUTFChars(env, payload, &iscopy);
+
+       tracepoint(lttng_ust_java, string_event, ev_name_cstr, payload_cstr);
+
+       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, payload, payload_cstr);
+}
+
diff --git a/src/lib/lttng-ust-java/Makefile.am b/src/lib/lttng-ust-java/Makefile.am
new file mode 100644 (file)
index 0000000..55252fb
--- /dev/null
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: LGPL-2.1-only
+
+JAVAROOT = .
+jarfile = liblttng-ust-java.jar
+jardir = $(datadir)/java
+pkgpath = org/lttng/ust
+
+dist_noinst_JAVA = $(pkgpath)/LTTngUst.java
+jar_DATA = $(jarfile)
+BUILT_SOURCES = org_lttng_ust_LTTngUst.h
+
+AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
+lib_LTLIBRARIES = liblttng-ust-java.la
+liblttng_ust_java_la_SOURCES = LTTngUst.c lttng_ust_java.h
+nodist_liblttng_ust_java_la_SOURCES = org_lttng_ust_LTTngUst.h
+
+liblttng_ust_java_la_LIBADD = -lc \
+       $(top_builddir)/src/liblttng-ust/liblttng-ust.la
+
+$(jarfile): classnoinst.stamp
+       $(JAR) cf $(JARFLAGS) $@ $(pkgpath)/*.class
+
+if !HAVE_JAVAH
+# If we don't have javah, assume we are running openjdk >= 10 and use javac
+# to generate the jni header file.
+AM_JAVACFLAGS = -h .
+
+org_lttng_ust_LTTngUst.h: $(jarfile)
+else
+org_lttng_ust_LTTngUst.h: jni-header.stamp
+
+jni-header.stamp: $(dist_noinst_JAVA)
+       $(JAVAH) -classpath $(srcdir) $(JAVAHFLAGS) org.lttng.ust.LTTngUst && \
+       echo "JNI header generated" > jni-header.stamp
+endif
+
+all-local: org_lttng_ust_LTTngUst.h
+
+EXTRA_DIST = README
+
+CLEANFILES = $(jarfile) $(pkgpath)/*.class jni-header.stamp org_lttng_ust_LTTngUst.h
diff --git a/src/lib/lttng-ust-java/README b/src/lib/lttng-ust-java/README
new file mode 100644 (file)
index 0000000..d2ca478
--- /dev/null
@@ -0,0 +1,15 @@
+This directory contains a simple API for instrumenting java applications.
+
+Configuration examples to build this library:
+
+dependency: openjdk-7-jdk
+./configure --enable-jni-interface
+
+Note that the OpenJDK 7 is used for development and continuous integration thus
+we directly support that version for this library. However, it has been tested
+with OpenJDK 6 also. Please let us know if other Java version (commercial or
+not) work with this library.
+
+After building, you can use the liblttng-ust-java.jar file in a Java project.
+It requires the liblttng-ust-java.so* files (which get installed when doing
+`make install') so make sure those are in the linker's library path.
diff --git a/src/lib/lttng-ust-java/lttng_ust_java.h b/src/lib/lttng-ust-java/lttng_ust_java.h
new file mode 100644 (file)
index 0000000..ea515a8
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2011  Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ */
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER lttng_ust_java
+
+#if !defined(_TRACEPOINT_LTTNG_UST_JAVA_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _TRACEPOINT_LTTNG_UST_JAVA_H
+
+#include <lttng/tracepoint.h>
+
+TRACEPOINT_EVENT(lttng_ust_java, int_event,
+       TP_ARGS(const char *, name, int, payload),
+       TP_FIELDS(
+               ctf_string(name, name)
+               ctf_integer(int, int_payload, payload)
+       )
+)
+
+TRACEPOINT_EVENT(lttng_ust_java, int_int_event,
+       TP_ARGS(const char *, name, int, payload1, int, payload2),
+       TP_FIELDS(
+               ctf_string(name, name)
+               ctf_integer(int, int_payload1, payload1)
+               ctf_integer(int, int_payload2, payload2)
+       )
+)
+
+TRACEPOINT_EVENT(lttng_ust_java, long_event,
+       TP_ARGS(const char *, name, long, payload),
+       TP_FIELDS(
+               ctf_string(name, name)
+               ctf_integer(long, long_payload, payload)
+       )
+)
+
+TRACEPOINT_EVENT(lttng_ust_java, long_long_event,
+       TP_ARGS(const char *, name, long, payload1, long, payload2),
+       TP_FIELDS(
+               ctf_string(name, name)
+               ctf_integer(long, long_payload1, payload1)
+               ctf_integer(long, long_payload2, payload2)
+       )
+)
+
+TRACEPOINT_EVENT(lttng_ust_java, string_event,
+       TP_ARGS(const char *, name, const char *, payload),
+       TP_FIELDS(
+               ctf_string(name, name)
+               ctf_string(string_payload, payload)
+       )
+)
+
+#endif /* _TRACEPOINT_LTTNG_UST_JAVA_H */
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./lttng_ust_java.h"
+
+/* This part must be outside protection */
+#include <lttng/tracepoint-event.h>
diff --git a/src/lib/lttng-ust-java/org/lttng/ust/LTTngUst.java b/src/lib/lttng-ust-java/org/lttng/ust/LTTngUst.java
new file mode 100644 (file)
index 0000000..cc14a72
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2012 Alexandre Montplaisir <alexandre.montplaisir@polymtl.ca>
+ */
+
+package org.lttng.ust;
+
+/**
+ * This class implements the the Java side of the LTTng-UST Java interface.
+ *
+ * First, make sure you have installed "liblttng-ust-java.so" where the linker
+ * can find it. You can then call LTTngUst.init() from your Java program to
+ * connect the methods exposed here to the native library.
+ *
+ * Because of limitations in the probe declaration, all trace events generated
+ * by this library will have "lttng_ust_java" for domain, and "<type>_event" for
+ * event name in the CTF trace files. The "name" parameter will instead appear
+ * as the first element of the event's payload.
+ *
+ * @author Mathieu Desnoyers
+ * @author Alexandre Montplaisir
+ *
+ */
+public abstract class LTTngUst {
+
+    /**
+     * Initialize the UST tracer. This should always be called first, before any
+     * tracepoint* method.
+     */
+    public static void init() {
+        System.loadLibrary("lttng-ust-java"); //$NON-NLS-1$
+    }
+
+    /**
+     * Insert a tracepoint with a payload of type Integer.
+     *
+     * @param name
+     *            The name assigned to this event. For best performance, this
+     *            should be a statically-defined String, or a literal.
+     * @param payload
+     *            The int payload
+     */
+    public static native void tracepointInt(String name, int payload);
+
+    /**
+     * Insert a tracepoint with a payload consisting of two integers.
+     *
+     * @param name
+     *            The name assigned to this event. For best performance, this
+     *            should be a statically-defined String, or a literal.
+     * @param payload1
+     *            The first int payload
+     * @param payload2
+     *            The second int payload
+     */
+    public static native void
+    tracepointIntInt(String name, int payload1, int payload2);
+
+    /**
+     * Insert a tracepoint with a payload of type Long
+     *
+     * @param name
+     *            The name assigned to this event. For best performance, this
+     *            should be a statically-defined String, or a literal.
+     * @param payload
+     *            The long payload
+     */
+    public static native void tracepointLong(String name, long payload);
+
+    /**
+     * Insert a tracepoint with a payload consisting of two longs.
+     *
+     * @param name
+     *            The name assigned to this event. For best performance, this
+     *            should be a statically-defined String, or a literal.
+     * @param payload1
+     *            The first long payload
+     * @param payload2
+     *            The second long payload
+     */
+    public static native void
+    tracepointLongLong(String name, long payload1, long payload2);
+
+    /**
+     * Insert a tracepoint with a String payload.
+     *
+     * @param name
+     *            The name assigned to this event. For best performance, this
+     *            should be a statically-defined String, or a literal.
+     * @param payload
+     *            The String payload
+     */
+    public static native void tracepointString(String name, String payload);
+
+}
+
diff --git a/src/liblttng-ust-java-agent/Makefile.am b/src/liblttng-ust-java-agent/Makefile.am
deleted file mode 100644 (file)
index ad47256..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-SUBDIRS = java jni
diff --git a/src/liblttng-ust-java-agent/java/Makefile.am b/src/liblttng-ust-java-agent/java/Makefile.am
deleted file mode 100644 (file)
index 96d575a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-SUBDIRS = lttng-ust-agent-common lttng-ust-agent-all
-
-if ENABLE_JAVA_AGENT_WITH_JUL
-SUBDIRS += lttng-ust-agent-jul
-endif
-
-if ENABLE_JAVA_AGENT_WITH_LOG4J
-SUBDIRS += lttng-ust-agent-log4j
-endif
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Makefile.am b/src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Makefile.am
deleted file mode 100644 (file)
index b6cf9aa..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-JAVAROOT = .
-
-jarfile_version = 1.0.0
-jarfile_manifest = $(srcdir)/Manifest.txt
-jarfile_symlink = lttng-ust-agent-all.jar
-jarfile = lttng-ust-agent-all-$(jarfile_version).jar
-
-# Compatibility symlink provided for applications expecting the agent
-# jar file installed by UST 2.7.
-jarfile_compat_symlink = liblttng-ust-agent.jar
-
-jardir = $(datadir)/java
-
-dist_noinst_DATA = $(jarfile_manifest)
-
-jar_DATA = $(jarfile)
-
-$(jarfile):
-       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) \
-               && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink) \
-               && rm -f $(jarfile_compat_symlink) && $(LN_S) $(jarfile_symlink) $(jarfile_compat_symlink)
-
-install-data-hook:
-       cd $(DESTDIR)/$(jardir) \
-               && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink) \
-               && rm -f $(jarfile_compat_symlink) && $(LN_S) $(jarfile_symlink) $(jarfile_compat_symlink)
-
-uninstall-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && rm -f $(jarfile_compat_symlink)
-
-CLEANFILES = *.jar
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Manifest.txt b/src/liblttng-ust-java-agent/java/lttng-ust-agent-all/Manifest.txt
deleted file mode 100644 (file)
index e09c85e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Name: org/lttng/ust/agent/all/
-Specification-Title: LTTng UST All Java Agents
-Specification-Version: 1.0.0
-Specification-Vendor: LTTng Project
-Implementation-Title: org.lttng.ust.agent.all
-Implementation-Version: 1.0.0
-Implementation-Vendor: LTTng Project
-Class-Path: lttng-ust-agent-common.jar lttng-ust-agent-jul.jar lttng-ust-agent-log4j.jar
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Makefile.am
deleted file mode 100644 (file)
index 473e872..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-JAVAROOT = .
-
-pkgpath = org/lttng/ust/agent
-
-jarfile_version = 1.0.0
-jarfile_manifest = $(srcdir)/Manifest.txt
-jarfile_symlink = lttng-ust-agent-common.jar
-jarfile = lttng-ust-agent-common-$(jarfile_version).jar
-
-jardir = $(datadir)/java
-jnioutdir = ../../jni/common
-
-dist_noinst_JAVA = $(pkgpath)/AbstractLttngAgent.java \
-                                  $(pkgpath)/EventNamePattern.java \
-                                  $(pkgpath)/ILttngAgent.java \
-                                  $(pkgpath)/ILttngHandler.java \
-                                  $(pkgpath)/LTTngAgent.java \
-                                  $(pkgpath)/client/ILttngTcpClientListener.java \
-                                  $(pkgpath)/client/SessiondCommand.java \
-                                  $(pkgpath)/client/LttngAgentResponse.java \
-                                  $(pkgpath)/client/LttngTcpSessiondClient.java \
-                                  $(pkgpath)/client/SessiondCommandHeader.java \
-                                  $(pkgpath)/client/SessiondDisableAppContextCommand.java \
-                                  $(pkgpath)/client/SessiondDisableEventCommand.java \
-                                  $(pkgpath)/client/SessiondEnableAppContextCommand.java \
-                                  $(pkgpath)/client/SessiondEnableEventCommand.java \
-                                  $(pkgpath)/client/SessiondListLoggersCommand.java \
-                                  $(pkgpath)/context/LttngContextApi.java \
-                                  $(pkgpath)/context/ContextInfoManager.java \
-                                  $(pkgpath)/context/ContextInfoSerializer.java \
-                                  $(pkgpath)/context/IContextInfoRetriever.java \
-                                  $(pkgpath)/filter/FilterChangeNotifier.java \
-                                  $(pkgpath)/filter/IFilterChangeListener.java \
-                                  $(pkgpath)/session/EventRule.java \
-                                  $(pkgpath)/session/LogLevelSelector.java \
-                                  $(pkgpath)/utils/LttngUstAgentLogger.java
-
-
-dist_noinst_DATA = $(jarfile_manifest)
-
-jar_DATA = $(jarfile)
-
-classes = $(pkgpath)/*.class \
-                 $(pkgpath)/client/*.class \
-                 $(pkgpath)/context/*.class \
-                 $(pkgpath)/filter/*.class \
-                 $(pkgpath)/session/*.class \
-                 $(pkgpath)/utils/*.class
-
-$(jarfile): classnoinst.stamp
-       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
-
-if !HAVE_JAVAH
-# If we don't have javah, assume we are running openjdk >= 10 and use javac
-# to generate the jni header file.
-AM_JAVACFLAGS = -h $(jnioutdir)
-else
-context-jni-header.stamp: $(dist_noinst_JAVA)
-       $(JAVAH) -classpath $(CLASSPATH):$(srcdir) -d $(jnioutdir) $(JAVAHFLAGS) org.lttng.ust.agent.context.LttngContextApi && \
-       echo "Context API JNI header generated" > context-jni-header.stamp
-
-all-local: context-jni-header.stamp
-endif
-
-install-data-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink)
-
-uninstall-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
-
-CLEANFILES = *.jar \
-                        $(pkgpath)/*.class \
-                        $(pkgpath)/client/*.class \
-                        $(pkgpath)/context/*.class \
-                        $(pkgpath)/filter/*.class \
-                        $(pkgpath)/session/*.class \
-                        $(pkgpath)/utils/*.class \
-                        context-jni-header.stamp \
-                        $(jnioutdir)/org_lttng_ust_agent_context_LttngContextApi.h
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Manifest.txt b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/Manifest.txt
deleted file mode 100644 (file)
index d3c7e26..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Name: org/lttng/ust/agent/
-Specification-Title: LTTng UST Java Agent
-Specification-Version: 1.0.0
-Specification-Vendor: LTTng Project
-Implementation-Title: org.lttng.ust.agent
-Implementation-Version: 1.0.0
-Implementation-Vendor: LTTng Project
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/AbstractLttngAgent.java
deleted file mode 100644 (file)
index acbdc4f..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.regex.Matcher;
-
-import org.lttng.ust.agent.client.ILttngTcpClientListener;
-import org.lttng.ust.agent.client.LttngTcpSessiondClient;
-import org.lttng.ust.agent.filter.FilterChangeNotifier;
-import org.lttng.ust.agent.session.EventRule;
-import org.lttng.ust.agent.utils.LttngUstAgentLogger;
-
-/**
- * Base implementation of a {@link ILttngAgent}.
- *
- * @author Alexandre Montplaisir
- * @param <T>
- *            The type of logging handler that should register to this agent
- */
-public abstract class AbstractLttngAgent<T extends ILttngHandler>
-               implements ILttngAgent<T>, ILttngTcpClientListener {
-
-       private static final int INIT_TIMEOUT = 3; /* Seconds */
-
-       /** The handlers registered to this agent */
-       private final Set<T> registeredHandlers = new HashSet<T>();
-
-       /**
-        * The trace events currently enabled in the sessions.
-        *
-        * The key is the {@link EventNamePattern} that comes from the event name.
-        * The value is the ref count (how many different sessions currently have
-        * this event enabled). Once the ref count falls to 0, this means we can
-        * avoid sending log events through JNI because nobody wants them.
-        *
-        * Its accesses should be protected by the {@link #enabledEventNamesLock}
-        * below.
-        */
-       private final Map<EventNamePattern, Integer> enabledPatterns = new HashMap<EventNamePattern, Integer>();
-
-       /**
-        * Cache of already-checked event names. As long as enabled/disabled events
-        * don't change in the session, we can avoid re-checking events that were
-        * previously checked against all known enabled patterns.
-        *
-        * Its accesses should be protected by the {@link #enabledEventNamesLock}
-        * below, with the exception of concurrent get operations.
-        */
-       private final Map<String, Boolean> enabledEventNamesCache = new ConcurrentHashMap<String, Boolean>();
-
-       /**
-        * Lock protecting accesses to the {@link #enabledPatterns} and
-        * {@link #enabledEventNamesCache} maps.
-        */
-       private final Lock enabledEventNamesLock = new ReentrantLock();
-
-       /**
-        * The application contexts currently enabled in the tracing sessions.
-        *
-        * It is first indexed by context retriever, then by context name. This
-        * allows to efficiently query all the contexts for a given retriever.
-        *
-        * Works similarly as {@link #enabledEvents}, but for app contexts (and with
-        * an extra degree of indexing).
-        *
-        * TODO Could be changed to a Guava Table once/if we start using it.
-        */
-       private final Map<String, Map<String, Integer>> enabledAppContexts = new ConcurrentHashMap<String, Map<String, Integer>>();
-
-       /** Tracing domain. Defined by the sub-classes via the constructor. */
-       private final Domain domain;
-
-       /* Lazy-loaded sessiond clients and their thread objects */
-       private LttngTcpSessiondClient rootSessiondClient = null;
-       private LttngTcpSessiondClient userSessiondClient = null;
-       private Thread rootSessiondClientThread = null;
-       private Thread userSessiondClientThread = null;
-
-       /** Indicates if this agent has been initialized. */
-       private boolean initialized = false;
-
-       /**
-        * Constructor. Should only be called by sub-classes via super(...);
-        *
-        * @param domain
-        *            The tracing domain of this agent.
-        */
-       protected AbstractLttngAgent(Domain domain) {
-               this.domain = domain;
-       }
-
-       @Override
-       public Domain getDomain() {
-               return domain;
-       }
-
-       @Override
-       public void registerHandler(T handler) {
-               synchronized (registeredHandlers) {
-                       if (registeredHandlers.isEmpty()) {
-                               /*
-                                * This is the first handler that registers, we will initialize
-                                * the agent.
-                                */
-                               init();
-                       }
-                       registeredHandlers.add(handler);
-               }
-       }
-
-       @Override
-       public void unregisterHandler(T handler) {
-               synchronized (registeredHandlers) {
-                       registeredHandlers.remove(handler);
-                       if (registeredHandlers.isEmpty()) {
-                               /* There are no more registered handlers, close the connection. */
-                               dispose();
-                       }
-               }
-       }
-
-       private void init() {
-               /*
-                * Only called from a synchronized (registeredHandlers) block, should
-                * not need additional synchronization.
-                */
-               if (initialized) {
-                       return;
-               }
-
-               LttngUstAgentLogger.log(AbstractLttngAgent.class, "Initializing Agent for domain: " + domain.name());
-
-               String rootClientThreadName = "Root sessiond client started by agent: " + this.getClass().getSimpleName();
-
-               rootSessiondClient = new LttngTcpSessiondClient(this, getDomain().value(), true);
-               rootSessiondClientThread = new Thread(rootSessiondClient, rootClientThreadName);
-               rootSessiondClientThread.setDaemon(true);
-               rootSessiondClientThread.start();
-
-               String userClientThreadName = "User sessiond client started by agent: " + this.getClass().getSimpleName();
-
-               userSessiondClient = new LttngTcpSessiondClient(this, getDomain().value(), false);
-               userSessiondClientThread = new Thread(userSessiondClient, userClientThreadName);
-               userSessiondClientThread.setDaemon(true);
-               userSessiondClientThread.start();
-
-               /* Give the threads' registration a chance to end. */
-               if (!rootSessiondClient.waitForConnection(INIT_TIMEOUT)) {
-                       userSessiondClient.waitForConnection(INIT_TIMEOUT);
-               }
-
-               initialized = true;
-       }
-
-       /**
-        * Dispose the agent
-        */
-       private void dispose() {
-               LttngUstAgentLogger.log(AbstractLttngAgent.class, "Disposing Agent for domain: " + domain.name());
-
-               /*
-                * Only called from a synchronized (registeredHandlers) block, should
-                * not need additional synchronization.
-                */
-               rootSessiondClient.close();
-               userSessiondClient.close();
-
-               try {
-                       rootSessiondClientThread.join();
-                       userSessiondClientThread.join();
-
-               } catch (InterruptedException e) {
-                       e.printStackTrace();
-               }
-               rootSessiondClient = null;
-               rootSessiondClientThread = null;
-               userSessiondClient = null;
-               userSessiondClientThread = null;
-
-               /*
-                * Send filter change notifications for all event rules currently
-                * active, then clear them.
-                */
-               FilterChangeNotifier fcn = FilterChangeNotifier.getInstance();
-
-               enabledEventNamesLock.lock();
-               try {
-                       for (Map.Entry<EventNamePattern, Integer> entry : enabledPatterns.entrySet()) {
-                               String eventName = entry.getKey().getEventName();
-                               Integer nb = entry.getValue();
-                               for (int i = 0; i < nb.intValue(); i++) {
-                                       fcn.removeEventRules(eventName);
-                               }
-                       }
-                       enabledPatterns.clear();
-                       enabledEventNamesCache.clear();
-               } finally {
-                       enabledEventNamesLock.unlock();
-               }
-
-               /*
-                * Also clear tracked app contexts (no filter notifications sent for
-                * those currently).
-                */
-               enabledAppContexts.clear();
-
-               initialized = false;
-       }
-
-       @Override
-       public boolean eventEnabled(EventRule eventRule) {
-               /* Notify the filter change manager of the command */
-               FilterChangeNotifier.getInstance().addEventRule(eventRule);
-
-               String eventName = eventRule.getEventName();
-               EventNamePattern pattern = new EventNamePattern(eventName);
-
-               enabledEventNamesLock.lock();
-               try {
-                       boolean ret = incrementRefCount(pattern, enabledPatterns);
-                       enabledEventNamesCache.clear();
-                       return ret;
-               } finally {
-                       enabledEventNamesLock.unlock();
-               }
-       }
-
-       @Override
-       public boolean eventDisabled(String eventName) {
-               /* Notify the filter change manager of the command */
-               FilterChangeNotifier.getInstance().removeEventRules(eventName);
-
-               EventNamePattern pattern = new EventNamePattern(eventName);
-
-               enabledEventNamesLock.lock();
-               try {
-                       boolean ret = decrementRefCount(pattern, enabledPatterns);
-                       enabledEventNamesCache.clear();
-                       return ret;
-               } finally {
-                       enabledEventNamesLock.unlock();
-               }
-       }
-
-       @Override
-       public boolean appContextEnabled(String contextRetrieverName, String contextName) {
-               synchronized (enabledAppContexts) {
-                       Map<String, Integer> retrieverMap = enabledAppContexts.get(contextRetrieverName);
-                       if (retrieverMap == null) {
-                               /* There is no submap for this retriever, let's create one. */
-                               retrieverMap = new ConcurrentHashMap<String, Integer>();
-                               enabledAppContexts.put(contextRetrieverName, retrieverMap);
-                       }
-
-                       return incrementRefCount(contextName, retrieverMap);
-               }
-       }
-
-       @Override
-       public boolean appContextDisabled(String contextRetrieverName, String contextName) {
-               synchronized (enabledAppContexts) {
-                       Map<String, Integer> retrieverMap = enabledAppContexts.get(contextRetrieverName);
-                       if (retrieverMap == null) {
-                               /* There was no submap for this retriever, invalid command? */
-                               return false;
-                       }
-
-                       boolean ret = decrementRefCount(contextName, retrieverMap);
-
-                       /* If the submap is now empty we can remove it from the main map. */
-                       if (retrieverMap.isEmpty()) {
-                               enabledAppContexts.remove(contextRetrieverName);
-                       }
-
-                       return ret;
-               }
-       }
-
-       /*
-        * Implementation of this method is domain-specific.
-        */
-       @Override
-       public abstract Collection<String> listAvailableEvents();
-
-       @Override
-       public boolean isEventEnabled(String eventName) {
-               Boolean cachedEnabled = enabledEventNamesCache.get(eventName);
-               if (cachedEnabled != null) {
-                       /* We have seen this event previously */
-                       /*
-                        * Careful! enabled == null could also mean that the null value is
-                        * associated with the key. But we should have never inserted null
-                        * values in the map.
-                        */
-                       return cachedEnabled.booleanValue();
-               }
-
-               /*
-                * We have not previously checked this event. Run it against all known
-                * enabled event patterns to determine if it should pass or not.
-                */
-               enabledEventNamesLock.lock();
-               try {
-                       boolean enabled = false;
-                       for (EventNamePattern enabledPattern : enabledPatterns.keySet()) {
-                               Matcher matcher = enabledPattern.getPattern().matcher(eventName);
-                               if (matcher.matches()) {
-                                       enabled = true;
-                                       break;
-                               }
-                       }
-
-                       /* Add the result to the cache */
-                       enabledEventNamesCache.put(eventName, Boolean.valueOf(enabled));
-                       return enabled;
-
-               } finally {
-                       enabledEventNamesLock.unlock();
-               }
-       }
-
-       @Override
-       public Collection<Map.Entry<String, Map<String, Integer>>> getEnabledAppContexts() {
-               return enabledAppContexts.entrySet();
-       }
-
-       private static <T> boolean incrementRefCount(T key, Map<T, Integer> refCountMap) {
-               synchronized (refCountMap) {
-                       Integer count = refCountMap.get(key);
-                       if (count == null) {
-                               /* This is the first instance of this event being enabled */
-                               refCountMap.put(key, Integer.valueOf(1));
-                               return true;
-                       }
-                       if (count.intValue() <= 0) {
-                               /* It should not have been in the map in the first place! */
-                               throw new IllegalStateException();
-                       }
-                       /* The event was already enabled, increment its refcount */
-                       refCountMap.put(key, Integer.valueOf(count.intValue() + 1));
-                       return true;
-               }
-       }
-
-       private static <T> boolean decrementRefCount(T key, Map<T, Integer> refCountMap) {
-               synchronized (refCountMap) {
-                       Integer count = refCountMap.get(key);
-                       if (count == null || count.intValue() <= 0) {
-                               /*
-                                * The sessiond asked us to disable an event that was not
-                                * enabled previously. Command error?
-                                */
-                               return false;
-                       }
-                       if (count.intValue() == 1) {
-                               /*
-                                * This is the last instance of this event being disabled,
-                                * remove it from the map so that we stop sending it.
-                                */
-                               refCountMap.remove(key);
-                               return true;
-                       }
-                       /*
-                        * Other sessions are still looking for this event, simply decrement
-                        * its refcount.
-                        */
-                       refCountMap.put(key, Integer.valueOf(count.intValue() - 1));
-                       return true;
-               }
-       }
-}
-
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java
deleted file mode 100644 (file)
index ada5c95..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2017 EfficiOS Inc.
- * Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
- */
-
-package org.lttng.ust.agent;
-
-import java.util.regex.Pattern;
-
-/**
- * Class encapsulating an event name from the session daemon, and its
- * corresponding {@link Pattern}. This allows referring back to the original
- * event name, for example when we receive a disable command.
- *
- * @author Philippe Proulx
- * @author Alexandre Montplaisir
- */
-class EventNamePattern {
-
-       private final String originalEventName;
-
-       /*
-        * Note that two Patterns coming from the exact same String will not be
-        * equals()! As such, it would be confusing to make the pattern part of this
-        * class's equals/hashCode
-        */
-       private final transient Pattern pattern;
-
-       public EventNamePattern(String eventName) {
-               if (eventName == null) {
-                       throw new IllegalArgumentException();
-               }
-
-               originalEventName = eventName;
-               pattern = patternFromEventName(eventName);
-       }
-
-       public String getEventName() {
-               return originalEventName;
-       }
-
-       public Pattern getPattern() {
-               return pattern;
-       }
-
-       @Override
-       public int hashCode() {
-               final int prime = 31;
-               int result = 1;
-               result = prime * result + originalEventName.hashCode();
-               return result;
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (this == obj) {
-                       return true;
-               }
-               if (obj == null) {
-                       return false;
-               }
-               if (getClass() != obj.getClass()) {
-                       return false;
-               }
-               EventNamePattern other = (EventNamePattern) obj;
-               if (!originalEventName.equals(other.originalEventName)) {
-                       return false;
-               }
-               return true;
-       }
-
-       private static Pattern patternFromEventName(String eventName) {
-               /*
-                * The situation here is that `\*` means a literal `*` in the event
-                * name, and `*` is a wildcard star. We check the event name one
-                * character at a time and create a list of tokens to be converter to
-                * partial patterns.
-                */
-               StringBuilder bigBuilder = new StringBuilder("^");
-               StringBuilder smallBuilder = new StringBuilder();
-
-               for (int i = 0; i < eventName.length(); i++) {
-                       char c = eventName.charAt(i);
-
-                       switch (c) {
-                       case '*':
-                               /* Add current quoted builder's string if not empty. */
-                               if (smallBuilder.length() > 0) {
-                                       bigBuilder.append(Pattern.quote(smallBuilder.toString()));
-                                       smallBuilder.setLength(0);
-                               }
-
-                               /* Append the equivalent regex which is `.*`. */
-                               bigBuilder.append(".*");
-                               continue;
-
-                       case '\\':
-                               /* We only escape `*` and `\` here. */
-                               if (i < (eventName.length() - 1)) {
-                                       char nextChar = eventName.charAt(i + 1);
-
-                                       if (nextChar == '*' || nextChar == '\\') {
-                                               smallBuilder.append(nextChar);
-                                       } else {
-                                               smallBuilder.append(c);
-                                               smallBuilder.append(nextChar);
-                                       }
-
-                                       i++;
-                                       continue;
-                               }
-                               break;
-
-                       default:
-                               break;
-                       }
-
-                       smallBuilder.append(c);
-               }
-
-               /* Add current quoted builder's string if not empty. */
-               if (smallBuilder.length() > 0) {
-                       bigBuilder.append(Pattern.quote(smallBuilder.toString()));
-               }
-
-               bigBuilder.append("$");
-
-               return Pattern.compile(bigBuilder.toString());
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngAgent.java
deleted file mode 100644 (file)
index ca2358a..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Interface to define LTTng Java agents.
- *
- * An "agent" is a representative of an LTTng session daemon in the Java world.
- * It tracks the settings of a tracing session as they defined in the session
- * daemon.
- *
- * It also track the current logging handlers that are sending events to UST.
- *
- * @author Alexandre Montplaisir
- *
- * @param <T>
- *            The type of logging handler that should register to this agent
- */
-public interface ILttngAgent<T extends ILttngHandler> {
-
-       // ------------------------------------------------------------------------
-       // Agent configuration elements
-       // ------------------------------------------------------------------------
-
-       /**
-        * Tracing domains. Corresponds to domains defined by LTTng Tools.
-        */
-       enum Domain {
-               JUL(3), LOG4J(4);
-               private int value;
-
-               private Domain(int value) {
-                       this.value = value;
-               }
-
-               public int value() {
-                       return value;
-               }
-       }
-
-       /**
-        * The tracing domain of this agent.
-        *
-        * @return The tracing domain.
-        */
-       Domain getDomain();
-
-       // ------------------------------------------------------------------------
-       // Log handler registering
-       // ------------------------------------------------------------------------
-
-       /**
-        * Register a handler to this agent.
-        *
-        * @param handler
-        *            The handler to register
-        */
-       void registerHandler(T handler);
-
-       /**
-        * Deregister a handler from this agent.
-        *
-        * @param handler
-        *            The handler to deregister.
-        */
-       void unregisterHandler(T handler);
-
-       // ------------------------------------------------------------------------
-       // Tracing session parameters
-       // ------------------------------------------------------------------------
-
-       /**
-        * Query if a given event is currently enabled in a current tracing session,
-        * meaning it should be sent to UST.
-        *
-        * @param eventName
-        *            The name of the event to check.
-        * @return True if the event is currently enabled, false if it is not.
-        */
-       boolean isEventEnabled(String eventName);
-
-       /**
-        * Return the list of application contexts enabled in the tracing sessions.
-        *
-        * @return The application contexts, first indexed by retriever name, then
-        *         by context name
-        */
-       Collection<Map.Entry<String, Map<String, Integer>>> getEnabledAppContexts();
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngHandler.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/ILttngHandler.java
deleted file mode 100644 (file)
index 0d1bd79..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent;
-
-/**
- * Simple interface to organize all LTTng log handlers under one type.
- *
- * @author Alexandre Montplaisir
- */
-public interface ILttngHandler {
-
-       /**
-        * Get the number of events logged by this handler since its inception.
-        * 
-        * @return The number of logged events
-        */
-       long getEventCount();
-
-       /**
-        * Close the log handler. Should be called once the application is done
-        * logging through it.
-        */
-       void close();
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/LTTngAgent.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/LTTngAgent.java
deleted file mode 100644 (file)
index f6aae35..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.logging.Handler;
-import java.util.logging.Logger;
-
-/**
- * The central agent managing the JUL and Log4j handlers.
- *
- * @author David Goulet
- * @deprecated Applications are now expected to manage their Logger and Handler
- *             objects.
- */
-@Deprecated
-public class LTTngAgent {
-
-       private static LTTngAgent instance = null;
-
-       /**
-        * Public getter to acquire a reference to this singleton object.
-        *
-        * @return The agent instance
-        */
-       public static synchronized LTTngAgent getLTTngAgent() {
-               if (instance == null) {
-                       instance = new LTTngAgent();
-               }
-               return instance;
-       }
-
-       /**
-        * Dispose the agent. Applications should call this once they are done
-        * logging. This dispose function is non-static for backwards
-        * compatibility purposes.
-        */
-       @SuppressWarnings("static-method")
-       public void dispose() {
-               synchronized (LTTngAgent.class) {
-                       if (instance != null) {
-                               instance.disposeInstance();
-                               instance = null;
-                       }
-               }
-               return;
-       }
-
-       private ILttngHandler julHandler = null;
-       private ILttngHandler log4jAppender = null;
-
-       /**
-        * Private constructor. This is a singleton and a reference should be
-        * acquired using {@link #getLTTngAgent()}.
-        */
-       private LTTngAgent() {
-               initJulHandler();
-               initLog4jAppender();
-       }
-
-       /**
-        * "Destructor" method.
-        */
-       private void disposeInstance() {
-               disposeJulHandler();
-               disposeLog4jAppender();
-       }
-
-       /**
-        * Create a LTTng-JUL handler, and attach it to the JUL root logger.
-        */
-       private void initJulHandler() {
-               try {
-                       Class<?> julHandlerClass = Class.forName("org.lttng.ust.agent.jul.LttngLogHandler");
-                       /*
-                        * It is safer to use Constructor.newInstance() rather than
-                        * Class.newInstance(), because it will catch the exceptions thrown
-                        * by the constructor below (which happens if the Java library is
-                        * present, but the matching JNI one is not).
-                        */
-                       Constructor<?> julHandlerCtor = julHandlerClass.getConstructor();
-                       julHandler = (ILttngHandler) julHandlerCtor.newInstance();
-
-                       /* Attach the handler to the root JUL logger */
-                       Logger.getLogger("").addHandler((Handler) julHandler);
-
-                       /*
-                        * If any of the following exceptions happen, it means we could not
-                        * find or initialize LTTng JUL classes. We will not setup LTTng JUL
-                        * tracing in this case.
-                        */
-               } catch (SecurityException e) {
-               } catch (IllegalAccessException e) {
-               } catch (IllegalArgumentException e) {
-               } catch (ClassNotFoundException e) {
-               } catch (NoSuchMethodException e) {
-               } catch (InstantiationException e) {
-               } catch (InvocationTargetException e) {
-               }
-       }
-
-       /**
-        * Create a LTTng-logj4 appender, and attach it to the log4j root logger.
-        */
-       private void initLog4jAppender() {
-               /*
-                * Since Log4j is a 3rd party library, we first need to check if we can
-                * load any of its classes.
-                */
-               if (!testLog4jClasses()) {
-                       return;
-               }
-
-               try {
-                       Class<?> log4jAppenderClass = Class.forName("org.lttng.ust.agent.log4j.LttngLogAppender");
-                       Constructor<?> log4jAppendCtor = log4jAppenderClass.getConstructor();
-                       log4jAppender = (ILttngHandler) log4jAppendCtor.newInstance();
-
-                       /*
-                        * If any of the following exceptions happen, it means we could not
-                        * find or initialize LTTng log4j classes. We will not setup LTTng
-                        * log4j tracing in this case.
-                        */
-               } catch (SecurityException e) {
-                       return;
-               } catch (ClassNotFoundException e) {
-                       return;
-               } catch (NoSuchMethodException e) {
-                       return;
-               } catch (IllegalArgumentException e) {
-                       return;
-               } catch (InstantiationException e) {
-                       return;
-               } catch (IllegalAccessException e) {
-                       return;
-               } catch (InvocationTargetException e) {
-                       return;
-               }
-
-               /*
-                * Attach the appender to the root Log4j logger. Slightly more tricky
-                * here, as log4j.Logger is not in the base Java library, and we do not
-                * want the "common" package to depend on log4j. So we have to obtain it
-                * through reflection too.
-                */
-               try {
-                       Class<?> loggerClass = Class.forName("org.apache.log4j.Logger");
-                       Class<?> appenderClass = Class.forName("org.apache.log4j.Appender");
-
-                       Method getRootLoggerMethod = loggerClass.getMethod("getRootLogger", (Class<?>[]) null);
-                       Method addAppenderMethod = loggerClass.getMethod("addAppender", appenderClass);
-
-                       Object rootLogger = getRootLoggerMethod.invoke(null, (Object[]) null);
-                       addAppenderMethod.invoke(rootLogger, log4jAppender);
-
-                       /*
-                        * We have checked for the log4j library version previously, none of
-                        * the following exceptions should happen.
-                        */
-               } catch (SecurityException e) {
-                       throw new IllegalStateException(e);
-               } catch (ClassNotFoundException e) {
-                       throw new IllegalStateException(e);
-               } catch (NoSuchMethodException e) {
-                       throw new IllegalStateException(e);
-               } catch (IllegalArgumentException e) {
-                       throw new IllegalStateException(e);
-               } catch (IllegalAccessException e) {
-                       throw new IllegalStateException(e);
-               } catch (InvocationTargetException e) {
-                       throw new IllegalStateException(e);
-               }
-       }
-
-       /**
-        * Check if log4j >= 1.2.15 library is present.
-        */
-       private static boolean testLog4jClasses() {
-               Class<?> loggingEventClass;
-
-               try {
-                       loggingEventClass = Class.forName("org.apache.log4j.spi.LoggingEvent");
-               } catch (ClassNotFoundException e) {
-                       /*
-                        * Log4j classes not found, no need to create the relevant objects
-                        */
-                       return false;
-               }
-
-               /*
-                * Detect capabilities of the log4j library. We only support log4j >=
-                * 1.2.15. The getTimeStamp() method was introduced in log4j 1.2.15, so
-                * verify that it is available.
-                *
-                * We can't rely on the getPackage().getImplementationVersion() call
-                * that would retrieves information from the manifest file found in the
-                * JAR since the manifest file shipped from upstream is known to be
-                * broken in several versions of the library.
-                *
-                * More info: https://issues.apache.org/bugzilla/show_bug.cgi?id=44370
-                */
-               try {
-                       loggingEventClass.getDeclaredMethod("getTimeStamp");
-               } catch (NoSuchMethodException e) {
-                       System.err.println(
-                                       "Warning: The loaded log4j library is too old. Log4j tracing with LTTng will be disabled.");
-                       return false;
-               } catch (SecurityException e) {
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * Detach the JUL handler from its logger and close it.
-        */
-       private void disposeJulHandler() {
-               if (julHandler == null) {
-                       /* The JUL handler was not activated, we have nothing to do */
-                       return;
-               }
-               Logger.getLogger("").removeHandler((Handler) julHandler);
-               julHandler.close();
-               julHandler = null;
-       }
-
-       /**
-        * Detach the log4j appender from its logger and close it.
-        */
-       private void disposeLog4jAppender() {
-               if (log4jAppender == null) {
-                       /* The log4j appender was not active, we have nothing to do */
-                       return;
-               }
-
-               /*
-                * Detach the appender from the log4j root logger. Again, we have to do
-                * this via reflection.
-                */
-               try {
-                       Class<?> loggerClass = Class.forName("org.apache.log4j.Logger");
-                       Class<?> appenderClass = Class.forName("org.apache.log4j.Appender");
-
-                       Method getRootLoggerMethod = loggerClass.getMethod("getRootLogger", (Class<?>[]) null);
-                       Method removeAppenderMethod = loggerClass.getMethod("removeAppender", appenderClass);
-
-                       Object rootLogger = getRootLoggerMethod.invoke(null, (Object[]) null);
-                       removeAppenderMethod.invoke(rootLogger, log4jAppender);
-
-                       /*
-                        * We were able to attach the appender previously, we should not
-                        * have problems here either!
-                        */
-               } catch (SecurityException e) {
-                       throw new IllegalStateException(e);
-               } catch (ClassNotFoundException e) {
-                       throw new IllegalStateException(e);
-               } catch (NoSuchMethodException e) {
-                       throw new IllegalStateException(e);
-               } catch (IllegalArgumentException e) {
-                       throw new IllegalStateException(e);
-               } catch (IllegalAccessException e) {
-                       throw new IllegalStateException(e);
-               } catch (InvocationTargetException e) {
-                       throw new IllegalStateException(e);
-               }
-
-               /* Close the appender */
-               log4jAppender.close();
-               log4jAppender = null;
-       }
-
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/ILttngTcpClientListener.java
deleted file mode 100644 (file)
index e6edb56..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.util.Collection;
-
-import org.lttng.ust.agent.session.EventRule;
-
-/**
- * TCP client listener interface.
- *
- * This interface contains callbacks that are called when the TCP client
- * receives commands from the session daemon. These callbacks will define what
- * do to with each command.
- *
- * @author Alexandre Montplaisir
- */
-public interface ILttngTcpClientListener {
-
-       /**
-        * Callback for the TCP client to notify the listener agent that a request
-        * for enabling an event rule was sent from the session daemon.
-        *
-        * @param eventRule
-        *            The event rule that was requested to be enabled
-        * @return Since we do not track individual sessions, right now this command
-        *         cannot fail. It will always return true.
-        */
-       boolean eventEnabled(EventRule eventRule);
-
-       /**
-        * Callback for the TCP client to notify the listener agent that a request
-        * for disabling an event was sent from the session daemon.
-        *
-        * @param eventName
-        *            The name of the event that was requested to be disabled.
-        * @return True if the command completed successfully, false if we should
-        *         report an error (event was not enabled, etc.)
-        */
-       boolean eventDisabled(String eventName);
-
-       /**
-        * Callback for the TCP client to notify the listener agent that a request
-        * for enabling an application-specific context was sent from the session
-        * daemon.
-        *
-        * @param contextRetrieverName
-        *            The name of the retriever in which the context is present.
-        *            This is used to namespace the contexts.
-        * @param contextName
-        *            The name of the context that was requested to be enabled
-        * @return Since we do not track individual sessions, right now this command
-        *         cannot fail. It will always return true.
-        */
-       boolean appContextEnabled(String contextRetrieverName, String contextName);
-
-       /**
-        * Callback for the TCP client to notify the listener agent that a request
-        * for disabling an application-specific context was sent from the session
-        * daemon.
-        *
-        * @param contextRetrieverName
-        *            The name of the retriever in which the context is present.
-        *            This is used to namespace the contexts.
-        * @param contextName
-        *            The name of the context that was requested to be disabled.
-        * @return True if the command completed successfully, false if we should
-        *         report an error (context was not previously enabled for example)
-        */
-       boolean appContextDisabled(String contextRetrieverName, String contextName);
-
-       /**
-        * List the events that are available in the agent's tracing domain.
-        *
-        * In Java terms, this means loggers that have at least one LTTng log
-        * handler of their corresponding domain attached.
-        *
-        * @return The list of available events
-        */
-       Collection<String> listAvailableEvents();
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngAgentResponse.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngAgentResponse.java
deleted file mode 100644 (file)
index 4ffeccd..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Interface for all response messages sent from the Java agent to the sessiond
- * daemon. Normally sent after a command coming from the session daemon was
- * executed.
- *
- * @author Alexandre Montplaisir
- */
-abstract class LttngAgentResponse {
-
-       private static final int INT_SIZE = 4;
-
-       public static final LttngAgentResponse SUCESS_RESPONSE = new LttngAgentResponse() {
-               @Override
-               public ReturnCode getReturnCode() {
-                       return ReturnCode.CODE_SUCCESS_CMD;
-               }
-       };
-
-       public static final LttngAgentResponse FAILURE_RESPONSE = new LttngAgentResponse() {
-               @Override
-               public ReturnCode getReturnCode() {
-                       return ReturnCode.CODE_INVALID_CMD;
-               }
-       };
-
-       /**
-        * Return codes used in agent responses, to indicate success or different
-        * types of failures of the commands.
-        */
-       protected enum ReturnCode {
-
-               CODE_SUCCESS_CMD(1, "sucess"),
-               CODE_INVALID_CMD(2, "invalid"),
-               CODE_UNKNOWN_LOGGER_NAME(3, "unknown logger name");
-
-               private final int code;
-               private final String toString;
-
-               private ReturnCode(int c, String str) {
-                       code = c;
-                       toString = str;
-               }
-
-               public int getCode() {
-                       return code;
-               }
-
-               /**
-                * Mainly used for debugging. The strings are not sent through the
-                * socket.
-                */
-               @Override
-               public String toString() {
-                       return toString;
-               }
-       }
-
-       /**
-        * Get the {@link ReturnCode} that goes with this response. It is expected
-        * by the session daemon, but some commands may require more than this
-        * in their response.
-        *
-        * @return The return code
-        */
-       public abstract ReturnCode getReturnCode();
-
-       /**
-        * Gets a byte array of the response so that it may be streamed.
-        *
-        * @return The byte array of the response
-        */
-       public byte[] getBytes() {
-               byte data[] = new byte[INT_SIZE];
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               buf.order(ByteOrder.BIG_ENDIAN);
-               buf.putInt(getReturnCode().getCode());
-               return data;
-       }
-
-       @Override
-       public String toString() {
-               return "LttngAgentResponse["
-                               + "code=" + getReturnCode().getCode()
-                               + ", " + getReturnCode().toString()
-                               + "]";
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/LttngTcpSessiondClient.java
deleted file mode 100644 (file)
index 9fa8c3a..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015-2016 EfficiOS Inc.
- * Copyright (C) 2015-2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.io.BufferedReader;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.Charset;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.lttng.ust.agent.utils.LttngUstAgentLogger;
-
-/**
- * Client for agents to connect to a local session daemon, using a TCP socket.
- *
- * @author David Goulet
- */
-public class LttngTcpSessiondClient implements Runnable {
-
-       private static final String SESSION_HOST = "127.0.0.1";
-       private static final String ROOT_PORT_FILE = "/var/run/lttng/agent.port";
-       private static final String USER_PORT_FILE = "/.lttng/agent.port";
-       private static final Charset PORT_FILE_ENCODING = Charset.forName("UTF-8");
-
-       private static final int PROTOCOL_MAJOR_VERSION = 2;
-       private static final int PROTOCOL_MINOR_VERSION = 0;
-
-       /** Command header from the session deamon. */
-       private final CountDownLatch registrationLatch = new CountDownLatch(1);
-
-       private Socket sessiondSock;
-       private volatile boolean quit = false;
-
-       private DataInputStream inFromSessiond;
-       private DataOutputStream outToSessiond;
-
-       private final ILttngTcpClientListener logAgent;
-       private final int domainValue;
-       private final boolean isRoot;
-
-       /**
-        * Constructor
-        *
-        * @param logAgent
-        *            The listener this client will operate on, typically an LTTng
-        *            agent.
-        * @param domainValue
-        *            The integer to send to the session daemon representing the
-        *            tracing domain to handle.
-        * @param isRoot
-        *            True if this client should connect to the root session daemon,
-        *            false if it should connect to the user one.
-        */
-       public LttngTcpSessiondClient(ILttngTcpClientListener logAgent, int domainValue, boolean isRoot) {
-               this.logAgent = logAgent;
-               this.domainValue = domainValue;
-               this.isRoot = isRoot;
-       }
-
-       /**
-        * Wait until this client has successfully established a connection to its
-        * target session daemon.
-        *
-        * @param seconds
-        *            A timeout in seconds after which this method will return
-        *            anyway.
-        * @return True if the the client actually established the connection, false
-        *         if we returned because the timeout has elapsed or the thread was
-        *         interrupted.
-        */
-       public boolean waitForConnection(int seconds) {
-               try {
-                       return registrationLatch.await(seconds, TimeUnit.SECONDS);
-               } catch (InterruptedException e) {
-                       return false;
-               }
-       }
-
-       @Override
-       public void run() {
-               for (;;) {
-                       if (this.quit) {
-                               break;
-                       }
-
-                       try {
-
-                               /*
-                                * Connect to the session daemon before anything else.
-                                */
-                               log("Connecting to sessiond");
-                               connectToSessiond();
-
-                               /*
-                                * Register to the session daemon as the Java component of the
-                                * UST application.
-                                */
-                               log("Registering to sessiond");
-                               registerToSessiond();
-
-                               /*
-                                * Block on socket receive and wait for command from the
-                                * session daemon. This will return if and only if there is a
-                                * fatal error or the socket closes.
-                                */
-                               log("Waiting on sessiond commands...");
-                               handleSessiondCmd();
-                       } catch (UnknownHostException uhe) {
-                               uhe.printStackTrace();
-                               /*
-                                * Terminate agent thread.
-                                */
-                               close();
-                       } catch (IOException ioe) {
-                               /*
-                                * I/O exception may have been triggered by a session daemon
-                                * closing the socket. Close our own socket and
-                                * retry connecting after a delay.
-                                */
-                               try {
-                                       if (this.sessiondSock != null) {
-                                               this.sessiondSock.close();
-                                       }
-                                       Thread.sleep(3000);
-                               } catch (InterruptedException e) {
-                                       /*
-                                        * Retry immediately if sleep is interrupted.
-                                        */
-                               } catch (IOException closeioe) {
-                                       closeioe.printStackTrace();
-                                       /*
-                                        * Terminate agent thread.
-                                        */
-                                       close();
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Dispose this client and close any socket connection it may hold.
-        */
-       public void close() {
-               log("Closing client");
-               this.quit = true;
-
-               try {
-                       if (this.sessiondSock != null) {
-                               this.sessiondSock.close();
-                       }
-               } catch (IOException e) {
-                       e.printStackTrace();
-               }
-       }
-
-       private void connectToSessiond() throws IOException {
-               int rootPort = getPortFromFile(ROOT_PORT_FILE);
-               int userPort = getPortFromFile(getHomePath() + USER_PORT_FILE);
-
-               /*
-                * Check for the edge case of both files existing but pointing to the
-                * same port. In this case, let the root client handle it.
-                */
-               if ((rootPort != 0) && (rootPort == userPort) && (!isRoot)) {
-                       log("User and root config files both point to port " + rootPort +
-                                       ". Letting the root client handle it.");
-                       throw new IOException();
-               }
-
-               int portToUse = (isRoot ? rootPort : userPort);
-
-               if (portToUse == 0) {
-                       /* No session daemon available. Stop and retry later. */
-                       throw new IOException();
-               }
-
-               this.sessiondSock = new Socket(SESSION_HOST, portToUse);
-               this.inFromSessiond = new DataInputStream(sessiondSock.getInputStream());
-               this.outToSessiond = new DataOutputStream(sessiondSock.getOutputStream());
-       }
-
-       private static String getHomePath() {
-               /*
-                * The environment variable LTTNG_HOME overrides HOME if
-                * defined.
-                */
-               String homePath = System.getenv("LTTNG_HOME");
-
-               if (homePath == null) {
-                       homePath = System.getProperty("user.home");
-               }
-               return homePath;
-       }
-
-       /**
-        * Read port number from file created by the session daemon.
-        *
-        * @return port value if found else 0.
-        */
-       private static int getPortFromFile(String path) throws IOException {
-               BufferedReader br = null;
-
-               try {
-                       br = new BufferedReader(new InputStreamReader(new FileInputStream(path), PORT_FILE_ENCODING));
-                       String line = br.readLine();
-                       if (line == null) {
-                               /* File exists but is empty. */
-                               return 0;
-                       }
-
-                       int port = Integer.parseInt(line, 10);
-                       if (port < 0 || port > 65535) {
-                               /* Invalid value. Ignore. */
-                               port = 0;
-                       }
-                       return port;
-
-               } catch (NumberFormatException e) {
-                       /* File contained something that was not a number. */
-                       return 0;
-               } catch (FileNotFoundException e) {
-                       /* No port available. */
-                       return 0;
-               } finally {
-                       if (br != null) {
-                               br.close();
-                       }
-               }
-       }
-
-       private void registerToSessiond() throws IOException {
-               byte data[] = new byte[16];
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
-
-               buf.putInt(domainValue);
-               buf.putInt(Integer.parseInt(pid));
-               buf.putInt(PROTOCOL_MAJOR_VERSION);
-               buf.putInt(PROTOCOL_MINOR_VERSION);
-               this.outToSessiond.write(data, 0, data.length);
-               this.outToSessiond.flush();
-       }
-
-       /**
-        * Handle session command from the session daemon.
-        */
-       private void handleSessiondCmd() throws IOException {
-               /* Data read from the socket */
-               byte inputData[] = null;
-               /* Reply data written to the socket, sent to the sessiond */
-               LttngAgentResponse response;
-
-               while (true) {
-                       /* Get header from session daemon. */
-                       SessiondCommandHeader cmdHeader = recvHeader();
-
-                       if (cmdHeader.getDataSize() > 0) {
-                               inputData = recvPayload(cmdHeader);
-                       }
-
-                       switch (cmdHeader.getCommandType()) {
-                       case CMD_REG_DONE:
-                       {
-                               /*
-                                * Countdown the registration latch, meaning registration is
-                                * done and we can proceed to continue tracing.
-                                */
-                               registrationLatch.countDown();
-                               /*
-                                * We don't send any reply to the registration done command.
-                                * This just marks the end of the initial session setup.
-                                */
-                               log("Registration done");
-                               continue;
-                       }
-                       case CMD_LIST:
-                       {
-                               SessiondCommand listLoggerCmd = new SessiondListLoggersCommand();
-                               response = listLoggerCmd.execute(logAgent);
-                               log("Received list loggers command");
-                               break;
-                       }
-                       case CMD_EVENT_ENABLE:
-                       {
-                               if (inputData == null) {
-                                       /* Invalid command */
-                                       response = LttngAgentResponse.FAILURE_RESPONSE;
-                                       break;
-                               }
-                               SessiondCommand enableEventCmd = new SessiondEnableEventCommand(inputData);
-                               response = enableEventCmd.execute(logAgent);
-                               log("Received enable event command: " + enableEventCmd.toString());
-                               break;
-                       }
-                       case CMD_EVENT_DISABLE:
-                       {
-                               if (inputData == null) {
-                                       /* Invalid command */
-                                       response = LttngAgentResponse.FAILURE_RESPONSE;
-                                       break;
-                               }
-                               SessiondCommand disableEventCmd = new SessiondDisableEventCommand(inputData);
-                               response = disableEventCmd.execute(logAgent);
-                               log("Received disable event command: " + disableEventCmd.toString());
-                               break;
-                       }
-                       case CMD_APP_CTX_ENABLE:
-                       {
-                               if (inputData == null) {
-                                       /* This commands expects a payload, invalid command */
-                                       response = LttngAgentResponse.FAILURE_RESPONSE;
-                                       break;
-                               }
-                               SessiondCommand enableAppCtxCmd = new SessiondEnableAppContextCommand(inputData);
-                               response = enableAppCtxCmd.execute(logAgent);
-                               log("Received enable app-context command");
-                               break;
-                       }
-                       case CMD_APP_CTX_DISABLE:
-                       {
-                               if (inputData == null) {
-                                       /* This commands expects a payload, invalid command */
-                                       response = LttngAgentResponse.FAILURE_RESPONSE;
-                                       break;
-                               }
-                               SessiondCommand disableAppCtxCmd = new SessiondDisableAppContextCommand(inputData);
-                               response = disableAppCtxCmd.execute(logAgent);
-                               log("Received disable app-context command");
-                               break;
-                       }
-                       default:
-                       {
-                               /* Unknown command, send empty reply */
-                               response = null;
-                               log("Received unknown command, ignoring");
-                               break;
-                       }
-                       }
-
-                       /* Send response to the session daemon. */
-                       byte[] responseData;
-                       if (response == null) {
-                               responseData = new byte[4];
-                               ByteBuffer buf = ByteBuffer.wrap(responseData);
-                               buf.order(ByteOrder.BIG_ENDIAN);
-                       } else {
-                               log("Sending response: " + response.toString());
-                               responseData = response.getBytes();
-                       }
-                       this.outToSessiond.write(responseData, 0, responseData.length);
-                       this.outToSessiond.flush();
-               }
-       }
-
-       /**
-        * Receive header data from the session daemon using the LTTng command
-        * static buffer of the right size.
-        */
-       private SessiondCommandHeader recvHeader() throws IOException {
-               byte data[] = new byte[SessiondCommandHeader.HEADER_SIZE];
-               int bytesLeft = data.length;
-               int bytesOffset = 0;
-
-               while (bytesLeft > 0) {
-                       int bytesRead = this.inFromSessiond.read(data, bytesOffset, bytesLeft);
-
-                       if (bytesRead < 0) {
-                               throw new IOException();
-                       }
-                       bytesLeft -= bytesRead;
-                       bytesOffset += bytesRead;
-               }
-               return new SessiondCommandHeader(data);
-       }
-
-       /**
-        * Receive payload from the session daemon. This MUST be done after a
-        * recvHeader() so the header value of a command are known.
-        *
-        * The caller SHOULD use isPayload() before which returns true if a payload
-        * is expected after the header.
-        */
-       private byte[] recvPayload(SessiondCommandHeader headerCmd) throws IOException {
-               byte payload[] = new byte[(int) headerCmd.getDataSize()];
-               int bytesLeft = payload.length;
-               int bytesOffset = 0;
-
-               /* Failsafe check so we don't waste our time reading 0 bytes. */
-               if (bytesLeft == 0) {
-                       return null;
-               }
-
-               while (bytesLeft > 0) {
-                       int bytesRead = inFromSessiond.read(payload, bytesOffset, bytesLeft);
-
-                       if (bytesRead < 0) {
-                               throw new IOException();
-                       }
-                       bytesLeft -= bytesRead;
-                       bytesOffset += bytesRead;
-               }
-               return payload;
-       }
-
-       /**
-        * Wrapper for this class's logging, adds the connection's characteristics
-        * to help differentiate between multiple TCP clients.
-        */
-       private void log(String message) {
-               LttngUstAgentLogger.log(getClass(),
-                               "(root=" + isRoot + ", domain=" + domainValue + ") " + message);
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommand.java
deleted file mode 100644 (file)
index 27aba23..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015-2016 EfficiOS Inc.
- * Copyright (C) 2015-2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Base class to represent all commands sent from the session daemon to the Java
- * agent. The agent is then expected to execute the command and provide a
- * response.
- *
- * @author Alexandre Montplaisir
- */
-abstract class SessiondCommand {
-
-       /**
-        * Encoding that should be used for the strings in the sessiond agent
-        * protocol on the socket.
-        */
-       protected static final Charset SESSIOND_PROTOCOL_CHARSET = Charset.forName("UTF-8");
-
-       enum CommandType {
-               /** List logger(s). */
-               CMD_LIST(1),
-               /** Enable logger by name. */
-               CMD_EVENT_ENABLE(2),
-               /** Disable logger by name. */
-               CMD_EVENT_DISABLE(3),
-               /** Registration done */
-               CMD_REG_DONE(4),
-               /** Enable application context */
-               CMD_APP_CTX_ENABLE(5),
-               /** Disable application context */
-               CMD_APP_CTX_DISABLE(6);
-
-               private int code;
-
-               private CommandType(int c) {
-                       code = c;
-               }
-
-               public int getCommandType() {
-                       return code;
-               }
-       }
-
-       /**
-        * Execute the command handler's action on the specified tracing agent.
-        *
-        * @param agent
-        *            The agent on which to execute the command
-        * @return If the command completed successfully or not
-        */
-       public abstract LttngAgentResponse execute(ILttngTcpClientListener agent);
-
-       /**
-        * Utility method to read agent-protocol strings passed on the socket. The
-        * buffer will contain a 32-bit integer representing the length, immediately
-        * followed by the string itself.
-        *
-        * @param buffer
-        *            The ByteBuffer from which to read. It should already be setup
-        *            and positioned where the read should begin.
-        * @return The string that was read, or <code>null</code> if it was badly
-        *         formatted.
-        */
-       protected static String readNextString(ByteBuffer buffer) {
-               int nbBytes = buffer.getInt();
-               if (nbBytes < 0) {
-                       /* The string length should be positive */
-                       return null;
-               }
-               if (nbBytes == 0) {
-                       /* The string is explicitly an empty string */
-                       return "";
-               }
-
-               byte[] stringBytes = new byte[nbBytes];
-               buffer.get(stringBytes);
-               return new String(stringBytes, SESSIOND_PROTOCOL_CHARSET).trim();
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondCommandHeader.java
deleted file mode 100644 (file)
index 845109d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.lttng.ust.agent.client.SessiondCommand.CommandType;
-
-/**
- * Header of session daemon commands.
- *
- * @author Alexandre Montplaisir
- * @author David Goulet
- */
-class SessiondCommandHeader {
-
-       /** ABI size of command header. */
-       public static final int HEADER_SIZE = 16;
-
-       /** Payload size in bytes following this header. */
-       private final long dataSize;
-
-       /** Command type. */
-       private final CommandType cmd;
-
-       public SessiondCommandHeader(byte[] data) {
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               buf.order(ByteOrder.BIG_ENDIAN);
-
-               dataSize = buf.getLong();
-               cmd = CommandType.values()[buf.getInt() - 1];
-               buf.getInt(); // command version, currently unused
-       }
-
-       public long getDataSize() {
-               return dataSize;
-       }
-
-       public CommandType getCommandType() {
-               return cmd;
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableAppContextCommand.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableAppContextCommand.java
deleted file mode 100644 (file)
index 4ac991a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Session daemon command indicating to the Java agent that an
- * application-specific context was disabled in the tracing session.
- *
- * @author Alexandre Montplaisir
- */
-class SessiondDisableAppContextCommand extends SessiondCommand {
-
-       private final String retrieverName;
-       private final String contextName;
-
-       private final boolean commandIsValid;
-
-       public SessiondDisableAppContextCommand(byte[] data) {
-               if (data == null) {
-                       throw new IllegalArgumentException();
-               }
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               buf.order(ByteOrder.BIG_ENDIAN);
-
-               /*
-                * The buffer contains the retriever name first, followed by the
-                * context's name.
-                */
-               retrieverName = readNextString(buf);
-               contextName = readNextString(buf);
-
-               /* If any of these strings were null then the command was invalid */
-               commandIsValid = ((retrieverName != null) && (contextName != null));
-       }
-
-       @Override
-       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
-               if (!commandIsValid) {
-                       return LttngAgentResponse.FAILURE_RESPONSE;
-               }
-
-               boolean success = agent.appContextDisabled(retrieverName, contextName);
-               return (success ? LttngAgentResponse.SUCESS_RESPONSE : DISABLE_APP_CONTEXT_FAILURE_RESPONSE);
-       }
-
-       /**
-        * Response sent when the disable-context command asks to disable an
-        * unknown context name.
-        */
-       private static final LttngAgentResponse DISABLE_APP_CONTEXT_FAILURE_RESPONSE = new LttngAgentResponse() {
-               @Override
-               public ReturnCode getReturnCode() {
-                       /* Same return code used for unknown event/logger names */
-                       return ReturnCode.CODE_UNKNOWN_LOGGER_NAME;
-               }
-       };
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondDisableEventCommand.java
deleted file mode 100644 (file)
index ff8eff3..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Session daemon command indicating to the Java agent that some events were
- * disabled in the tracing session.
- *
- * @author Alexandre Montplaisir
- * @author David Goulet
- */
-class SessiondDisableEventCommand extends SessiondCommand {
-
-       /**
-        * Response sent when the disable-event command asks to disable an
-        * unknown event.
-        */
-       private static final LttngAgentResponse DISABLE_EVENT_FAILURE_RESPONSE = new LttngAgentResponse() {
-               @Override
-               public ReturnCode getReturnCode() {
-                       return ReturnCode.CODE_UNKNOWN_LOGGER_NAME;
-               }
-       };
-
-       /** Event name to disable from the tracing session */
-       private final String eventName;
-
-       public SessiondDisableEventCommand(byte[] data) {
-               if (data == null) {
-                       throw new IllegalArgumentException();
-               }
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               buf.order(ByteOrder.BIG_ENDIAN);
-               eventName = new String(data, SESSIOND_PROTOCOL_CHARSET).trim();
-       }
-
-       @Override
-       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
-               boolean success = agent.eventDisabled(this.eventName);
-               return (success ? LttngAgentResponse.SUCESS_RESPONSE : DISABLE_EVENT_FAILURE_RESPONSE);
-       }
-
-       @Override
-       public String toString() {
-               return "SessiondDisableEventCommand["
-                               + "eventName=" + eventName
-                               +"]";
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableAppContextCommand.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableAppContextCommand.java
deleted file mode 100644 (file)
index d0be8cf..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Session daemon command indicating to the Java agent that an
- * application-specific context was enabled in the tracing session.
- *
- * @author Alexandre Montplaisir
- */
-class SessiondEnableAppContextCommand extends SessiondCommand {
-
-       private final String retrieverName;
-       private final String contextName;
-
-       private final boolean commandIsValid;
-
-       public SessiondEnableAppContextCommand(byte[] data) {
-               if (data == null) {
-                       throw new IllegalArgumentException();
-               }
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               buf.order(ByteOrder.BIG_ENDIAN);
-
-               /*
-                * The buffer contains the retriever name first, followed by the
-                * context's name.
-                */
-               retrieverName = readNextString(buf);
-               contextName = readNextString(buf);
-
-               /* If any of these strings were null then the command was invalid */
-               commandIsValid = ((retrieverName != null) && (contextName != null));
-       }
-
-       @Override
-       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
-               if (!commandIsValid) {
-                       return LttngAgentResponse.FAILURE_RESPONSE;
-               }
-
-               boolean success = agent.appContextEnabled(retrieverName, contextName);
-               return (success ? LttngAgentResponse.SUCESS_RESPONSE : LttngAgentResponse.FAILURE_RESPONSE);
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondEnableEventCommand.java
deleted file mode 100644 (file)
index 35029c9..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.lttng.ust.agent.session.EventRule;
-import org.lttng.ust.agent.session.LogLevelSelector;
-
-/**
- * Session daemon command indicating to the Java agent that some events were
- * enabled in the tracing session.
- *
- * @author Alexandre Montplaisir
- * @author David Goulet
- */
-class SessiondEnableEventCommand extends SessiondCommand {
-
-       /** Fixed event name length. Value defined by the lttng agent protocol. */
-       private static final int EVENT_NAME_LENGTH = 256;
-
-       private final boolean commandIsValid;
-
-       /* Parameters of the event rule being enabled */
-       private final String eventName;
-       private final LogLevelSelector logLevelFilter;
-       private final String filterString;
-
-       public SessiondEnableEventCommand(byte[] data) {
-               if (data == null) {
-                       throw new IllegalArgumentException();
-               }
-               ByteBuffer buf = ByteBuffer.wrap(data);
-               buf.order(ByteOrder.BIG_ENDIAN);
-               int logLevel = buf.getInt();
-               int logLevelType = buf.getInt();
-               logLevelFilter = new LogLevelSelector(logLevel, logLevelType);
-
-               /* Read the event name */
-               byte[] eventNameBytes = new byte[EVENT_NAME_LENGTH];
-               buf.get(eventNameBytes);
-               eventName = new String(eventNameBytes, SESSIOND_PROTOCOL_CHARSET).trim();
-
-               /* Read the filter string */
-               filterString = readNextString(buf);
-
-               /* The command was invalid if the string could not be read correctly */
-               commandIsValid = (filterString != null);
-       }
-
-       @Override
-       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
-               if (!commandIsValid) {
-                       return LttngAgentResponse.FAILURE_RESPONSE;
-               }
-
-               EventRule rule = new EventRule(eventName, logLevelFilter, filterString);
-               boolean success = agent.eventEnabled(rule);
-               return (success ? LttngAgentResponse.SUCESS_RESPONSE : LttngAgentResponse.FAILURE_RESPONSE);
-       }
-
-       @Override
-       public String toString() {
-               return "SessiondEnableEventCommand["
-                               + "eventName=" + eventName
-                               + ", logLevel=" + logLevelFilter.toString()
-                               + ", filterString=" + filterString
-                               +"]";
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/client/SessiondListLoggersCommand.java
deleted file mode 100644 (file)
index 0500055..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.client;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Collection;
-
-/**
- * Session daemon command asking the Java agent to list its registered loggers,
- * which corresponds to event names in the tracing session.
- *
- * @author Alexandre Montplaisir
- * @author David Goulet
- */
-class SessiondListLoggersCommand extends SessiondCommand {
-
-       @Override
-       public LttngAgentResponse execute(ILttngTcpClientListener agent) {
-               final Collection<String> loggerList = agent.listAvailableEvents();
-               return new SessiondListLoggersResponse(loggerList);
-       }
-
-       private static class SessiondListLoggersResponse extends LttngAgentResponse {
-
-               private final static int SIZE = 12;
-
-               private final Collection<String> loggers;
-
-               public SessiondListLoggersResponse(Collection<String> loggers) {
-                       this.loggers = loggers;
-               }
-
-               @Override
-               public ReturnCode getReturnCode() {
-                       /* This command can't really fail */
-                       return ReturnCode.CODE_SUCCESS_CMD;
-               }
-
-               @Override
-               public byte[] getBytes() {
-                       /*
-                        * Compute the data size, which is the number of bytes of each
-                        * encoded string, +1 per string for the \0
-                        */
-                       int dataSize = 0;
-                       for (String logger : loggers) {
-                               dataSize += logger.getBytes(SESSIOND_PROTOCOL_CHARSET).length + 1;
-                       }
-
-                       /* Prepare the buffer */
-                       byte data[] = new byte[SIZE + dataSize];
-                       ByteBuffer buf = ByteBuffer.wrap(data);
-                       buf.order(ByteOrder.BIG_ENDIAN);
-
-                       /* Write the header section of the response */
-                       buf.putInt(getReturnCode().getCode());
-                       buf.putInt(dataSize);
-                       buf.putInt(loggers.size());
-
-                       /* Write the payload */
-                       for (String logger : loggers) {
-                               buf.put(logger.getBytes(SESSIOND_PROTOCOL_CHARSET));
-                               /* NULL terminated byte after the logger name. */
-                               buf.put((byte) 0x0);
-                       }
-                       return data;
-               }
-       }
-
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoManager.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoManager.java
deleted file mode 100644 (file)
index 22efe02..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.context;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The singleton manager of {@link IContextInfoRetriever} objects.
- *
- * @author Alexandre Montplaisir
- */
-public final class ContextInfoManager {
-
-       private static final String SHARED_LIBRARY_NAME = "lttng-ust-context-jni";
-
-       private static final Pattern VALID_CONTEXT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_\\.]+$");
-
-       private static ContextInfoManager instance;
-
-       private final Map<String, IContextInfoRetriever> contextInfoRetrievers = new ConcurrentHashMap<String, IContextInfoRetriever>();
-       private final Map<String, Long> contextInforRetrieverRefs = new HashMap<String, Long>();
-
-       /**
-        * Lock used to keep the two maps above in sync when retrievers are
-        * registered or unregistered.
-        */
-       private final Object retrieverLock = new Object();
-
-       /** Singleton class, constructor should not be accessed directly */
-       private ContextInfoManager() {
-       }
-
-       /**
-        * Get the singleton instance.
-        *
-        * <p>
-        * Usage of this class requires the "liblttng-ust-context-jni.so" native
-        * library to be present on the system and available (passing
-        * -Djava.library.path=path to the JVM may be needed).
-        * </p>
-        *
-        * @return The singleton instance
-        * @throws IOException
-        *             If the shared library cannot be found.
-        * @throws SecurityException
-        *             We will forward any SecurityExcepion that may be thrown when
-        *             trying to load the JNI library.
-        */
-       public static synchronized ContextInfoManager getInstance() throws IOException, SecurityException {
-               if (instance == null) {
-                       try {
-                               System.loadLibrary(SHARED_LIBRARY_NAME);
-                       } catch (UnsatisfiedLinkError e) {
-                               throw new IOException(e);
-                       }
-                       instance = new ContextInfoManager();
-               }
-               return instance;
-       }
-
-       /**
-        * Register a new context info retriever.
-        *
-        * <p>
-        * Each context info retriever is registered with a given "retriever name",
-        * which specifies the namespace of the context elements. This name is
-        * specified separately from the retriever objects, which would allow
-        * register the same retriever under different namespaces for example.
-        * </p>
-        *
-        * <p>
-        * If the method returns false (indicating registration failure), then the
-        * retriever object will *not* be used for context information.
-        * </p>
-        *
-        * @param retrieverName
-        *            The name to register to the context retriever object with.
-        * @param contextInfoRetriever
-        *            The context info retriever to register
-        * @return True if the retriever was successfully registered, false if there
-        *         was an error, for example if a retriever is already registered
-        *         with that name.
-        */
-       public boolean registerContextInfoRetriever(String retrieverName, IContextInfoRetriever contextInfoRetriever) {
-               synchronized (retrieverLock) {
-                       if (!validateRetrieverName(retrieverName)) {
-                               return false;
-                       }
-
-                       if (contextInfoRetrievers.containsKey(retrieverName)) {
-                               /*
-                                * There is already a retriever registered with that name,
-                                * refuse the new registration.
-                                */
-                               return false;
-                       }
-                       /*
-                        * Inform LTTng-UST of the new retriever. The names have to start
-                        * with "$app." on the UST side!
-                        */
-                       long ref = LttngContextApi.registerProvider("$app." + retrieverName);
-                       if (ref == 0) {
-                               return false;
-                       }
-
-                       contextInfoRetrievers.put(retrieverName, contextInfoRetriever);
-                       contextInforRetrieverRefs.put(retrieverName, Long.valueOf(ref));
-
-                       return true;
-               }
-       }
-
-       /**
-        * Unregister a previously added context info retriever.
-        *
-        * This method has no effect if the retriever was not already registered.
-        *
-        * @param retrieverName
-        *            The context info retriever to unregister
-        * @return True if unregistration was successful, false if there was an
-        *         error
-        */
-       public boolean unregisterContextInfoRetriever(String retrieverName) {
-               synchronized (retrieverLock) {
-                       if (!contextInfoRetrievers.containsKey(retrieverName)) {
-                               /*
-                                * There was no retriever registered with that name.
-                                */
-                               return false;
-                       }
-                       contextInfoRetrievers.remove(retrieverName);
-                       long ref = contextInforRetrieverRefs.remove(retrieverName).longValue();
-
-                       /* Unregister the retriever on the UST side too */
-                       LttngContextApi.unregisterProvider(ref);
-
-                       return true;
-               }
-       }
-
-       /**
-        * Return the context info retriever object registered with the given name.
-        *
-        * @param retrieverName
-        *            The retriever name to look for
-        * @return The corresponding retriever object, or <code>null</code> if there
-        *         was none
-        */
-       public IContextInfoRetriever getContextInfoRetriever(String retrieverName) {
-               /*
-                * Note that this method does not take the retrieverLock, it lets
-                * concurrent threads access the ConcurrentHashMap directly.
-                *
-                * It's fine for a get() to happen during a registration or
-                * unregistration, it's first-come-first-serve.
-                */
-               return contextInfoRetrievers.get(retrieverName);
-       }
-
-       /**
-        * Validate that the given retriever name contains only the allowed
-        * characters, which are alphanumerical characters, period "." and
-        * underscore "_". The name must also not start with a number.
-        */
-       private static boolean validateRetrieverName(String contextName) {
-               if (contextName.isEmpty()) {
-                       return false;
-               }
-
-               /* First character must not be a number */
-               if (Character.isDigit(contextName.charAt(0))) {
-                       return false;
-               }
-
-               /* Validate the other characters of the string */
-               Matcher matcher = VALID_CONTEXT_NAME_PATTERN.matcher(contextName);
-               return matcher.matches();
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoSerializer.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/ContextInfoSerializer.java
deleted file mode 100644 (file)
index ae65060..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.context;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.Charset;
-import java.util.Collection;
-import java.util.Map;
-
-import org.lttng.ust.agent.utils.LttngUstAgentLogger;
-
-/**
- * This class is used to serialize the list of "context info" objects to pass
- * through JNI.
- *
- * The protocol expects two byte array parameters, which are contained here in
- * the {@link SerializedContexts} inner class.
- *
- * The first byte array is called the "entries array", and contains fixed-size
- * entries, one per context element.
- *
- * The second one is the "strings array", it is of variable length and used to
- * hold the variable-length strings. Each one of these strings is formatted as a
- * UTF-8 C-string, meaning in will end with a "\0" byte to indicate its end.
- * Entries in the first array may refer to offsets in the second array to point
- * to relevant strings.
- *
- * The fixed-size entries in the entries array contain the following elements
- * (size in bytes in parentheses):
- *
- * <ul>
- * <li>The offset in the strings array pointing to the full context name, like
- * "$app.myprovider:mycontext" (4)</li>
- * <li>The context value type (1)</li>
- * <li>The context value itself (8)</li>
- * </ul>
- *
- * The context value type will indicate how many bytes are used for the value.
- * If the it is of String type, then we use 4 bytes to represent the offset in
- * the strings array.
- *
- * So the total size of each entry is 13 bytes. All unused bytes (for context
- * values shorter than 8 bytes for example) will be zero'ed.
- *
- * @author Alexandre Montplaisir
- */
-public class ContextInfoSerializer {
-
-       private enum DataType {
-               NULL(0),
-               INTEGER(1),
-               LONG(2),
-               DOUBLE(3),
-               FLOAT(4),
-               BYTE(5),
-               SHORT(6),
-               BOOLEAN(7),
-               STRING(8);
-
-               private final byte value;
-
-               private DataType(int value) {
-                       this.value = (byte) value;
-               }
-
-               public byte getValue() {
-                       return value;
-               }
-       }
-
-       /**
-        * Class used to wrap the two byte arrays returned by
-        * {@link #queryAndSerializeRequestedContexts}.
-        */
-       public static class SerializedContexts {
-
-               private final byte[] contextEntries;
-               private final byte[] contextStrings;
-
-               /**
-                * Constructor
-                *
-                * @param entries
-                *            Arrays for the fixed-size context entries.
-                * @param strings
-                *            Arrays for variable-length strings
-                */
-               public SerializedContexts(byte[] entries, byte[] strings) {
-                       contextEntries = entries;
-                       contextStrings = strings;
-               }
-
-               /**
-                * @return The entries array
-                */
-               public byte[] getEntriesArray() {
-                       return contextEntries;
-               }
-
-               /**
-                * @return The strings array
-                */
-               public byte[] getStringsArray() {
-                       return contextStrings;
-               }
-       }
-
-       private static final String UST_APP_CTX_PREFIX = "$app.";
-       private static final int ENTRY_LENGTH = 13;
-       private static final ByteOrder NATIVE_ORDER = ByteOrder.nativeOrder();
-       private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
-       private static final SerializedContexts EMPTY_CONTEXTS = new SerializedContexts(new byte[0], new byte[0]);
-
-       /**
-        * From the list of requested contexts in the tracing session, look them up
-        * in the {@link ContextInfoManager}, retrieve the available ones, and
-        * serialize them into a byte array.
-        *
-        * @param enabledContexts
-        *            The contexts that are enabled in the tracing session (indexed
-        *            first by retriever name, then by index names). Should come
-        *            from the LTTng Agent.
-        * @return The byte array representing the intersection of the requested and
-        *         available contexts.
-        */
-       public static SerializedContexts queryAndSerializeRequestedContexts(Collection<Map.Entry<String, Map<String, Integer>>> enabledContexts) {
-               if (enabledContexts.isEmpty()) {
-                       /* Early return if there is no requested context information */
-                       return EMPTY_CONTEXTS;
-               }
-
-               ContextInfoManager contextManager;
-               try {
-                       contextManager = ContextInfoManager.getInstance();
-               } catch (IOException e) {
-                       /*
-                        * The JNI library is not available, do not send any context
-                        * information. No retriever could have been defined anyways.
-                        */
-                       return EMPTY_CONTEXTS;
-               }
-
-               /* Compute the total number of contexts (flatten the map) */
-               int totalArraySize = 0;
-               for (Map.Entry<String, Map<String, Integer>> contexts : enabledContexts) {
-                       totalArraySize += contexts.getValue().size() * ENTRY_LENGTH;
-               }
-
-               /* Prepare the ByteBuffer that will generate the "entries" array */
-               ByteBuffer entriesBuffer = ByteBuffer.allocate(totalArraySize);
-               entriesBuffer.order(NATIVE_ORDER);
-               entriesBuffer.clear();
-
-               /* Prepare the streams that will generate the "strings" array */
-               ByteArrayOutputStream stringsBaos = new ByteArrayOutputStream();
-               DataOutputStream stringsDos = new DataOutputStream(stringsBaos);
-
-               try {
-                       for (Map.Entry<String, Map<String, Integer>> entry : enabledContexts) {
-                               String requestedRetrieverName = entry.getKey();
-                               Map<String, Integer> requestedContexts = entry.getValue();
-
-                               IContextInfoRetriever retriever = contextManager.getContextInfoRetriever(requestedRetrieverName);
-
-                               for (String requestedContext : requestedContexts.keySet()) {
-                                       Object contextInfo;
-                                       if (retriever == null) {
-                                               contextInfo = null;
-                                       } else {
-                                               contextInfo = retriever.retrieveContextInfo(requestedContext);
-                                               /*
-                                                * 'contextInfo' can still be null here, which would
-                                                * indicate the retriever does not supply this context.
-                                                * We will still write this information so that the
-                                                * tracer can know about it.
-                                                */
-                                       }
-
-                                       /* Serialize the result to the buffers */
-                                       // FIXME Eventually pass the retriever name only once?
-                                       String fullContextName = (UST_APP_CTX_PREFIX + requestedRetrieverName + ':' + requestedContext);
-                                       byte[] strArray = fullContextName.getBytes(UTF8_CHARSET);
-
-                                       entriesBuffer.putInt(stringsDos.size());
-                                       stringsDos.write(strArray);
-                                       stringsDos.writeChar('\0');
-
-                                       LttngUstAgentLogger.log(ContextInfoSerializer.class,
-                                                       "ContextInfoSerializer: Context to be sent through JNI: " + fullContextName + '=' +
-                                                                       (contextInfo == null ? "null" : contextInfo.toString()));
-
-                                       serializeContextInfo(entriesBuffer, stringsDos, contextInfo);
-                               }
-                       }
-
-                       stringsDos.flush();
-                       stringsBaos.flush();
-
-               } catch (IOException e) {
-                       /*
-                        * Should not happen because we are wrapping a
-                        * ByteArrayOutputStream, which writes to memory
-                        */
-                       e.printStackTrace();
-               }
-
-               byte[] entriesArray = entriesBuffer.array();
-               byte[] stringsArray = stringsBaos.toByteArray();
-               return new SerializedContexts(entriesArray, stringsArray);
-       }
-
-       private static final int CONTEXT_VALUE_LENGTH = 8;
-
-       private static void serializeContextInfo(ByteBuffer entriesBuffer, DataOutputStream stringsDos, Object contextInfo) throws IOException {
-               int remainingBytes;
-               if (contextInfo == null) {
-                       entriesBuffer.put(DataType.NULL.getValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH;
-
-               } else if (contextInfo instanceof Integer) {
-                       entriesBuffer.put(DataType.INTEGER.getValue());
-                       entriesBuffer.putInt(((Integer) contextInfo).intValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 4;
-
-               } else if (contextInfo instanceof Long) {
-                       entriesBuffer.put(DataType.LONG.getValue());
-                       entriesBuffer.putLong(((Long) contextInfo).longValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 8;
-
-               } else if (contextInfo instanceof Double) {
-                       entriesBuffer.put(DataType.DOUBLE.getValue());
-                       entriesBuffer.putDouble(((Double) contextInfo).doubleValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 8;
-
-               } else if (contextInfo instanceof Float) {
-                       entriesBuffer.put(DataType.FLOAT.getValue());
-                       entriesBuffer.putFloat(((Float) contextInfo).floatValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 4;
-
-               } else if (contextInfo instanceof Byte) {
-                       entriesBuffer.put(DataType.BYTE.getValue());
-                       entriesBuffer.put(((Byte) contextInfo).byteValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 1;
-
-               } else if (contextInfo instanceof Short) {
-                       entriesBuffer.put(DataType.SHORT.getValue());
-                       entriesBuffer.putShort(((Short) contextInfo).shortValue());
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 2;
-
-               } else if (contextInfo instanceof Boolean) {
-                       entriesBuffer.put(DataType.BOOLEAN.getValue());
-                       boolean b = ((Boolean) contextInfo).booleanValue();
-                       /* Converted to one byte, write 1 for true, 0 for false */
-                       entriesBuffer.put((byte) (b ? 1 : 0));
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 1;
-
-               } else {
-                       /* Also includes the case of Character. */
-                       /*
-                        * We'll write the object as a string, into the strings array. We
-                        * will write the corresponding offset to the entries array.
-                        */
-                       String str = contextInfo.toString();
-                       byte[] strArray = str.getBytes(UTF8_CHARSET);
-
-                       entriesBuffer.put(DataType.STRING.getValue());
-
-                       entriesBuffer.putInt(stringsDos.size());
-                       stringsDos.write(strArray);
-                       stringsDos.writeChar('\0');
-
-                       remainingBytes = CONTEXT_VALUE_LENGTH - 4;
-               }
-               entriesBuffer.position(entriesBuffer.position() + remainingBytes);
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/IContextInfoRetriever.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/IContextInfoRetriever.java
deleted file mode 100644 (file)
index 235a30a..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.context;
-
-/**
- * Context-retrieving object specified by the application to extract
- * application-specific context information, which can then be passed on to the
- * Java agents and saved to a trace.
- *
- * Retriever objects should be registered to the {@link ContextInfoManager} to
- * make them available to the LTTng agents.
- *
- * @author Alexandre Montplaisir
- */
-public interface IContextInfoRetriever {
-
-       /**
-        * Retrieve a piece of context information from the application, identified
-        * by a key.
-        *
-        * @param key
-        *            The key identifying the context information
-        * @return The context information.
-        */
-       Object retrieveContextInfo(String key);
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/LttngContextApi.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/context/LttngContextApi.java
deleted file mode 100644 (file)
index a60d80e..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.context;
-
-/**
- * Virtual class containing the Java side of the LTTng-UST context provider
- * registering/unregistering methods.
- *
- * @author Alexandre Montplaisir
- */
-final class LttngContextApi {
-
-       private LttngContextApi() {}
-
-       /**
-        * Register a context provider to UST.
-        *
-        * The callbacks are the same for all providers, and are defined in the .c
-        * file. The only needed information is the retriever (which is called
-        * "provider" from UST'S point of view) name.
-        *
-        * @param provider_name
-        *            The name of the provider
-        * @return The pointer to the created provider object. It's useless in the
-        *         Java space, but will be needed for
-        *         {@link #unregisterProvider(long)}.
-        */
-       static native long registerProvider(String provider_name);
-
-       /**
-        * Unregister a previously-registered context provider from UST.
-        *
-        * @param provider_ref
-        *            The pointer to the provider object, obtained from
-        *            {@link #registerProvider}
-        */
-       static native void unregisterProvider(long provider_ref);
-}
-
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/FilterChangeNotifier.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/FilterChangeNotifier.java
deleted file mode 100644 (file)
index e1c96e1..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.filter;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.lttng.ust.agent.session.EventRule;
-
-/**
- * Singleton class managing the filter notifications.
- *
- * Applications can register a {@link IFilterChangeListener} to be notified when
- * event filtering rules change in the tracing sessions.
- *
- * @author Alexandre Montplaisir
- */
-public final class FilterChangeNotifier {
-
-       /** Lazy-loaded singleton instance object */
-       private static FilterChangeNotifier instance = null;
-
-       private final Map<EventRule, Integer> enabledEventRules = new HashMap<EventRule, Integer>();
-       private final Collection<IFilterChangeListener> registeredListeners = new LinkedList<IFilterChangeListener>();
-
-
-       /**
-        * Private constructor, singleton class should not be instantiated directly.
-        */
-       private FilterChangeNotifier() {
-       }
-
-       /**
-        * Get the singleton instance, initializing it if needed.
-        *
-        * @return The singleton instance
-        */
-       public static synchronized FilterChangeNotifier getInstance() {
-               if (instance == null) {
-                       instance = new FilterChangeNotifier();
-               }
-               return instance;
-       }
-
-       /**
-        * Notify the filter manager that a new rule was enabled in a tracing
-        * session ("lttng enable-event ...")
-        *
-        * This is meant to be called by the LTTng Agent only. External Java
-        * applications should not call this.
-        *
-        * @param rule
-        *            The rule that was added
-        */
-       public synchronized void addEventRule(EventRule rule) {
-               Integer count = enabledEventRules.get(rule);
-               if (count == null) {
-                       /*
-                        * This is the first instance of this rule being enabled. Add it to
-                        * the map and send notifications to the registered notifiers.
-                        */
-                       enabledEventRules.put(rule, Integer.valueOf(1));
-                       notifyForAddedRule(rule);
-                       return;
-               }
-               if (count.intValue() <= 0) {
-                       /* It should not have been in the map! */
-                       throw new IllegalStateException();
-               }
-               /*
-                * This exact event rule was already enabled, just increment its
-                * refcount without sending notifications
-                */
-               enabledEventRules.put(rule, Integer.valueOf(count.intValue() + 1));
-       }
-
-       /**
-        * Notify the filter manager that an event name was disabled in the tracing
-        * sessions ("lttng disable-event ...").
-        *
-        * The "disable-event" only specifies an event name. This means all the
-        * rules containing this event name are to be disabled.
-        *
-        * This is meant to be called by the LTTng Agent only. External Java
-        * applications should not call this.
-        *
-        * @param eventName
-        *            The event name to disable
-        */
-       public synchronized void removeEventRules(String eventName) {
-               List<EventRule> rulesToRemove = new LinkedList<EventRule>();
-
-               for (EventRule eventRule : enabledEventRules.keySet()) {
-                       if (eventRule.getEventName().equals(eventName)) {
-                               rulesToRemove.add(eventRule);
-                       }
-               }
-               /*
-                * We cannot modify the map while iterating on it. We have to do the
-                * removal separately from the iteration above.
-                */
-               for (EventRule rule : rulesToRemove) {
-                       removeEventRule(rule);
-               }
-       }
-
-       private synchronized void removeEventRule(EventRule eventRule) {
-               Integer count = enabledEventRules.get(eventRule);
-               if (count == null || count.intValue() <= 0) {
-                       /*
-                        * We were asked us to disable an event rule that was not enabled
-                        * previously. Command error?
-                        */
-                       throw new IllegalStateException();
-               }
-               if (count.intValue() == 1) {
-                       /*
-                        * This is the last instance of this event rule being disabled,
-                        * remove it from the map and send notifications of this rule being
-                        * gone.
-                        */
-                       enabledEventRules.remove(eventRule);
-                       notifyForRemovedRule(eventRule);
-                       return;
-               }
-               /*
-                * Other sessions/daemons are still looking for this event rule, simply
-                * decrement its refcount, and do not send notifications.
-                */
-               enabledEventRules.put(eventRule, Integer.valueOf(count.intValue() - 1));
-
-       }
-
-       /**
-        * Register a new listener to the manager.
-        *
-        * @param listener
-        *            The listener to add
-        */
-       public synchronized void registerListener(IFilterChangeListener listener) {
-               registeredListeners.add(listener);
-
-               /* Send the current rules to the new listener ("statedump") */
-               for (EventRule rule : enabledEventRules.keySet()) {
-                       listener.eventRuleAdded(rule);
-               }
-       }
-
-       /**
-        * Unregister a listener from the manager.
-        *
-        * @param listener
-        *            The listener to remove
-        */
-       public synchronized void unregisterListener(IFilterChangeListener listener) {
-               registeredListeners.remove(listener);
-       }
-
-       private void notifyForAddedRule(final EventRule rule) {
-               for (IFilterChangeListener notifier : registeredListeners) {
-                       notifier.eventRuleAdded(rule);
-               }
-       }
-
-       private void notifyForRemovedRule(final EventRule rule) {
-               for (IFilterChangeListener notifier : registeredListeners) {
-                       notifier.eventRuleRemoved(rule);
-               }
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/IFilterChangeListener.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/filter/IFilterChangeListener.java
deleted file mode 100644 (file)
index e222b22..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.filter;
-
-import org.lttng.ust.agent.session.EventRule;
-
-/**
- * Filter notification listener interface.
- * <p>
- * Applications wanting to be notified of event filtering rule changes should
- * implement this interface, then register their listener using
- * {@link FilterChangeNotifier#registerListener}.
- * </p>
- * <p>
- * The callbacks defined in this interface will be called whenever an event rule
- * is added or removed. The manager will take care of the reference-counting in
- * case multiple tracing sessions enable the exact same rules. For example, the
- * {@link #eventRuleRemoved} callback is only called when there are no more
- * session interested into it.
- * </p>
- * <p>
- * Do not forget to unregister the listener after use, using
- * {@link FilterChangeNotifier#unregisterListener}. If you do not, or if
- * you use an anonymous listener for example, these will remain attached until
- * the complete shutdown of the application.
- * </p>
- * <p>
- * Only one thread is used to dispatch notifications, sequentially. This means
- * that if a callback hangs it will prevent other listeners from receiving
- * notifications. Please take care of not blocking inside the listener
- * callbacks, and use separate threads for potentially long or blocking
- * operations.
- * </p>
- *
- * @author Alexandre Montplaisir
- */
-public interface IFilterChangeListener {
-
-       /**
-        * Notification that a new event rule is now enabled in the tracing
-        * sessions.
-        *
-        * @param rule
-        *            The event rule that was enabled
-        */
-       void eventRuleAdded(EventRule rule);
-
-       /**
-        * Notification that an existing event rule is now disabled in the tracing
-        * sessions.
-        *
-        * @param rule
-        *            The event rule that was disabled
-        */
-       void eventRuleRemoved(EventRule rule);
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/EventRule.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/EventRule.java
deleted file mode 100644 (file)
index dcf05a7..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.session;
-
-/**
- * Event filtering rule present in a tracing session.
- *
- * It typically comes from a "lttng enable-event" command, and contains a
- * domain, event name, log level and filter string.
- *
- * @author Alexandre Montplaisir
- */
-public class EventRule {
-
-       private final String eventName;
-       private final LogLevelSelector logLevelSelector;
-       private final String filterString;
-
-       /**
-        * Constructor.
-        *
-        * @param eventName
-        *            The name of the tracepoint
-        * @param logLevelSelector
-        *            The log level of the event rule
-        * @param filterString
-        *            The filtering string. May be null if there is no extra filter.
-        */
-       public EventRule(String eventName, LogLevelSelector logLevelSelector, String filterString) {
-               this.eventName = eventName;
-               this.logLevelSelector = logLevelSelector;
-               this.filterString = filterString;
-       }
-
-       /**
-        * Get the event name of this rule.
-        *
-        * @return The event name
-        */
-       public String getEventName() {
-               return eventName;
-       }
-
-       /**
-        * Get the log level filter configuration of the rule.
-        *
-        * @return The log level selector
-        */
-       public LogLevelSelector getLogLevelSelector() {
-               return logLevelSelector;
-       }
-
-       /**
-        * Get the filter string associated with this rule.
-        *
-        * @return The filter string, may be null for no filter string.
-        */
-       public String getFilterString() {
-               return filterString;
-       }
-
-       // ------------------------------------------------------------------------
-       // Methods from Object
-       // ------------------------------------------------------------------------
-
-       @Override
-       public int hashCode() {
-               final int prime = 31;
-               int result = 1;
-               result = prime * result + ((eventName == null) ? 0 : eventName.hashCode());
-               result = prime * result + ((filterString == null) ? 0 : filterString.hashCode());
-               result = prime * result + ((logLevelSelector == null) ? 0 : logLevelSelector.hashCode());
-               return result;
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (this == obj) {
-                       return true;
-               }
-               if (obj == null) {
-                       return false;
-               }
-               if (getClass() != obj.getClass()) {
-                       return false;
-               }
-               EventRule other = (EventRule) obj;
-
-               if (eventName == null) {
-                       if (other.eventName != null) {
-                               return false;
-                       }
-               } else if (!eventName.equals(other.eventName)) {
-                       return false;
-               }
-               /* else, continue */
-
-               if (filterString == null) {
-                       if (other.filterString != null) {
-                               return false;
-                       }
-               } else if (!filterString.equals(other.filterString)) {
-                       return false;
-               }
-               /* else, continue */
-
-               if (logLevelSelector == null) {
-                       if (other.logLevelSelector != null) {
-                               return false;
-                       }
-               } else if (!logLevelSelector.equals(other.logLevelSelector)) {
-                       return false;
-               }
-               /* else, continue */
-
-               return true;
-       }
-
-       @Override
-       public String toString() {
-               return "Event name = " + getEventName() +
-               ", Log level selector = (" + getLogLevelSelector().toString() + ")" +
-               ", Filter string = " + getFilterString();
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/LogLevelSelector.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/session/LogLevelSelector.java
deleted file mode 100644 (file)
index c25ec81..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.session;
-
-/**
- * Log level filtering element, which is part of an {@link EventRule}.
- *
- * @author Alexandre Montplaisir
- */
-public class LogLevelSelector {
-
-       /**
-        * The type of log level filter that is enabled.
-        *
-        * Defined from lttng-tools' include/lttng/event.h.
-        */
-       public enum LogLevelType {
-               /**
-                * All log levels are enabled. This overrides the value of
-                * {@link LogLevelSelector#getLogLevel}.
-                */
-               LTTNG_EVENT_LOGLEVEL_ALL(0),
-
-               /** This log level along with all log levels of higher severity are enabled. */
-               LTTNG_EVENT_LOGLEVEL_RANGE(1),
-
-               /** Only this exact log level is enabled. */
-               LTTNG_EVENT_LOGLEVEL_SINGLE(2);
-
-               private final int value;
-
-               private LogLevelType(int value) {
-                       this.value = value;
-               }
-
-               /**
-                * Get the numerical (int) value representing this log level type in the
-                * communication protocol.
-                *
-                * @return The int value
-                */
-               public int getValue() {
-                       return value;
-               }
-
-               static LogLevelType fromValue(int val) {
-                       switch (val) {
-                       case 0:
-                               return LTTNG_EVENT_LOGLEVEL_ALL;
-                       case 1:
-                               return LTTNG_EVENT_LOGLEVEL_RANGE;
-                       case 2:
-                               return LTTNG_EVENT_LOGLEVEL_SINGLE;
-                       default:
-                               throw new IllegalArgumentException();
-                       }
-               }
-       }
-
-       private final int logLevel;
-       private final LogLevelType logLevelType;
-
-       /**
-        * Constructor using numerical values straight from the communication
-        * protocol.
-        *
-        * @param logLevel
-        *            The numerical value of the log level. The exact value depends
-        *            on the tracing domain, see include/lttng/event.h in the
-        *            lttng-tools tree for the complete enumeration.
-        * @param logLevelType
-        *            The numerical value of the log level type. It will be
-        *            converted to a {@link LogLevelType} by this constructor.
-        * @throws IllegalArgumentException
-        *             If the 'logLevelType' does not correspond to a valid value.
-        */
-       public LogLevelSelector(int logLevel, int logLevelType) {
-               this.logLevel = logLevel;
-               this.logLevelType = LogLevelType.fromValue(logLevelType);
-       }
-
-       /**
-        * "Manual" constructor, specifying the {@link LogLevelType} directly.
-        *
-        * @param logLevel
-        *            The numerical value of the log level. The exact value depends
-        *            on the tracing domain, see include/lttng/event.h in the
-        *            lttng-tools tree for the complete enumeration.
-        * @param type
-        *            The log level filter type.
-        */
-       public LogLevelSelector(int logLevel, LogLevelType type) {
-               this.logLevel = logLevel;
-               this.logLevelType = type;
-       }
-
-       /**
-        * Get the numerical value of the log level element. Does not apply if
-        * {@link #getLogLevelType} returns
-        * {@link LogLevelType#LTTNG_EVENT_LOGLEVEL_ALL}.
-        *
-        * @return The numerical value of the log level
-        */
-       public int getLogLevel() {
-               return logLevel;
-       }
-
-       /**
-        * Get the log level filter type.
-        *
-        * @return The log level filter type
-        */
-       public LogLevelType getLogLevelType() {
-               return logLevelType;
-       }
-
-       /**
-        * Helper method to determine if an event with the given log level should be
-        * traced when considering this filter.
-        *
-        * For example, if this filter object represents "higher severity than 5",
-        * and the log level passed in parameter is "8", it will return that it
-        * matches (higher value means higher severity).
-        *
-        * @param targetLogLevel
-        *            The log level value of the event to check for
-        * @return Should this event be traced, or not
-        */
-       public boolean matches(int targetLogLevel) {
-               switch (logLevelType) {
-               case LTTNG_EVENT_LOGLEVEL_ALL:
-                       return true;
-               case LTTNG_EVENT_LOGLEVEL_RANGE:
-                       return (targetLogLevel >= logLevel);
-               case LTTNG_EVENT_LOGLEVEL_SINGLE:
-                       return (targetLogLevel == logLevel);
-               default:
-                       throw new IllegalStateException();
-               }
-       }
-
-       // ------------------------------------------------------------------------
-       // Methods from Object
-       // ------------------------------------------------------------------------
-
-       @Override
-       public int hashCode() {
-               final int prime = 31;
-               int result = 1;
-               result = prime * result + logLevel;
-               result = prime * result + ((logLevelType == null) ? 0 : logLevelType.hashCode());
-               return result;
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (this == obj) {
-                       return true;
-               }
-               if (obj == null) {
-                       return false;
-               }
-               if (getClass() != obj.getClass()) {
-                       return false;
-               }
-               LogLevelSelector other = (LogLevelSelector) obj;
-
-               if (logLevel != other.logLevel) {
-                       return false;
-               }
-               if (logLevelType != other.logLevelType) {
-                       return false;
-               }
-               return true;
-       }
-
-       @Override
-       public String toString() {
-               if (getLogLevelType() == LogLevelType.LTTNG_EVENT_LOGLEVEL_ALL) {
-                       return LogLevelType.LTTNG_EVENT_LOGLEVEL_ALL.toString();
-               }
-               return String.valueOf(getLogLevel()) + ", " + getLogLevelType().toString();
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/utils/LttngUstAgentLogger.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/utils/LttngUstAgentLogger.java
deleted file mode 100644 (file)
index 3e78553..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.utils;
-
-/**
- * Logging infrastructure for the lttng-ust Java agent. It prints log messages
- * to stderr but only when the environment variable LTTNG_UST_DEBUG is defined.
- *
- * @author Alexandre Montplaisir
- */
-public class LttngUstAgentLogger {
-
-       private static final String ENV_VAR_NAME = "LTTNG_UST_DEBUG";
-       private static final boolean LOGGING_ENABLED = (System.getenv(ENV_VAR_NAME) == null ? false : true);
-
-       /**
-        * Log event. Will be printed to stderr if the environment variable
-        * "LTTNG_UST_DEBUG" is defined.
-        *
-        * @param c
-        *            The class logging the message (should normally be called with
-        *            {@link #getClass()}).
-        * @param message
-        *            The message to print
-        */
-       public static void log(Class<?> c, String message) {
-               if (LOGGING_ENABLED) {
-                       System.err.println(c.getSimpleName() + ": " + message);
-               }
-       }
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile.am b/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Makefile.am
deleted file mode 100644 (file)
index 91ac203..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-JAVAROOT = .
-AM_JAVACFLAGS = -classpath $(CLASSPATH):$(builddir)/../lttng-ust-agent-common/lttng-ust-agent-common.jar
-
-pkgpath = org/lttng/ust/agent/jul
-
-jarfile_version = 1.0.0
-jarfile_manifest = $(srcdir)/Manifest.txt
-jarfile_symlink = lttng-ust-agent-jul.jar
-jarfile = lttng-ust-agent-jul-$(jarfile_version).jar
-
-jardir = $(datadir)/java
-
-juljniout = ../../jni/jul
-
-dist_noinst_JAVA = $(pkgpath)/LttngJulAgent.java \
-                                  $(pkgpath)/LttngJulApi.java \
-                                  $(pkgpath)/LttngLogHandler.java
-
-dist_noinst_DATA = $(jarfile_manifest)
-
-jar_DATA = $(jarfile)
-
-stamp = jul-jni-header.stamp
-classes = $(pkgpath)/*.class
-
-$(jarfile): classnoinst.stamp
-       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
-
-if !HAVE_JAVAH
-# If we don't have javah, assume we are running openjdk >= 10 and use javac
-# to generate the jni header file.
-AM_JAVACFLAGS += -h $(juljniout)
-else
-jul-jni-header.stamp: $(dist_noinst_JAVA)
-       $(JAVAH) -classpath $(CLASSPATH):$(srcdir) -d $(juljniout) $(JAVAHFLAGS) org.lttng.ust.agent.jul.LttngJulApi && \
-       echo "JUL JNI header generated" > jul-jni-header.stamp
-
-all-local: $(stamp)
-endif
-
-install-data-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink)
-
-uninstall-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
-
-CLEANFILES = *.jar \
-       $(pkgpath)/*.class \
-       jul-jni-header.stamp \
-       $(juljniout)/org_lttng_ust_agent_jul_LttngJulApi.h
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Manifest.txt b/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/Manifest.txt
deleted file mode 100644 (file)
index 4aba360..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Name: org/lttng/ust/agent/jul/
-Specification-Title: LTTng UST Java Agent JUL Integration
-Specification-Version: 1.0.0
-Specification-Vendor: LTTng Project
-Implementation-Title: org.lttng.ust.agent.jul
-Implementation-Version: 1.0.0
-Implementation-Vendor: LTTng Project
-Class-Path: lttng-ust-agent-common.jar
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulAgent.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulAgent.java
deleted file mode 100644 (file)
index 99c5fde..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.jul;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.logging.Handler;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-
-import org.lttng.ust.agent.AbstractLttngAgent;
-
-/**
- * Agent implementation for tracing from JUL loggers.
- *
- * @author Alexandre Montplaisir
- */
-class LttngJulAgent extends AbstractLttngAgent<LttngLogHandler> {
-
-       private static LttngJulAgent instance = null;
-
-       private LttngJulAgent() {
-               super(Domain.JUL);
-       }
-
-       public static synchronized LttngJulAgent getInstance() {
-               if (instance == null) {
-                       instance = new LttngJulAgent();
-               }
-               return instance;
-       }
-
-       @Override
-       public Collection<String> listAvailableEvents() {
-               Set<String> ret = new TreeSet<String>();
-
-               List<String> loggersNames = Collections.list(LogManager.getLogManager().getLoggerNames());
-               for (String name : loggersNames) {
-                       /*
-                        * Skip the root logger. An empty string is not a valid event name
-                        * in LTTng.
-                        */
-                       if (name.equals("") || name.equals("global")) {
-                               continue;
-                       }
-
-                       /*
-                        * Check if that logger has at least one LTTng JUL handler attached.
-                        */
-                       Logger logger = Logger.getLogger(name);
-                       if (hasLttngHandlerAttached(logger)) {
-                               ret.add(name);
-                       }
-               }
-
-               return ret;
-       }
-
-       private static boolean hasLttngHandlerAttached(Logger logger) {
-               for (Handler handler : logger.getHandlers()) {
-                       if (handler instanceof LttngLogHandler) {
-                               return true;
-                       }
-               }
-
-               /*
-                * A parent logger, if any, may be connected to an LTTng handler. In
-                * this case, we will want to include this child logger in the output,
-                * since it will be accessible by LTTng.
-                */
-               Logger parent = logger.getParent();
-               if (parent != null) {
-                       return hasLttngHandlerAttached(parent);
-               }
-
-               /*
-                * We have reached the root logger and have not found any LTTng handler,
-                * this event will not be accessible.
-                */
-               return false;
-       }
-
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulApi.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngJulApi.java
deleted file mode 100644 (file)
index 07b0cde..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.jul;
-
-/**
- * Virtual class containing the Java side of the LTTng-JUL JNI API methods.
- *
- * @author Alexandre Montplaisir
- */
-final class LttngJulApi {
-
-       private LttngJulApi() {}
-
-       static native void tracepoint(String msg,
-                       String logger_name,
-                       String class_name,
-                       String method_name,
-                       long millis,
-                       int log_level,
-                       int thread_id);
-
-       static native void tracepointWithContext(String msg,
-                       String logger_name,
-                       String class_name,
-                       String method_name,
-                       long millis,
-                       int log_level,
-                       int thread_id,
-                       byte[] contextEntries,
-                       byte[] contextStrings);
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngLogHandler.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-jul/org/lttng/ust/agent/jul/LttngLogHandler.java
deleted file mode 100644 (file)
index 42bea9c..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
- */
-
-package org.lttng.ust.agent.jul;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.logging.Formatter;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
-
-import org.lttng.ust.agent.ILttngAgent;
-import org.lttng.ust.agent.ILttngHandler;
-import org.lttng.ust.agent.context.ContextInfoSerializer;
-
-/**
- * LTTng-UST JUL log handler.
- *
- * Applications can attach this handler to their
- * {@link java.util.logging.Logger} to have it generate UST events from logging
- * events received through the logger.
- *
- * It sends its events to UST via the JNI library "liblttng-ust-jul-jni.so".
- * Make sure this library is available before using this handler.
- *
- * @author Alexandre Montplaisir
- * @author David Goulet
- */
-public class LttngLogHandler extends Handler implements ILttngHandler {
-
-       private static final String SHARED_OBJECT_NAME = "lttng-ust-jul-jni";
-
-       /**
-        * Dummy Formatter object, so we can use its
-        * {@link Formatter#formatMessage(LogRecord)} method.
-        */
-       private static final Formatter FORMATTER = new Formatter() {
-               @Override
-               public String format(LogRecord record) {
-                       throw new UnsupportedOperationException();
-               }
-       };
-
-       private final ILttngAgent<LttngLogHandler> agent;
-
-       /** Number of events logged (really sent through JNI) by this handler */
-       private final AtomicLong eventCount = new AtomicLong(0);
-
-       /**
-        * Constructor
-        *
-        * @throws IOException
-        *             This handler requires the lttng-ust-jul-jni.so native
-        *             library, through which it will send the trace events. This
-        *             exception is throw is this library cannot be found.
-        * @throws SecurityException
-        *             We will forward any SecurityExcepion that may be thrown when
-        *             trying to load the JNI library.
-        */
-       public LttngLogHandler() throws IOException, SecurityException {
-               super();
-               /* Initialize LTTng UST tracer. */
-               try {
-                       System.loadLibrary(SHARED_OBJECT_NAME); //$NON-NLS-1$
-               } catch (UnsatisfiedLinkError e) {
-                       throw new IOException(e);
-               }
-
-               /** Register to the relevant agent */
-               agent = LttngJulAgent.getInstance();
-               agent.registerHandler(this);
-       }
-
-       @Override
-       public synchronized void close() {
-               agent.unregisterHandler(this);
-       }
-
-       /**
-        * Get the number of events logged by this handler so far. This means the
-        * number of events actually sent through JNI to UST.
-        *
-        * @return The number of events logged so far
-        */
-       @Override
-       public long getEventCount() {
-               return eventCount.get();
-       }
-
-       @Override
-       public void flush() {
-       }
-
-       @Override
-       public void publish(LogRecord record) {
-               /*
-                * Check if the current message should be logged, according to the UST
-                * session settings.
-                */
-               if (!agent.isEventEnabled(record.getLoggerName())) {
-                       return;
-               }
-
-               String formattedMessage = FORMATTER.formatMessage(record);
-
-               /* Retrieve all the requested context information we can find */
-               Collection<Entry<String, Map<String, Integer>>> enabledContexts = agent.getEnabledAppContexts();
-               ContextInfoSerializer.SerializedContexts contextInfo = ContextInfoSerializer.queryAndSerializeRequestedContexts(enabledContexts);
-
-               eventCount.incrementAndGet();
-
-               /*
-                * Specific tracepoint designed for JUL events. The source class of the
-                * caller is used for the event name, the raw message is taken, the
-                * loglevel of the record and the thread ID.
-                */
-               LttngJulApi.tracepointWithContext(formattedMessage,
-                               record.getLoggerName(),
-                               record.getSourceClassName(),
-                               record.getSourceMethodName(),
-                               record.getMillis(),
-                               record.getLevel().intValue(),
-                               record.getThreadID(),
-                               contextInfo.getEntriesArray(),
-                               contextInfo.getStringsArray());
-       }
-
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile.am b/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Makefile.am
deleted file mode 100644 (file)
index 009f141..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-JAVAROOT = .
-AM_JAVACFLAGS = -classpath $(CLASSPATH):$(builddir)/../lttng-ust-agent-common/lttng-ust-agent-common.jar
-
-pkgpath = org/lttng/ust/agent/log4j
-
-jarfile_version = 1.0.0
-jarfile_manifest = $(srcdir)/Manifest.txt
-jarfile_symlink = lttng-ust-agent-log4j.jar
-jarfile = lttng-ust-agent-log4j-$(jarfile_version).jar
-
-jardir = $(datadir)/java
-
-log4jjniout = ../../jni/log4j
-
-dist_noinst_JAVA = $(pkgpath)/LttngLog4jAgent.java \
-                                  $(pkgpath)/LttngLog4jApi.java \
-                                  $(pkgpath)/LttngLogAppender.java
-
-dist_noinst_DATA = $(jarfile_manifest)
-
-jar_DATA = $(jarfile)
-
-stamp = log4j-jni-header.stamp
-classes = $(pkgpath)/*.class
-
-$(jarfile): classnoinst.stamp
-       $(JAR) cfm $(JARFLAGS) $@ $(jarfile_manifest) $(classes) && rm -f $(jarfile_symlink) && $(LN_S) $@ $(jarfile_symlink)
-
-if !HAVE_JAVAH
-# If we don't have javah, assume we are running openjdk >= 10 and use javac
-# to generate the jni header file.
-AM_JAVACFLAGS += -h $(log4jjniout)
-else
-log4j-jni-header.stamp: $(dist_noinst_JAVA)
-       $(JAVAH) -classpath $(CLASSPATH):$(srcdir) -d $(log4jjniout) $(JAVAHFLAGS) org.lttng.ust.agent.log4j.LttngLog4jApi && \
-       echo "Log4j JNI header generated" > log4j-jni-header.stamp
-
-all-local: $(stamp)
-endif
-
-install-data-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink) && $(LN_S) $(jarfile) $(jarfile_symlink)
-
-uninstall-hook:
-       cd $(DESTDIR)/$(jardir) && rm -f $(jarfile_symlink)
-
-CLEANFILES = *.jar \
-       $(pkgpath)/*.class \
-       log4j-jni-header.stamp \
-       $(log4jjniout)/org_lttng_ust_agent_log4j_LttngLog4jApi.h
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Manifest.txt b/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/Manifest.txt
deleted file mode 100644 (file)
index d7b98f4..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Name: org/lttng/ust/agent/log4j/
-Specification-Title: LTTng UST Java Agent Log4J 1.x Integration
-Specification-Version: 1.0.0
-Specification-Vendor: LTTng Project
-Implementation-Title: org.lttng.ust.agent.log4j
-Implementation-Version: 1.0.0
-Implementation-Vendor: LTTng Project
-Class-Path: lttng-ust-agent-common.jar
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jAgent.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jAgent.java
deleted file mode 100644 (file)
index bb5deb3..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.log4j;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.log4j.Appender;
-import org.apache.log4j.Category;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.lttng.ust.agent.AbstractLttngAgent;
-
-/**
- * Agent implementation for using the Log4j logger, connecting to a root session
- * daemon.
- *
- * @author Alexandre Montplaisir
- */
-class LttngLog4jAgent extends AbstractLttngAgent<LttngLogAppender> {
-
-       private static LttngLog4jAgent instance = null;
-
-       private LttngLog4jAgent() {
-               super(Domain.LOG4J);
-       }
-
-       public static synchronized LttngLog4jAgent getInstance() {
-               if (instance == null) {
-                       instance = new LttngLog4jAgent();
-               }
-               return instance;
-       }
-
-       @Override
-       public Collection<String> listAvailableEvents() {
-               Set<String> ret = new TreeSet<String>();
-
-               @SuppressWarnings("unchecked")
-               List<Logger> loggers = Collections.list(LogManager.getCurrentLoggers());
-               for (Logger logger : loggers) {
-                       if (logger == null) {
-                               continue;
-                       }
-
-                       /*
-                        * Check if that logger has at least one LTTng log4j appender
-                        * attached.
-                        */
-                       if (hasLttngAppenderAttached(logger)) {
-                               ret.add(logger.getName());
-                       }
-               }
-
-               return ret;
-       }
-
-       private static boolean hasLttngAppenderAttached(Category logger) {
-               @SuppressWarnings("unchecked")
-               Enumeration<Appender> appenders = logger.getAllAppenders();
-               if (appenders != null) {
-                       for (Appender appender : Collections.list(appenders)) {
-                               if (appender instanceof LttngLogAppender) {
-                                       return true;
-                               }
-                       }
-               }
-
-               /*
-                * A parent logger, if any, may be connected to an LTTng handler. In
-                * this case, we will want to include this child logger in the output,
-                * since it will be accessible by LTTng.
-                */
-               Category parent = logger.getParent();
-               if (parent != null) {
-                       return hasLttngAppenderAttached(parent);
-               }
-
-               /*
-                * We have reached the root logger and have not found any LTTng handler,
-                * this event will not be accessible.
-                */
-               return false;
-       }
-
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jApi.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLog4jApi.java
deleted file mode 100644 (file)
index c3e76ee..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-package org.lttng.ust.agent.log4j;
-
-/**
- * Virtual class containing the Java side of the LTTng-log4j JNI API methods.
- *
- * @author Alexandre Montplaisir
- */
-final class LttngLog4jApi {
-
-       private LttngLog4jApi() {}
-
-       static native void tracepoint(String msg,
-                       String logger_name,
-                       String class_name,
-                       String method_name,
-                       String file_name,
-                       int line_number,
-                       long timestamp,
-                       int loglevel,
-                       String thread_name);
-
-       static native void tracepointWithContext(String msg,
-                       String logger_name,
-                       String class_name,
-                       String method_name,
-                       String file_name,
-                       int line_number,
-                       long timestamp,
-                       int loglevel,
-                       String thread_name,
-                       byte[] contextEntries,
-                       byte[] contextStrings);
-}
diff --git a/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLogAppender.java b/src/liblttng-ust-java-agent/java/lttng-ust-agent-log4j/org/lttng/ust/agent/log4j/LttngLogAppender.java
deleted file mode 100644 (file)
index c232fb8..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2015 EfficiOS Inc.
- * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2014 Christian Babeux <christian.babeux@efficios.com>
- */
-
-package org.lttng.ust.agent.log4j;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.log4j.AppenderSkeleton;
-import org.apache.log4j.spi.LoggingEvent;
-import org.lttng.ust.agent.ILttngAgent;
-import org.lttng.ust.agent.ILttngHandler;
-import org.lttng.ust.agent.context.ContextInfoSerializer;
-
-/**
- * LTTng-UST Log4j 1.x log handler.
- *
- * Applications can attach this appender to their
- * {@link org.apache.log4j.Logger} to have it generate UST events from logging
- * events received through the logger.
- *
- * It sends its events to UST via the JNI library "liblttng-ust-log4j-jni.so".
- * Make sure this library is available before using this appender.
- *
- * @author Alexandre Montplaisir
- * @author Christian Babeux
- */
-public class LttngLogAppender extends AppenderSkeleton implements ILttngHandler {
-
-       private static final String SHARED_OBJECT_NAME = "lttng-ust-log4j-jni";
-
-       private final AtomicLong eventCount = new AtomicLong(0);
-
-       private final ILttngAgent<LttngLogAppender> agent;
-
-
-       /**
-        * Constructor
-        *
-        * @throws IOException
-        *             This handler requires the lttng-ust-log4j-jni.so native
-        *             library, through which it will send the trace events. This
-        *             exception is throw is this library cannot be found.
-        * @throws SecurityException
-        *             We will forward any SecurityExcepion that may be thrown when
-        *             trying to load the JNI library.
-        */
-       public LttngLogAppender() throws IOException, SecurityException {
-               super();
-               /* Initialize LTTng UST tracer. */
-               try {
-                       System.loadLibrary(SHARED_OBJECT_NAME); // $NON-NLS-1$
-               } catch (UnsatisfiedLinkError e) {
-                       throw new IOException(e);
-               }
-
-               /** Register to the relevant agent */
-               agent = LttngLog4jAgent.getInstance();
-               agent.registerHandler(this);
-       }
-
-       @Override
-       public synchronized void close() {
-               agent.unregisterHandler(this);
-       }
-
-       /**
-        * Get the number of events logged by this handler so far. This means the
-        * number of events actually sent through JNI to UST.
-        *
-        * @return The number of events logged so far
-        */
-       @Override
-       public long getEventCount() {
-               return eventCount.get();
-       }
-
-       @Override
-       public boolean requiresLayout() {
-               return false;
-       }
-
-       @Override
-       protected void append(LoggingEvent event) {
-               /*
-                * Check if the current message should be logged, according to the UST
-                * session settings.
-                */
-               if (!agent.isEventEnabled(event.getLoggerName())) {
-                       return;
-               }
-
-               /*
-                * The line number returned from LocationInformation is a string. At
-                * least try to convert to a proper int.
-                */
-               int line;
-               try {
-                       String lineString = event.getLocationInformation().getLineNumber();
-                       line = Integer.parseInt(lineString);
-               } catch (NumberFormatException n) {
-                       line = -1;
-               }
-
-               /* Retrieve all the requested context information we can find */
-               Collection<Entry<String, Map<String, Integer>>> enabledContexts = agent.getEnabledAppContexts();
-               ContextInfoSerializer.SerializedContexts contextInfo = ContextInfoSerializer.queryAndSerializeRequestedContexts(enabledContexts);
-
-               eventCount.incrementAndGet();
-
-               LttngLog4jApi.tracepointWithContext(event.getRenderedMessage(),
-                               event.getLoggerName(),
-                               event.getLocationInformation().getClassName(),
-                               event.getLocationInformation().getMethodName(),
-                               event.getLocationInformation().getFileName(),
-                               line,
-                               event.getTimeStamp(),
-                               event.getLevel().toInt(),
-                               event.getThreadName(),
-                               contextInfo.getEntriesArray(),
-                               contextInfo.getStringsArray());
-       }
-
-}
diff --git a/src/liblttng-ust-java-agent/jni/Makefile.am b/src/liblttng-ust-java-agent/jni/Makefile.am
deleted file mode 100644 (file)
index 711fd47..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-SUBDIRS = common
-
-if ENABLE_JAVA_AGENT_WITH_JUL
-SUBDIRS += jul
-endif
-
-if ENABLE_JAVA_AGENT_WITH_LOG4J
-SUBDIRS += log4j
-endif
diff --git a/src/liblttng-ust-java-agent/jni/common/Makefile.am b/src/liblttng-ust-java-agent/jni/common/Makefile.am
deleted file mode 100644 (file)
index c066157..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
-
-lib_LTLIBRARIES = liblttng-ust-context-jni.la
-liblttng_ust_context_jni_la_SOURCES = lttng_ust_context.c lttng_ust_context.h
-
-nodist_liblttng_ust_context_jni_la_SOURCES = org_lttng_ust_agent_context_LttngContextApi.h
-
-liblttng_ust_context_jni_la_LIBADD = -lc \
-       $(top_builddir)/src/liblttng-ust/liblttng-ust.la
diff --git a/src/liblttng-ust-java-agent/jni/common/lttng_ust_context.c b/src/liblttng-ust-java-agent/jni/common/lttng_ust_context.c
deleted file mode 100644 (file)
index 8570b21..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#include "org_lttng_ust_agent_context_LttngContextApi.h"
-
-#include <string.h>
-#include <inttypes.h>
-#include <lttng/ust-events.h>
-#include <lttng/ringbuffer-context.h>
-#include <common/ust-context-provider.h>
-
-#include "common/macros.h"
-#include "lttng_ust_context.h"
-
-enum lttng_ust_jni_type {
-       JNI_TYPE_NULL = 0,
-       JNI_TYPE_INTEGER = 1,
-       JNI_TYPE_LONG = 2,
-       JNI_TYPE_DOUBLE = 3,
-       JNI_TYPE_FLOAT = 4,
-       JNI_TYPE_BYTE = 5,
-       JNI_TYPE_SHORT = 6,
-       JNI_TYPE_BOOLEAN = 7,
-       JNI_TYPE_STRING = 8,
-};
-
-struct lttng_ust_jni_ctx_entry {
-       int32_t context_name_offset;
-       char type;      /* enum lttng_ust_jni_type */
-       union {
-               int32_t _integer;
-               int64_t _long;
-               double _double;
-               float _float;
-               signed char _byte;
-               int16_t _short;
-               signed char _boolean;
-               int32_t _string_offset;
-       } value;
-} __attribute__((packed));
-
-struct lttng_ust_jni_provider {
-       struct lttng_ust_registered_context_provider *reg_provider;
-       char *name;
-       struct lttng_ust_context_provider provider;
-};
-
-/* TLS passing context info from JNI to callbacks. */
-__thread struct lttng_ust_jni_tls lttng_ust_context_info_tls;
-
-static const char *get_ctx_string_at_offset(int32_t offset)
-{
-       signed char *ctx_strings_array = lttng_ust_context_info_tls.ctx_strings;
-
-       if (offset < 0 || offset >= lttng_ust_context_info_tls.ctx_strings_len) {
-               return NULL;
-       }
-       return (const char *) (ctx_strings_array + offset);
-}
-
-static struct lttng_ust_jni_ctx_entry *lookup_ctx_by_name(const char *ctx_name)
-{
-       struct lttng_ust_jni_ctx_entry *ctx_entries_array = lttng_ust_context_info_tls.ctx_entries;
-       int i, len = lttng_ust_context_info_tls.ctx_entries_len / sizeof(struct lttng_ust_jni_ctx_entry);
-
-       for (i = 0; i < len; i++) {
-               int32_t offset = ctx_entries_array[i].context_name_offset;
-               const char *string = get_ctx_string_at_offset(offset);
-
-               if (string && strcmp(string, ctx_name) == 0) {
-                       return &ctx_entries_array[i];
-               }
-       }
-       return NULL;
-}
-
-static size_t get_size_cb(void *priv, size_t offset)
-{
-       struct lttng_ust_jni_ctx_entry *jctx;
-       size_t size = 0;
-       struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv;
-       const char *ctx_name = jni_provider->name;
-       enum lttng_ust_jni_type jni_type;
-
-       size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char));
-       size += sizeof(char);           /* tag */
-       jctx = lookup_ctx_by_name(ctx_name);
-       if (!jctx) {
-               jni_type = JNI_TYPE_NULL;
-       } else {
-               jni_type = jctx->type;
-       }
-       switch (jni_type) {
-       case JNI_TYPE_NULL:
-               break;
-       case JNI_TYPE_INTEGER:
-               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int32_t));
-               size += sizeof(int32_t);        /* variant */
-               break;
-       case JNI_TYPE_LONG:
-               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int64_t));
-               size += sizeof(int64_t);        /* variant */
-               break;
-       case JNI_TYPE_DOUBLE:
-               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(double));
-               size += sizeof(double);         /* variant */
-               break;
-       case JNI_TYPE_FLOAT:
-               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(float));
-               size += sizeof(float);          /* variant */
-               break;
-       case JNI_TYPE_SHORT:
-               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(int16_t));
-               size += sizeof(int16_t);        /* variant */
-               break;
-       case JNI_TYPE_BYTE:             /* Fall-through. */
-       case JNI_TYPE_BOOLEAN:
-               size += lttng_ust_lib_ring_buffer_align(offset, lttng_ust_rb_alignof(char));
-               size += sizeof(char);           /* variant */
-               break;
-       case JNI_TYPE_STRING:
-       {
-               /* The value is an offset, the string is in the "strings" array */
-               int32_t string_offset = jctx->value._string_offset;
-               const char *string = get_ctx_string_at_offset(string_offset);
-
-               if (string) {
-                       size += strlen(string) + 1;
-               }
-               break;
-       }
-       default:
-               abort();
-       }
-       return size;
-
-}
-
-static void record_cb(void *priv,
-                struct lttng_ust_lib_ring_buffer_ctx *ctx,
-                struct lttng_ust_channel_buffer *lttng_chan_buf)
-{
-       struct lttng_ust_jni_ctx_entry *jctx;
-       struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv;
-       const char *ctx_name = jni_provider->name;
-       enum lttng_ust_jni_type jni_type;
-       char sel_char;
-
-       jctx = lookup_ctx_by_name(ctx_name);
-       if (!jctx) {
-               jni_type = JNI_TYPE_NULL;
-       } else {
-               jni_type = jctx->type;
-       }
-
-       switch (jni_type) {
-       case JNI_TYPE_NULL:
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               break;
-       case JNI_TYPE_INTEGER:
-       {
-               int32_t v = jctx->value._integer;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_S32;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_LONG:
-       {
-               int64_t v = jctx->value._long;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_S64;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_DOUBLE:
-       {
-               double v = jctx->value._double;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_FLOAT:
-       {
-               float v = jctx->value._float;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_FLOAT;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_SHORT:
-       {
-               int16_t v = jctx->value._short;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_S16;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_BYTE:
-       {
-               char v = jctx->value._byte;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_S8;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_BOOLEAN:
-       {
-               char v = jctx->value._boolean;
-
-               sel_char = LTTNG_UST_DYNAMIC_TYPE_S8;
-               lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-               lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v), lttng_ust_rb_alignof(v));
-               break;
-       }
-       case JNI_TYPE_STRING:
-       {
-                       int32_t offset = jctx->value._string_offset;
-                       const char *str = get_ctx_string_at_offset(offset);
-
-                       if (str) {
-                               sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING;
-                       } else {
-                               sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE;
-                       }
-                       lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char), lttng_ust_rb_alignof(char));
-                       if (str) {
-                               lttng_chan_buf->ops->event_write(ctx, str, strlen(str) + 1, 1);
-                       }
-                       break;
-       }
-       default:
-               abort();
-       }
-}
-
-static void get_value_cb(void *priv, struct lttng_ust_ctx_value *value)
-{
-       struct lttng_ust_jni_provider *jni_provider = (struct lttng_ust_jni_provider *) priv;
-       struct lttng_ust_jni_ctx_entry *jctx;
-       const char *ctx_name = jni_provider->name;
-       enum lttng_ust_jni_type jni_type;
-
-       jctx = lookup_ctx_by_name(ctx_name);
-       if (!jctx) {
-               jni_type = JNI_TYPE_NULL;
-       } else {
-               jni_type = jctx->type;
-       }
-
-       switch (jni_type) {
-       case JNI_TYPE_NULL:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
-               break;
-       case JNI_TYPE_INTEGER:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
-               value->u.s64 = (int64_t) jctx->value._integer;
-               break;
-       case JNI_TYPE_LONG:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
-               value->u.s64 = jctx->value._long;
-               break;
-       case JNI_TYPE_DOUBLE:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
-               value->u.d = jctx->value._double;
-               break;
-       case JNI_TYPE_FLOAT:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_DOUBLE;
-               value->u.d = (double) jctx->value._float;
-               break;
-       case JNI_TYPE_SHORT:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
-               value->u.s64 = (int64_t) jctx->value._short;
-               break;
-       case JNI_TYPE_BYTE:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
-               value->u.s64 = (int64_t) jctx->value._byte;
-               break;
-       case JNI_TYPE_BOOLEAN:
-               value->sel = LTTNG_UST_DYNAMIC_TYPE_S64;
-               value->u.s64 = (int64_t) jctx->value._boolean;
-               break;
-       case JNI_TYPE_STRING:
-       {
-               int32_t offset = jctx->value._string_offset;
-               const char *str = get_ctx_string_at_offset(offset);
-
-               if (str) {
-                       value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING;
-                       value->u.str = str;
-               } else {
-                       value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE;
-               }
-               break;
-       }
-       default:
-               abort();
-       }
-}
-
-/*
- * Register a context provider to UST.
- *
- * Called from the Java side when an application registers a context retriever,
- * so we create and register a corresponding provider on the C side.
- */
-JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registerProvider(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring provider_name)
-{
-       jboolean iscopy;
-       const char *provider_name_jstr;
-       char *provider_name_cstr;
-       struct lttng_ust_context_provider *provider;
-       struct lttng_ust_jni_provider *jni_provider;
-       /*
-        * Note: a "jlong" is 8 bytes on all architectures, whereas a
-        * C "long" varies.
-        */
-       jlong provider_ref;
-
-       provider_name_jstr = (*env)->GetStringUTFChars(env, provider_name, &iscopy);
-       if (!provider_name_jstr) {
-               goto error_jstr;
-       }
-       /* Keep our own copy of the string so UST can use it. */
-       provider_name_cstr = strdup(provider_name_jstr);
-       (*env)->ReleaseStringUTFChars(env, provider_name, provider_name_jstr);
-       if (!provider_name_cstr) {
-               goto error_strdup;
-       }
-       jni_provider = zmalloc(sizeof(*jni_provider));
-       if (!jni_provider) {
-               goto error_provider;
-       }
-       provider = &jni_provider->provider;
-       provider->struct_size = sizeof(*provider);
-       jni_provider->name = provider_name_cstr;
-       provider->name = jni_provider->name;
-       provider->get_size = get_size_cb;
-       provider->record = record_cb;
-       provider->get_value = get_value_cb;
-       provider->priv = jni_provider;
-
-       jni_provider->reg_provider = lttng_ust_context_provider_register(provider);
-       if (!jni_provider->reg_provider) {
-               goto error_register;
-       }
-
-       provider_ref = (jlong) (long) jni_provider;
-       return provider_ref;
-
-       /* Error handling. */
-error_register:
-       free(jni_provider);
-error_provider:
-       free(provider_name_cstr);
-error_strdup:
-error_jstr:
-       return 0;
-}
-
-/*
- * Unregister a previously-registered context provider.
- *
- * Called from the Java side when an application unregisters a context retriever,
- * so we unregister and delete the corresponding provider on the C side.
- */
-JNIEXPORT void JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_unregisterProvider(JNIEnv *env __attribute__((unused)),
-                                               jobject jobj __attribute__((unused)),
-                                               jlong provider_ref)
-{
-       struct lttng_ust_jni_provider *jni_provider =
-                       (struct lttng_ust_jni_provider *) (unsigned long) provider_ref;
-
-       if (!jni_provider) {
-               return;
-       }
-
-       lttng_ust_context_provider_unregister(jni_provider->reg_provider);
-
-       free(jni_provider->name);
-       free(jni_provider);
-}
diff --git a/src/liblttng-ust-java-agent/jni/common/lttng_ust_context.h b/src/liblttng-ust-java-agent/jni/common/lttng_ust_context.h
deleted file mode 100644 (file)
index ab003c8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- */
-
-#ifndef LIBLTTNG_UST_JAVA_AGENT_JNI_COMMON_LTTNG_UST_CONTEXT_H_
-#define LIBLTTNG_UST_JAVA_AGENT_JNI_COMMON_LTTNG_UST_CONTEXT_H_
-
-struct lttng_ust_jni_ctx_entry;
-
-struct lttng_ust_jni_tls {
-       struct lttng_ust_jni_ctx_entry *ctx_entries;
-       int32_t ctx_entries_len;
-       signed char *ctx_strings;
-       int32_t ctx_strings_len;
-};
-
-extern __thread struct lttng_ust_jni_tls lttng_ust_context_info_tls;
-
-#endif /* LIBLTTNG_UST_JAVA_AGENT_JNI_COMMON_LTTNG_UST_CONTEXT_H_ */
diff --git a/src/liblttng-ust-java-agent/jni/jul/Makefile.am b/src/liblttng-ust-java-agent/jni/jul/Makefile.am
deleted file mode 100644 (file)
index 32089ae..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
-
-lib_LTLIBRARIES = liblttng-ust-jul-jni.la
-liblttng_ust_jul_jni_la_SOURCES = lttng_ust_jul.c \
-       lttng_ust_jul.h
-
-nodist_liblttng_ust_jul_jni_la_SOURCES = org_lttng_ust_agent_jul_LttngJulApi.h
-
-liblttng_ust_jul_jni_la_LIBADD = -lc \
-       $(top_builddir)/src/liblttng-ust/liblttng-ust.la \
-       $(top_builddir)/src/liblttng-ust-java-agent/jni/common/liblttng-ust-context-jni.la
diff --git a/src/liblttng-ust-java-agent/jni/jul/lttng_ust_jul.c b/src/liblttng-ust-java-agent/jni/jul/lttng_ust_jul.c
deleted file mode 100644 (file)
index afc9f11..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#define _LGPL_SOURCE
-#include "org_lttng_ust_agent_jul_LttngJulApi.h"
-
-#define TRACEPOINT_DEFINE
-#define TRACEPOINT_CREATE_PROBES
-#include "lttng_ust_jul.h"
-#include "../common/lttng_ust_context.h"
-
-/*
- * Deprecated function from before the context information was passed.
- */
-JNIEXPORT void JNICALL Java_org_lttng_ust_agent_jul_LttngJulApi_tracepoint(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring msg,
-                                               jstring logger_name,
-                                               jstring class_name,
-                                               jstring method_name,
-                                               jlong millis,
-                                               jint log_level,
-                                               jint thread_id)
-{
-       jboolean iscopy;
-       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
-       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
-       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
-       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
-
-       tracepoint(lttng_jul, event, msg_cstr, logger_name_cstr,
-                       class_name_cstr, method_name_cstr, millis, log_level, thread_id);
-
-       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
-       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
-}
-
-/*
- * Tracepoint used by Java applications using the JUL handler.
- */
-JNIEXPORT void JNICALL Java_org_lttng_ust_agent_jul_LttngJulApi_tracepointWithContext(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring msg,
-                                               jstring logger_name,
-                                               jstring class_name,
-                                               jstring method_name,
-                                               jlong millis,
-                                               jint log_level,
-                                               jint thread_id,
-                                               jbyteArray context_info_entries,
-                                               jbyteArray context_info_strings)
-{
-       jboolean iscopy;
-       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
-       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
-       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
-       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
-       signed char *context_info_entries_array;
-       signed char *context_info_strings_array;
-
-       /*
-        * Write these to the TLS variables, so that the UST callbacks in
-        * lttng_ust_context.c can access them.
-        */
-       context_info_entries_array = (*env)->GetByteArrayElements(env, context_info_entries, &iscopy);
-       lttng_ust_context_info_tls.ctx_entries = (struct lttng_ust_jni_ctx_entry *) context_info_entries_array;
-       lttng_ust_context_info_tls.ctx_entries_len = (*env)->GetArrayLength(env, context_info_entries);
-       context_info_strings_array = (*env)->GetByteArrayElements(env, context_info_strings, &iscopy);
-       lttng_ust_context_info_tls.ctx_strings = context_info_strings_array;
-       lttng_ust_context_info_tls.ctx_strings_len = (*env)->GetArrayLength(env, context_info_strings);
-
-       tracepoint(lttng_jul, event, msg_cstr, logger_name_cstr,
-                       class_name_cstr, method_name_cstr, millis, log_level, thread_id);
-
-       lttng_ust_context_info_tls.ctx_entries = NULL;
-       lttng_ust_context_info_tls.ctx_entries_len = 0;
-       lttng_ust_context_info_tls.ctx_strings = NULL;
-       lttng_ust_context_info_tls.ctx_strings_len = 0;
-       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
-       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
-       (*env)->ReleaseByteArrayElements(env, context_info_entries, context_info_entries_array, 0);
-       (*env)->ReleaseByteArrayElements(env, context_info_strings, context_info_strings_array, 0);
-}
diff --git a/src/liblttng-ust-java-agent/jni/jul/lttng_ust_jul.h b/src/liblttng-ust-java-agent/jni/jul/lttng_ust_jul.h
deleted file mode 100644 (file)
index 13003bf..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#undef TRACEPOINT_PROVIDER
-#define TRACEPOINT_PROVIDER lttng_jul
-
-#if !defined(_TRACEPOINT_LTTNG_UST_JUL_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
-#define _TRACEPOINT_LTTNG_UST_JUL_H
-
-#include <lttng/tracepoint.h>
-
-/*
- * Tracepoint used by Java applications using the JUL handler.
- */
-TRACEPOINT_EVENT(lttng_jul, event,
-       TP_ARGS(
-               const char *, msg,
-               const char *, logger_name,
-               const char *, class_name,
-               const char *, method_name,
-               long, millis,
-               int, log_level,
-               int, thread_id),
-       TP_FIELDS(
-               ctf_string(msg, msg)
-               ctf_string(logger_name, logger_name)
-               ctf_string(class_name, class_name)
-               ctf_string(method_name, method_name)
-               ctf_integer(long, long_millis, millis)
-               ctf_integer(int, int_loglevel, log_level)
-               ctf_integer(int, int_threadid, thread_id)
-       )
-)
-
-#endif /* _TRACEPOINT_LTTNG_UST_JUL_H */
-
-#undef TRACEPOINT_INCLUDE
-#define TRACEPOINT_INCLUDE "./lttng_ust_jul.h"
-
-/* This part must be outside protection */
-#include <lttng/tracepoint-event.h>
diff --git a/src/liblttng-ust-java-agent/jni/log4j/Makefile.am b/src/liblttng-ust-java-agent/jni/log4j/Makefile.am
deleted file mode 100644 (file)
index 383bb9c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
-
-lib_LTLIBRARIES = liblttng-ust-log4j-jni.la
-liblttng_ust_log4j_jni_la_SOURCES = lttng_ust_log4j.c \
-       lttng_ust_log4j.h
-
-nodist_liblttng_ust_log4j_jni_la_SOURCES = org_lttng_ust_agent_log4j_LttngLog4jApi.h
-
-liblttng_ust_log4j_jni_la_LIBADD = -lc \
-       $(top_builddir)/src/liblttng-ust/liblttng-ust.la \
-       $(top_builddir)/src/liblttng-ust-java-agent/jni/common/liblttng-ust-context-jni.la
diff --git a/src/liblttng-ust-java-agent/jni/log4j/lttng_ust_log4j.c b/src/liblttng-ust-java-agent/jni/log4j/lttng_ust_log4j.c
deleted file mode 100644 (file)
index e88235a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2016 EfficiOS Inc.
- * Copyright (C) 2016 Alexandre Montplaisir <alexmonthy@efficios.com>
- * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#define _LGPL_SOURCE
-#include "org_lttng_ust_agent_log4j_LttngLog4jApi.h"
-
-#define TRACEPOINT_DEFINE
-#define TRACEPOINT_CREATE_PROBES
-#include "lttng_ust_log4j.h"
-#include "../common/lttng_ust_context.h"
-
-/*
- * Deprecated function from before the context information was passed.
- */
-JNIEXPORT void JNICALL Java_org_lttng_ust_agent_log4j_LttngLog4jApi_tracepoint(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring msg,
-                                               jstring logger_name,
-                                               jstring class_name,
-                                               jstring method_name,
-                                               jstring file_name,
-                                               jint line_number,
-                                               jlong timestamp,
-                                               jint loglevel,
-                                               jstring thread_name)
-{
-       jboolean iscopy;
-       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
-       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
-       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
-       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
-       const char *file_name_cstr = (*env)->GetStringUTFChars(env, file_name, &iscopy);
-       const char *thread_name_cstr = (*env)->GetStringUTFChars(env, thread_name, &iscopy);
-
-       tracepoint(lttng_log4j, event, msg_cstr, logger_name_cstr,
-                  class_name_cstr, method_name_cstr, file_name_cstr,
-                  line_number, timestamp, loglevel, thread_name_cstr);
-
-       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
-       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, file_name, file_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, thread_name, thread_name_cstr);
-}
-
-/*
- * Tracepoint used by Java applications using the log4j handler.
- */
-JNIEXPORT void JNICALL Java_org_lttng_ust_agent_log4j_LttngLog4jApi_tracepointWithContext(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring msg,
-                                               jstring logger_name,
-                                               jstring class_name,
-                                               jstring method_name,
-                                               jstring file_name,
-                                               jint line_number,
-                                               jlong timestamp,
-                                               jint loglevel,
-                                               jstring thread_name,
-                                               jbyteArray context_info_entries,
-                                               jbyteArray context_info_strings)
-{
-       jboolean iscopy;
-       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
-       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
-       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
-       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
-       const char *file_name_cstr = (*env)->GetStringUTFChars(env, file_name, &iscopy);
-       const char *thread_name_cstr = (*env)->GetStringUTFChars(env, thread_name, &iscopy);
-       signed char *context_info_entries_array;
-       signed char *context_info_strings_array;
-
-       /*
-        * Write these to the TLS variables, so that the UST callbacks in
-        * lttng_ust_context.c can access them.
-        */
-       context_info_entries_array = (*env)->GetByteArrayElements(env, context_info_entries, &iscopy);
-       lttng_ust_context_info_tls.ctx_entries = (struct lttng_ust_jni_ctx_entry *) context_info_entries_array;
-       lttng_ust_context_info_tls.ctx_entries_len = (*env)->GetArrayLength(env, context_info_entries);
-       context_info_strings_array = (*env)->GetByteArrayElements(env, context_info_strings, &iscopy);
-       lttng_ust_context_info_tls.ctx_strings = context_info_strings_array;
-       lttng_ust_context_info_tls.ctx_strings_len = (*env)->GetArrayLength(env, context_info_strings);
-
-       tracepoint(lttng_log4j, event, msg_cstr, logger_name_cstr,
-                  class_name_cstr, method_name_cstr, file_name_cstr,
-                  line_number, timestamp, loglevel, thread_name_cstr);
-
-       lttng_ust_context_info_tls.ctx_entries = NULL;
-       lttng_ust_context_info_tls.ctx_entries_len = 0;
-       lttng_ust_context_info_tls.ctx_strings = NULL;
-       lttng_ust_context_info_tls.ctx_strings_len = 0;
-       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
-       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, file_name, file_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, thread_name, thread_name_cstr);
-       (*env)->ReleaseByteArrayElements(env, context_info_entries, context_info_entries_array, 0);
-       (*env)->ReleaseByteArrayElements(env, context_info_strings, context_info_strings_array, 0);
-}
diff --git a/src/liblttng-ust-java-agent/jni/log4j/lttng_ust_log4j.h b/src/liblttng-ust-java-agent/jni/log4j/lttng_ust_log4j.h
deleted file mode 100644 (file)
index c7d7d52..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#undef TRACEPOINT_PROVIDER
-#define TRACEPOINT_PROVIDER lttng_log4j
-
-#if !defined(_TRACEPOINT_LTTNG_UST_LOG4J_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
-#define _TRACEPOINT_LTTNG_UST_LOG4J_H
-
-#include <lttng/tracepoint.h>
-
-/*
- * Tracepoint used by Java applications using the log4j log appender.
- */
-TRACEPOINT_EVENT(lttng_log4j, event,
-       TP_ARGS(
-               const char *, msg,
-               const char *, logger_name,
-               const char *, class_name,
-               const char *, method_name,
-               const char *, file_name,
-               int, line_number,
-               long, timestamp,
-               int, log_level,
-               const char *, thread_name),
-       TP_FIELDS(
-               ctf_string(msg, msg)
-               ctf_string(logger_name, logger_name)
-               ctf_string(class_name, class_name)
-               ctf_string(method_name, method_name)
-               ctf_string(filename, file_name)
-               ctf_integer(int, line_number, line_number)
-               ctf_integer(long, timestamp, timestamp)
-               ctf_integer(int, int_loglevel, log_level)
-               ctf_string(thread_name, thread_name)
-       )
-)
-
-#endif /* _TRACEPOINT_LTTNG_UST_LOG4J_H */
-
-#undef TRACEPOINT_INCLUDE
-#define TRACEPOINT_INCLUDE "./lttng_ust_log4j.h"
-
-/* This part must be outside protection */
-#include <lttng/tracepoint-event.h>
diff --git a/src/liblttng-ust-java/.gitignore b/src/liblttng-ust-java/.gitignore
deleted file mode 100644 (file)
index e07ee50..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-org_lttng_ust_LTTngUst.h
-org/
-liblttng-ust-java.jar
diff --git a/src/liblttng-ust-java/LTTngUst.c b/src/liblttng-ust-java/LTTngUst.c
deleted file mode 100644 (file)
index f5e0c96..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#define _LGPL_SOURCE
-#include "org_lttng_ust_LTTngUst.h"
-
-#define TRACEPOINT_DEFINE
-#define TRACEPOINT_CREATE_PROBES
-#include "lttng_ust_java.h"
-
-JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointInt(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring ev_name,
-                                               jint payload)
-{
-       jboolean iscopy;
-       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
-
-       tracepoint(lttng_ust_java, int_event, ev_name_cstr, payload);
-
-       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
-}
-
-JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointIntInt(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring ev_name,
-                                               jint payload1,
-                                               jint payload2)
-{
-       jboolean iscopy;
-       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
-
-       tracepoint(lttng_ust_java, int_int_event, ev_name_cstr, payload1, payload2);
-
-       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
-}
-
-JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLong(JNIEnv *env,
-                                               jobject jobj  __attribute__((unused)),
-                                               jstring ev_name,
-                                               jlong payload)
-{
-       jboolean iscopy;
-       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
-
-       tracepoint(lttng_ust_java, long_event, ev_name_cstr, payload);
-
-       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
-}
-
-JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointLongLong(JNIEnv *env,
-                                               jobject jobj  __attribute__((unused)),
-                                               jstring ev_name,
-                                               jlong payload1,
-                                               jlong payload2)
-{
-       jboolean iscopy;
-       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
-
-       tracepoint(lttng_ust_java, long_long_event, ev_name_cstr, payload1, payload2);
-
-       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
-}
-
-JNIEXPORT void JNICALL Java_org_lttng_ust_LTTngUst_tracepointString(JNIEnv *env,
-                                               jobject jobj __attribute__((unused)),
-                                               jstring ev_name,
-                                               jstring payload)
-{
-       jboolean iscopy;
-       const char *ev_name_cstr = (*env)->GetStringUTFChars(env, ev_name, &iscopy);
-       const char *payload_cstr = (*env)->GetStringUTFChars(env, payload, &iscopy);
-
-       tracepoint(lttng_ust_java, string_event, ev_name_cstr, payload_cstr);
-
-       (*env)->ReleaseStringUTFChars(env, ev_name, ev_name_cstr);
-       (*env)->ReleaseStringUTFChars(env, payload, payload_cstr);
-}
-
diff --git a/src/liblttng-ust-java/Makefile.am b/src/liblttng-ust-java/Makefile.am
deleted file mode 100644 (file)
index 55252fb..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-only
-
-JAVAROOT = .
-jarfile = liblttng-ust-java.jar
-jardir = $(datadir)/java
-pkgpath = org/lttng/ust
-
-dist_noinst_JAVA = $(pkgpath)/LTTngUst.java
-jar_DATA = $(jarfile)
-BUILT_SOURCES = org_lttng_ust_LTTngUst.h
-
-AM_CPPFLAGS += -I$(builddir) -I$(srcdir) $(JNI_CPPFLAGS)
-lib_LTLIBRARIES = liblttng-ust-java.la
-liblttng_ust_java_la_SOURCES = LTTngUst.c lttng_ust_java.h
-nodist_liblttng_ust_java_la_SOURCES = org_lttng_ust_LTTngUst.h
-
-liblttng_ust_java_la_LIBADD = -lc \
-       $(top_builddir)/src/liblttng-ust/liblttng-ust.la
-
-$(jarfile): classnoinst.stamp
-       $(JAR) cf $(JARFLAGS) $@ $(pkgpath)/*.class
-
-if !HAVE_JAVAH
-# If we don't have javah, assume we are running openjdk >= 10 and use javac
-# to generate the jni header file.
-AM_JAVACFLAGS = -h .
-
-org_lttng_ust_LTTngUst.h: $(jarfile)
-else
-org_lttng_ust_LTTngUst.h: jni-header.stamp
-
-jni-header.stamp: $(dist_noinst_JAVA)
-       $(JAVAH) -classpath $(srcdir) $(JAVAHFLAGS) org.lttng.ust.LTTngUst && \
-       echo "JNI header generated" > jni-header.stamp
-endif
-
-all-local: org_lttng_ust_LTTngUst.h
-
-EXTRA_DIST = README
-
-CLEANFILES = $(jarfile) $(pkgpath)/*.class jni-header.stamp org_lttng_ust_LTTngUst.h
diff --git a/src/liblttng-ust-java/README b/src/liblttng-ust-java/README
deleted file mode 100644 (file)
index d2ca478..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-This directory contains a simple API for instrumenting java applications.
-
-Configuration examples to build this library:
-
-dependency: openjdk-7-jdk
-./configure --enable-jni-interface
-
-Note that the OpenJDK 7 is used for development and continuous integration thus
-we directly support that version for this library. However, it has been tested
-with OpenJDK 6 also. Please let us know if other Java version (commercial or
-not) work with this library.
-
-After building, you can use the liblttng-ust-java.jar file in a Java project.
-It requires the liblttng-ust-java.so* files (which get installed when doing
-`make install') so make sure those are in the linker's library path.
diff --git a/src/liblttng-ust-java/lttng_ust_java.h b/src/liblttng-ust-java/lttng_ust_java.h
deleted file mode 100644 (file)
index ea515a8..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2011  Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- */
-
-#undef TRACEPOINT_PROVIDER
-#define TRACEPOINT_PROVIDER lttng_ust_java
-
-#if !defined(_TRACEPOINT_LTTNG_UST_JAVA_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
-#define _TRACEPOINT_LTTNG_UST_JAVA_H
-
-#include <lttng/tracepoint.h>
-
-TRACEPOINT_EVENT(lttng_ust_java, int_event,
-       TP_ARGS(const char *, name, int, payload),
-       TP_FIELDS(
-               ctf_string(name, name)
-               ctf_integer(int, int_payload, payload)
-       )
-)
-
-TRACEPOINT_EVENT(lttng_ust_java, int_int_event,
-       TP_ARGS(const char *, name, int, payload1, int, payload2),
-       TP_FIELDS(
-               ctf_string(name, name)
-               ctf_integer(int, int_payload1, payload1)
-               ctf_integer(int, int_payload2, payload2)
-       )
-)
-
-TRACEPOINT_EVENT(lttng_ust_java, long_event,
-       TP_ARGS(const char *, name, long, payload),
-       TP_FIELDS(
-               ctf_string(name, name)
-               ctf_integer(long, long_payload, payload)
-       )
-)
-
-TRACEPOINT_EVENT(lttng_ust_java, long_long_event,
-       TP_ARGS(const char *, name, long, payload1, long, payload2),
-       TP_FIELDS(
-               ctf_string(name, name)
-               ctf_integer(long, long_payload1, payload1)
-               ctf_integer(long, long_payload2, payload2)
-       )
-)
-
-TRACEPOINT_EVENT(lttng_ust_java, string_event,
-       TP_ARGS(const char *, name, const char *, payload),
-       TP_FIELDS(
-               ctf_string(name, name)
-               ctf_string(string_payload, payload)
-       )
-)
-
-#endif /* _TRACEPOINT_LTTNG_UST_JAVA_H */
-
-#undef TRACEPOINT_INCLUDE
-#define TRACEPOINT_INCLUDE "./lttng_ust_java.h"
-
-/* This part must be outside protection */
-#include <lttng/tracepoint-event.h>
diff --git a/src/liblttng-ust-java/org/lttng/ust/LTTngUst.java b/src/liblttng-ust-java/org/lttng/ust/LTTngUst.java
deleted file mode 100644 (file)
index cc14a72..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * Copyright (C) 2012 Alexandre Montplaisir <alexandre.montplaisir@polymtl.ca>
- */
-
-package org.lttng.ust;
-
-/**
- * This class implements the the Java side of the LTTng-UST Java interface.
- *
- * First, make sure you have installed "liblttng-ust-java.so" where the linker
- * can find it. You can then call LTTngUst.init() from your Java program to
- * connect the methods exposed here to the native library.
- *
- * Because of limitations in the probe declaration, all trace events generated
- * by this library will have "lttng_ust_java" for domain, and "<type>_event" for
- * event name in the CTF trace files. The "name" parameter will instead appear
- * as the first element of the event's payload.
- *
- * @author Mathieu Desnoyers
- * @author Alexandre Montplaisir
- *
- */
-public abstract class LTTngUst {
-
-    /**
-     * Initialize the UST tracer. This should always be called first, before any
-     * tracepoint* method.
-     */
-    public static void init() {
-        System.loadLibrary("lttng-ust-java"); //$NON-NLS-1$
-    }
-
-    /**
-     * Insert a tracepoint with a payload of type Integer.
-     *
-     * @param name
-     *            The name assigned to this event. For best performance, this
-     *            should be a statically-defined String, or a literal.
-     * @param payload
-     *            The int payload
-     */
-    public static native void tracepointInt(String name, int payload);
-
-    /**
-     * Insert a tracepoint with a payload consisting of two integers.
-     *
-     * @param name
-     *            The name assigned to this event. For best performance, this
-     *            should be a statically-defined String, or a literal.
-     * @param payload1
-     *            The first int payload
-     * @param payload2
-     *            The second int payload
-     */
-    public static native void
-    tracepointIntInt(String name, int payload1, int payload2);
-
-    /**
-     * Insert a tracepoint with a payload of type Long
-     *
-     * @param name
-     *            The name assigned to this event. For best performance, this
-     *            should be a statically-defined String, or a literal.
-     * @param payload
-     *            The long payload
-     */
-    public static native void tracepointLong(String name, long payload);
-
-    /**
-     * Insert a tracepoint with a payload consisting of two longs.
-     *
-     * @param name
-     *            The name assigned to this event. For best performance, this
-     *            should be a statically-defined String, or a literal.
-     * @param payload1
-     *            The first long payload
-     * @param payload2
-     *            The second long payload
-     */
-    public static native void
-    tracepointLongLong(String name, long payload1, long payload2);
-
-    /**
-     * Insert a tracepoint with a String payload.
-     *
-     * @param name
-     *            The name assigned to this event. For best performance, this
-     *            should be a statically-defined String, or a literal.
-     * @param payload
-     *            The String payload
-     */
-    public static native void tracepointString(String name, String payload);
-
-}
-
This page took 0.250041 seconds and 4 git commands to generate.