1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.catalina.core;
19
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23
24 import org.apache.catalina.Lifecycle;
25 import org.apache.catalina.LifecycleEvent;
26 import org.apache.catalina.LifecycleListener;
27 import org.apache.catalina.util.StringManager;
28 import org.apache.juli.logging.Log;
29 import org.apache.juli.logging.LogFactory;
30 import org.apache.tomcat.jni.Library;
31
32
33
34 /**
35 * Implementation of <code>LifecycleListener</code> that will init and
36 * and destroy APR.
37 *
38 * @author Remy Maucherat
39 * @author Filip Hanik
40 * @version $Revision: 534930 $ $Date: 2007-05-03 18:43:35 +0200 (jeu., 03 mai 2007) $
41 * @since 4.1
42 */
43
44 public class AprLifecycleListener
45 implements LifecycleListener {
46
47 private static Log log = LogFactory.getLog(AprLifecycleListener.class);
48
49 /**
50 * The string manager for this package.
51 */
52 protected StringManager sm =
53 StringManager.getManager(Constants.Package);
54
55
56 // ---------------------------------------------- Constants
57
58
59 protected static final int TCN_REQUIRED_MAJOR = 1;
60 protected static final int TCN_REQUIRED_MINOR = 1;
61 protected static final int TCN_REQUIRED_PATCH = 8;
62 protected static final int TCN_RECOMMENDED_PV = 10;
63
64
65 // ---------------------------------------------- Properties
66 protected static String SSLEngine = "on"; //default on
67 protected static boolean sslInitialized = false;
68 protected static boolean aprInitialized = false;
69
70 // ---------------------------------------------- LifecycleListener Methods
71
72 /**
73 * Primary entry point for startup and shutdown events.
74 *
75 * @param event The event that has occurred
76 */
77 public void lifecycleEvent(LifecycleEvent event) {
78
79 if (Lifecycle.INIT_EVENT.equals(event.getType())) {
80 aprInitialized = init();
81 if (aprInitialized) {
82 try {
83 initializeSSL();
84 } catch (Throwable t) {
85 if (!log.isDebugEnabled()) {
86 log.info(sm.getString("aprListener.sslInit"));
87 } else {
88 log.debug(sm.getString("aprListener.sslInit"));
89 }
90 }
91 }
92 } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
93 if (!aprInitialized) {
94 return;
95 }
96 try {
97 terminateAPR();
98 } catch (Throwable t) {
99 if (!log.isDebugEnabled()) {
100 log.info(sm.getString("aprListener.aprDestroy"));
101 } else {
102 log.debug(sm.getString("aprListener.aprDestroy"), t);
103 }
104 }
105 }
106
107 }
108
109 private static synchronized void terminateAPR()
110 throws ClassNotFoundException, NoSuchMethodException,
111 IllegalAccessException, InvocationTargetException
112 {
113 String methodName = "terminate";
114 Method method = Class.forName("org.apache.tomcat.jni.Library")
115 .getMethod(methodName, (Class [])null);
116 method.invoke(null, (Object []) null);
117 }
118
119 private boolean init()
120 {
121 int major = 0;
122 int minor = 0;
123 int patch = 0;
124 if (aprInitialized) {
125 return true;
126 }
127 try {
128 String methodName = "initialize";
129 Class paramTypes[] = new Class[1];
130 paramTypes[0] = String.class;
131 Object paramValues[] = new Object[1];
132 paramValues[0] = null;
133 Class clazz = Class.forName("org.apache.tomcat.jni.Library");
134 Method method = clazz.getMethod(methodName, paramTypes);
135 method.invoke(null, paramValues);
136 major = clazz.getField("TCN_MAJOR_VERSION").getInt(null);
137 minor = clazz.getField("TCN_MINOR_VERSION").getInt(null);
138 patch = clazz.getField("TCN_PATCH_VERSION").getInt(null);
139 } catch (Throwable t) {
140 if (!log.isDebugEnabled()) {
141 log.info(sm.getString("aprListener.aprInit",
142 System.getProperty("java.library.path")));
143 } else {
144 log.debug(sm.getString("aprListener.aprInit",
145 System.getProperty("java.library.path")), t);
146 }
147 return false;
148 }
149 if ((major != TCN_REQUIRED_MAJOR) ||
150 (minor != TCN_REQUIRED_MINOR) ||
151 (patch < TCN_REQUIRED_PATCH)) {
152 log.error(sm.getString("aprListener.tcnInvalid", major + "."
153 + minor + "." + patch,
154 TCN_REQUIRED_MAJOR + "." +
155 TCN_REQUIRED_MINOR + "." +
156 TCN_REQUIRED_PATCH));
157 try {
158 // Terminate the APR in case the version
159 // is below required.
160 terminateAPR();
161 } catch (Throwable t) {
162 // Ignore
163 }
164 return false;
165 }
166 if (patch < TCN_RECOMMENDED_PV) {
167 if (!log.isDebugEnabled()) {
168 log.info(sm.getString("aprListener.tcnVersion", major + "."
169 + minor + "." + patch,
170 TCN_REQUIRED_MAJOR + "." +
171 TCN_REQUIRED_MINOR + "." +
172 TCN_RECOMMENDED_PV));
173 } else {
174 log.debug(sm.getString("aprListener.tcnVersion", major + "."
175 + minor + "." + patch,
176 TCN_REQUIRED_MAJOR + "." +
177 TCN_REQUIRED_MINOR + "." +
178 TCN_RECOMMENDED_PV));
179 }
180 }
181 if (!log.isDebugEnabled()) {
182 log.info(sm.getString("aprListener.tcnValid", major + "."
183 + minor + "." + patch));
184 }
185 else {
186 log.debug(sm.getString("aprListener.tcnValid", major + "."
187 + minor + "." + patch));
188 }
189 // Log APR flags
190 log.info(sm.getString("aprListener.flags", Library.APR_HAVE_IPV6, Library.APR_HAS_SENDFILE,
191 Library.APR_HAS_SO_ACCEPTFILTER, Library.APR_HAS_RANDOM));
192 return true;
193 }
194
195 private static synchronized void initializeSSL()
196 throws ClassNotFoundException, NoSuchMethodException,
197 IllegalAccessException, InvocationTargetException
198 {
199
200 if ("off".equalsIgnoreCase(SSLEngine)) {
201 return;
202 }
203 if (sslInitialized) {
204 //only once per VM
205 return;
206 }
207 String methodName = "initialize";
208 Class paramTypes[] = new Class[1];
209 paramTypes[0] = String.class;
210 Object paramValues[] = new Object[1];
211 paramValues[0] = "on".equalsIgnoreCase(SSLEngine)?null:SSLEngine;
212 Class clazz = Class.forName("org.apache.tomcat.jni.SSL");
213 Method method = clazz.getMethod(methodName, paramTypes);
214 method.invoke(null, paramValues);
215 sslInitialized = true;
216 }
217
218 public String getSSLEngine() {
219 return SSLEngine;
220 }
221
222 public void setSSLEngine(String SSLEngine) {
223 this.SSLEngine = SSLEngine;
224 }
225
226 }