View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  
21  package org.apache.james.postage.jmx;
22  
23  import org.apache.james.postage.SamplingException;
24  import org.apache.james.postage.execution.Sampler;
25  import org.apache.james.postage.result.PostageRunnerResult;
26  
27  import java.lang.reflect.Constructor;
28  import java.lang.reflect.Method;
29  
30  /***
31   * wraps JVMResourceSamplerWorker to allow J2SE 1.4 compatibility<br/>
32   * does not access this class through direct reference, only through reflection<br/>
33   * in the case this compatibility is removed, simply inline the Worker class<br/>
34   * <br/>
35   * @see org.apache.james.postage.jmx.JVMResourceSamplerWorker for how to configure James to be JVM-JMX agnostic
36   */
37  public class JVMResourceSampler implements Sampler {
38  
39      private Object jvmResourceSampleWorker = null;
40      private Method m_connectMethod;
41      private Method m_doSampleMethod;
42      private static final Class[] VOID_ARGUMENT_LIST = new Class[]{};
43  
44      public static boolean isJMXAvailable() {
45          try {
46              // this class is only present, when the package _is run_ at least under Java 5
47              Class jmxFactoryClass = Class.forName("javax.management.remote.JMXConnectorFactory");
48          } catch (ClassNotFoundException e) {
49              return false;
50          }
51          return true;
52      }
53  
54      public JVMResourceSampler(String host, int port, PostageRunnerResult results) {
55          Class workerClass;
56          Constructor constructor;
57          try {
58              // the class is only present, when the package _was compiled_ with at least Java 5 (see build script)
59              workerClass = Class.forName("org.apache.james.postage.jmx.JVMResourceSamplerWorker");
60              Constructor[] constructors = workerClass.getConstructors();
61              if (constructors.length != 1) throw new IllegalStateException("only constructor JVMResourceSamplerWorker(String host, int port, PostageRunnerResult results) is supported");
62              constructor = constructors[0];
63          } catch (ClassNotFoundException e) {
64              return; // keep worker object NULL
65          }
66  
67          try {
68              jvmResourceSampleWorker = constructor.newInstance(new Object[]{host, new Integer(port), results});
69          } catch (Exception e) {
70              throw new RuntimeException("could not create JVMResourceSamplerWorker", e);
71          }
72          if (jvmResourceSampleWorker == null) throw new IllegalStateException("could not create JVMResourceSamplerWorker");
73  
74          try {
75              m_connectMethod = workerClass.getMethod("connectRemoteJamesJMXServer", VOID_ARGUMENT_LIST);
76              m_doSampleMethod = workerClass.getMethod("doSample", VOID_ARGUMENT_LIST);
77          } catch (NoSuchMethodException e) {
78              throw new RuntimeException("could not access delegation methods", e);
79          }
80  
81      }
82  
83      public void connectRemoteJamesJMXServer() throws SamplingException {
84          if(jvmResourceSampleWorker == null) throw new SamplingException("JSE specific features not present. (compile the project with JSE 5)");
85          try {
86              m_connectMethod.invoke(jvmResourceSampleWorker, (Object[])VOID_ARGUMENT_LIST);
87          } catch (Exception e) {
88              throw new SamplingException("could not establish connection to remote James JMX. is James really configured for JMX and running under JSE5 or later?");
89          }
90      }
91  
92      public void doSample() throws SamplingException {
93          if(jvmResourceSampleWorker == null) throw new SamplingException("JSE specific features not present. (compile the project with JSE 5)");
94          try {
95              m_doSampleMethod.invoke(jvmResourceSampleWorker, (Object[])VOID_ARGUMENT_LIST);
96          } catch (Exception e) {
97              throw new SamplingException(e);
98          }
99      }
100 }