Fix compilation warnings in the Java agent
[lttng-ust.git] / liblttng-ust-java-agent / java / org / lttng / ust / agent / LTTngAgent.java
CommitLineData
501f6777
CB
1/*
2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18package org.lttng.ust.agent;
19
501f6777 20import java.io.IOException;
57224e35 21import java.lang.reflect.InvocationTargetException;
501f6777
CB
22import java.util.concurrent.Semaphore;
23import java.util.concurrent.TimeUnit;
501f6777
CB
24
25public class LTTngAgent {
26 /* Domains */
27 static enum Domain {
28 JUL(3), LOG4J(4);
29 private int value;
30
31 private Domain(int value) {
32 this.value = value;
33 }
34
35 public int value() {
36 return value;
37 }
38 }
39
40 private static LogFramework julUser;
41 private static LogFramework julRoot;
42 private static LogFramework log4jUser;
43 private static LogFramework log4jRoot;
44
45 /* Sessiond clients */
46 private static LTTngTCPSessiondClient julUserClient;
47 private static LTTngTCPSessiondClient julRootClient;
48 private static LTTngTCPSessiondClient log4jUserClient;
49 private static LTTngTCPSessiondClient log4jRootClient;
50
51 private static Thread sessiondThreadJULUser;
52 private static Thread sessiondThreadJULRoot;
53 private static Thread sessiondThreadLog4jUser;
54 private static Thread sessiondThreadLog4jRoot;
55
56 private boolean useJUL = false;
57 private boolean useLog4j = false;
58
59 /* Singleton agent object */
60 private static LTTngAgent curAgent = null;
61
62 /* Indicate if this object has been initialized. */
63 private static boolean initialized = false;
64
65 private static Semaphore registerSem;
66 private final static int semTimeout = 3; /* Seconds */
67
68 /*
69 * Constructor is private. This is a singleton and a reference should be
70 * acquired using getLTTngAgent().
71 */
57224e35 72 private LTTngAgent() {
501f6777
CB
73 initAgentJULClasses();
74
75 /* Since Log4j is a 3rd party JAR, we need to check if we can load any of its classes */
76 Boolean log4jLoaded = loadLog4jClasses();
77 if (log4jLoaded) {
78 initAgentLog4jClasses();
79 }
80
57224e35 81 registerSem = new Semaphore(0, true);
501f6777
CB
82 }
83
57224e35 84 private static Boolean loadLog4jClasses() {
17be0b58
CB
85 Class<?> logging;
86
501f6777 87 try {
15c78a9e 88 logging = loadClass("org.apache.log4j.spi.LoggingEvent");
501f6777
CB
89 } catch (ClassNotFoundException e) {
90 /* Log4j classes not found, no need to create the relevant objects */
17be0b58
CB
91 return false;
92 }
93
94 /*
95 * Detect capabilities of the log4j library. We only
96 * support log4j >= 1.2.15. The getTimeStamp() method
97 * was introduced in log4j 1.2.15, so verify that it
98 * is available.
99 *
100 * We can't rely on the getPackage().getImplementationVersion()
101 * call that would retrieves information from the manifest file
102 * found in the JAR since the manifest file shipped
103 * from upstream is known to be broken in several
104 * versions of the library.
105 *
106 * More info:
107 * https://issues.apache.org/bugzilla/show_bug.cgi?id=44370
108 */
109
110 try {
111 logging.getDeclaredMethod("getTimeStamp");
112 } catch (NoSuchMethodException e) {
8b067666 113 System.err.println("Warning: The loaded log4j library is too old. Log4j tracing with LTTng will be disabled.");
17be0b58
CB
114 return false;
115 } catch (NullPointerException e) {
116 /* Should never happen */
117 return false;
118 } catch (SecurityException e) {
119 return false;
501f6777
CB
120 }
121
17be0b58 122 return true;
501f6777
CB
123 }
124
57224e35 125 private static Class<?> loadClass(String className) throws ClassNotFoundException {
15c78a9e
JG
126 ClassLoader loader;
127 Class<?> loadedClass;
128
129 try {
130 /* Try to load class using the current thread's context class loader */
131 loader = Thread.currentThread().getContextClassLoader();
132 loadedClass = loader.loadClass(className);
133 } catch (ClassNotFoundException e) {
134 /* Loading failed, try using the system class loader */
135 loader = ClassLoader.getSystemClassLoader();
136 loadedClass = loader.loadClass(className);
137 }
138
139 return loadedClass;
140 }
141
501f6777
CB
142 private void initAgentJULClasses() {
143 try {
15c78a9e 144 Class<?> lttngJUL = loadClass("org.lttng.ust.agent.jul.LTTngJUL");
57224e35
AM
145 julUser = (LogFramework)lttngJUL.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
146 julRoot = (LogFramework)lttngJUL.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
501f6777
CB
147 this.useJUL = true;
148 } catch (ClassNotFoundException e) {
149 /* LTTng JUL classes not found, no need to create the relevant objects */
150 this.useJUL = false;
151 } catch (InstantiationException e) {
152 this.useJUL = false;
153 } catch (NoSuchMethodException e) {
154 this.useJUL = false;
155 } catch (IllegalAccessException e) {
156 this.useJUL = false;
157 } catch (InvocationTargetException e) {
158 this.useJUL = false;
159 }
160 }
161
162 private void initAgentLog4jClasses() {
163 try {
15c78a9e 164 Class<?> lttngLog4j = loadClass("org.lttng.ust.agent.log4j.LTTngLog4j");
57224e35
AM
165 log4jUser = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(false);
166 log4jRoot = (LogFramework)lttngLog4j.getDeclaredConstructor(new Class[] {Boolean.class}).newInstance(true);
501f6777
CB
167 this.useLog4j = true;
168 } catch (ClassNotFoundException e) {
169 /* LTTng Log4j classes not found, no need to create the relevant objects */
170 this.useLog4j = false;
171 } catch (InstantiationException e) {
172 this.useLog4j = false;
173 } catch (NoSuchMethodException e) {
174 this.useLog4j = false;
175 } catch (IllegalAccessException e) {
176 this.useLog4j = false;
177 } catch (InvocationTargetException e) {
178 this.useLog4j = false;
179 }
180 }
181
182 /*
183 * Public getter to acquire a reference to this singleton object.
184 */
185 public static synchronized LTTngAgent getLTTngAgent() throws IOException {
186 if (curAgent == null) {
187 curAgent = new LTTngAgent();
188 curAgent.init();
189 }
190
191 return curAgent;
192 }
193
57224e35
AM
194 private synchronized void init() throws SecurityException {
195 if (initialized) {
501f6777
CB
196 return;
197 }
198
199 Integer numJULThreads = 0;
200 Integer numLog4jThreads = 0;
201
202 if (this.useJUL) {
203 numJULThreads = initJULClientThreads();
204 }
205
206 if (this.useLog4j) {
207 numLog4jThreads = initLog4jClientThreads();
208 }
209
210 Integer numThreads = numJULThreads + numLog4jThreads;
211
212 /* Wait for each registration to end. */
213 try {
57224e35 214 registerSem.tryAcquire(numThreads,
501f6777
CB
215 semTimeout,
216 TimeUnit.SECONDS);
217 } catch (InterruptedException e) {
218 e.printStackTrace();
219 }
220
57224e35 221 initialized = true;
501f6777
CB
222 }
223
57224e35 224 private synchronized static Integer initJULClientThreads() {
501f6777
CB
225 Integer numThreads = 2;
226
227 /* Handle user session daemon if any. */
57224e35
AM
228 julUserClient = new LTTngTCPSessiondClient(Domain.JUL,
229 julUser,
230 registerSem);
501f6777
CB
231
232 String userThreadName = "LTTng UST agent JUL user thread";
57224e35
AM
233 sessiondThreadJULUser = new Thread(julUserClient, userThreadName);
234 sessiondThreadJULUser.setDaemon(true);
235 sessiondThreadJULUser.start();
501f6777
CB
236
237 /* Handle root session daemon. */
57224e35
AM
238 julRootClient = new LTTngTCPSessiondClient(Domain.JUL,
239 julRoot,
240 registerSem);
501f6777
CB
241
242 String rootThreadName = "LTTng UST agent JUL root thread";
57224e35
AM
243 sessiondThreadJULRoot = new Thread(julRootClient, rootThreadName);
244 sessiondThreadJULRoot.setDaemon(true);
245 sessiondThreadJULRoot.start();
501f6777
CB
246
247 return numThreads;
248 }
249
57224e35 250 private synchronized static Integer initLog4jClientThreads() {
501f6777
CB
251 Integer numThreads = 2;
252
57224e35
AM
253 log4jUserClient = new LTTngTCPSessiondClient(Domain.LOG4J,
254 log4jUser,
255 registerSem);
501f6777
CB
256
257 String userThreadName = "LTTng UST agent Log4j user thread";
57224e35
AM
258 sessiondThreadLog4jUser = new Thread(log4jUserClient, userThreadName);
259 sessiondThreadLog4jUser.setDaemon(true);
260 sessiondThreadLog4jUser.start();
501f6777 261
57224e35
AM
262 log4jRootClient = new LTTngTCPSessiondClient(Domain.LOG4J,
263 log4jRoot,
264 registerSem);
501f6777
CB
265
266 String rootThreadName = "LTTng UST agent Log4j root thread";
57224e35
AM
267 sessiondThreadLog4jRoot = new Thread(log4jRootClient,rootThreadName);
268 sessiondThreadLog4jRoot.setDaemon(true);
269 sessiondThreadLog4jRoot.start();
501f6777
CB
270
271 return numThreads;
272 }
273
274
275 public void dispose() throws IOException {
276 if (this.useJUL) {
57224e35
AM
277 julUserClient.destroy();
278 julRootClient.destroy();
279 julUser.reset();
280 julRoot.reset();
501f6777
CB
281 }
282
283 if (this.useLog4j) {
57224e35
AM
284 log4jUserClient.destroy();
285 log4jRootClient.destroy();
286 log4jUser.reset();
287 log4jRoot.reset();
501f6777
CB
288 }
289
290 try {
291 if (this.useJUL) {
57224e35
AM
292 sessiondThreadJULUser.join();
293 sessiondThreadJULRoot.join();
501f6777
CB
294 }
295
296 if (this.useLog4j) {
57224e35
AM
297 sessiondThreadLog4jUser.join();
298 sessiondThreadLog4jRoot.join();
501f6777
CB
299 }
300
301 } catch (InterruptedException e) {
302 e.printStackTrace();
303 }
304 }
305}
This page took 0.038349 seconds and 4 git commands to generate.