You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jg...@apache.org on 2015/04/15 12:35:51 UTC

tomee git commit: TOMEE-1547 adding example

Repository: tomee
Updated Branches:
  refs/heads/tomee-1.7.x a552172bb -> eb76a0cdd


TOMEE-1547 adding example


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/eb76a0cd
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/eb76a0cd
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/eb76a0cd

Branch: refs/heads/tomee-1.7.x
Commit: eb76a0cddad7f39b697ee2f899f764f91642b8ff
Parents: a552172
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Wed Apr 15 11:35:33 2015 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Wed Apr 15 11:35:33 2015 +0100

----------------------------------------------------------------------
 examples/resources-jmx-example/pom.xml          |  90 ++++++++++++
 .../resources-jmx-ear/pom.xml                   |  45 ++++++
 .../resources-jmx-ejb/pom.xml                   | 104 ++++++++++++++
 .../resource/jmx/factory/Converter.java         | 143 +++++++++++++++++++
 .../superbiz/resource/jmx/factory/Editors.java  |  49 +++++++
 .../resource/jmx/factory/JMXBeanCreator.java    | 109 ++++++++++++++
 .../jmx/factory/MBeanRegistrationException.java |  39 +++++
 .../resource/jmx/factory/PrimitiveTypes.java    | 124 ++++++++++++++++
 .../superbiz/resource/jmx/resources/Hello.java  |  51 +++++++
 .../resource/jmx/resources/HelloMBean.java      |  32 +++++
 .../src/main/resources/META-INF/beans.xml       |   3 +
 .../src/main/resources/META-INF/resources.xml   |  27 ++++
 .../java/org/superbiz/resource/jmx/JMXTest.java | 118 +++++++++++++++
 .../src/test/resources/arquillian.xml           |  31 ++++
 14 files changed, 965 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/pom.xml
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/pom.xml b/examples/resources-jmx-example/pom.xml
new file mode 100644
index 0000000..7a44815
--- /dev/null
+++ b/examples/resources-jmx-example/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.superbiz</groupId>
+  <artifactId>resources-jmx</artifactId>
+  <packaging>pom</packaging>
+  <version>1.1.1-SNAPSHOT</version>
+  <name>OpenEJB :: Examples :: Resources/JMX Example</name>
+  
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <version.openejb>4.7.2-SNAPSHOT</version.openejb>
+    <version.tomee>1.7.2-SNAPSHOT</version.tomee>
+    <version.openjpa>2.3.0</version.openjpa>
+  </properties>
+  
+  <repositories>
+    <repository>
+      <id>apache-m2-snapshot</id>
+      <name>Apache Snapshot Repository</name>
+      <url>http://repository.apache.org/snapshots</url>
+    </repository>
+    <repository>
+      <id>tomcat-m2-repo</id>
+      <name>Tomcat Dev Repository</name>
+      <url>http://tomcat.apache.org/dev/dist/m2-repository/</url>
+    </repository>
+  </repositories>
+  
+  <pluginRepositories>
+    <pluginRepository>
+      <id>apache-m2-snapshot</id>
+      <name>Apache Snapshot Repository</name>
+      <url>http://repository.apache.org/snapshots</url>
+    </pluginRepository>
+  </pluginRepositories>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.1</version>
+          <configuration>
+            <source>1.6</source>
+            <target>1.6</target>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-resources-plugin</artifactId>
+          <version>2.6</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+  <modules>
+    <module>resources-jmx-ejb</module>
+    <module>resources-jmx-ear</module>
+  </modules>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.superbiz</groupId>
+        <artifactId>resources-jmx-ejb</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <type>ejb</type>
+        <scope>compile</scope>
+      </dependency>
+      <!-- Java EE6 dependencies -->
+      <dependency>
+        <groupId>org.apache.openejb</groupId>
+        <artifactId>javaee-api</artifactId>
+        <version>6.0-6</version>
+        <scope>provided</scope>
+      </dependency>
+      <!-- Test dependencies -->
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.11</version>
+        <type>jar</type>
+        <scope>test</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ear/pom.xml
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ear/pom.xml b/examples/resources-jmx-example/resources-jmx-ear/pom.xml
new file mode 100644
index 0000000..e83de66
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ear/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+	    <groupId>org.superbiz</groupId>
+	    <artifactId>resources-jmx</artifactId>
+	    <version>1.1.1-SNAPSHOT</version>
+	</parent>
+	<artifactId>resources-jmx-ear</artifactId>
+	<packaging>ear</packaging>
+	<name>OpenEJB :: Examples :: Resources/JMX Example :: EAR Module</name>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-ear-plugin</artifactId>
+				<version>2.9</version>
+				<configuration>
+					<version>6</version>
+					<defaultLibBundleDir>lib</defaultLibBundleDir>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+							<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+						</manifest>
+					</archive>
+					<modules>
+						<ejbModule>
+							<groupId>org.superbiz</groupId>
+							<artifactId>resources-jmx-ejb</artifactId>
+						</ejbModule>
+					</modules>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>org.superbiz</groupId>
+			<artifactId>resources-jmx-ejb</artifactId>
+			<type>ejb</type>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/pom.xml
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/pom.xml b/examples/resources-jmx-example/resources-jmx-ejb/pom.xml
new file mode 100644
index 0000000..e44feb1
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/pom.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+	    <groupId>org.superbiz</groupId>
+	    <artifactId>resources-jmx</artifactId>
+	    <version>1.1.1-SNAPSHOT</version>
+	</parent>
+	<artifactId>resources-jmx-ejb</artifactId>
+	<packaging>ejb</packaging>
+	<name>OpenEJB :: Examples :: Resources/JMX Example :: EJB Module</name>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-ejb-plugin</artifactId>
+				<version>2.3</version>
+				<configuration>
+					<ejbVersion>3.1</ejbVersion>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+							<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.openejb</groupId>
+			<artifactId>javaee-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.openejb</groupId>
+			<artifactId>arquillian-tomee-remote</artifactId>
+			<version>${version.tomee}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.openejb</groupId>
+			<artifactId>openejb-provisionning</artifactId>
+			<version>${version.openejb}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.arquillian.junit</groupId>
+			<artifactId>arquillian-junit-container</artifactId>
+			<version>1.1.7.Final</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.openejb</groupId>
+			<artifactId>ziplock</artifactId>
+			<version>${version.tomee}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.shrinkwrap.resolver</groupId>
+			<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
+			<version>2.2.0-beta-2</version>
+			<scope>test</scope>
+			<exclusions>
+				<exclusion>
+					<artifactId>aether-api</artifactId>
+					<groupId>org.eclipse.aether</groupId>
+				</exclusion>
+				<exclusion>
+					<artifactId>aether-impl</artifactId>
+					<groupId>org.eclipse.aether</groupId>
+				</exclusion>
+				<exclusion>
+					<artifactId>aether-spi</artifactId>
+					<groupId>org.eclipse.aether</groupId>
+				</exclusion>
+				<exclusion>
+					<artifactId>aether-util</artifactId>
+					<groupId>org.eclipse.aether</groupId>
+				</exclusion>
+				<exclusion>
+					<artifactId>aether-connector-basic</artifactId>
+					<groupId>org.eclipse.aether</groupId>
+				</exclusion>
+				<exclusion>
+					<artifactId>aether-transport-wagon</artifactId>
+					<groupId>org.eclipse.aether</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.maven</groupId>
+			<artifactId>maven-aether-provider</artifactId>
+			<version>3.0.5</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Converter.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Converter.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Converter.java
new file mode 100644
index 0000000..07305ee
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Converter.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.superbiz.resource.jmx.factory;
+
+
+import java.beans.PropertyEditor;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Can convert anything with a:
+ * - PropertyEditor
+ * - Constructor that accepts String
+ * - public static method that returns itself and takes a String
+ *
+ * @version $Revision$ $Date$
+ */
+public class Converter {
+
+    private Converter() {
+    }
+
+    public static Object convert(final Object value, Class<?> targetType, final String name) {
+        if (value == null) {
+            if (targetType.equals(Boolean.TYPE)) {
+                return false;
+            }
+            return value;
+        }
+
+        final Class<? extends Object> actualType = value.getClass();
+
+        if (targetType.isPrimitive()) {
+            targetType =  PrimitiveTypes.valueOf(targetType.toString().toUpperCase()).getWraper();
+        }
+
+        if (targetType.isAssignableFrom(actualType)) {
+            return value;
+        }
+
+        if (Number.class.isAssignableFrom(actualType) && Number.class.isAssignableFrom(targetType)) {
+            return value;
+        }
+
+        if (!(value instanceof String)) {
+            final String message = String.format("Expected type '%s' for '%s'. Found '%s'", targetType.getName(), name, actualType.getName());
+            throw new IllegalArgumentException(message);
+        }
+
+        final String stringValue = (String) value;
+
+        if (Enum.class.isAssignableFrom(targetType)) {
+            final Class<? extends Enum> enumType = (Class<? extends Enum>) targetType;
+            try {
+                return Enum.valueOf(enumType, stringValue);
+            } catch (final IllegalArgumentException e) {
+                try {
+                    return Enum.valueOf(enumType, stringValue.toUpperCase());
+                } catch (final IllegalArgumentException e1) {
+                    return Enum.valueOf(enumType, stringValue.toLowerCase());
+                }
+            }
+        }
+
+        try {
+            // Force static initializers to run
+            Class.forName(targetType.getName(), true, targetType.getClassLoader());
+        } catch (final ClassNotFoundException e) {
+            e.printStackTrace();
+        }
+
+        final PropertyEditor editor = Editors.get(targetType);
+
+        if (editor == null) {
+            final Object result = create(targetType, stringValue);
+            if (result != null) {
+                return result;
+            }
+        }
+
+        if (editor == null) {
+            final String message = String.format("Cannot convert to '%s' for '%s'. No PropertyEditor", targetType.getName(), name);
+            throw new IllegalArgumentException(message);
+        }
+
+        editor.setAsText(stringValue);
+        return editor.getValue();
+    }
+
+    private static Object create(final Class<?> type, final String value) {
+        try {
+            final Constructor<?> constructor = type.getConstructor(String.class);
+            return constructor.newInstance(value);
+        } catch (final NoSuchMethodException e) {
+            // fine
+        } catch (final Exception e) {
+            final String message = String.format("Cannot convert string '%s' to %s.", value, type);
+            throw new IllegalArgumentException(message, e);
+        }
+
+        for (final Method method : type.getMethods()) {
+            if (isInvalidMethod(type, method)) { continue; }
+
+            try {
+                return method.invoke(null, value);
+            } catch (final Exception e) {
+                final String message = String.format("Cannot convert string '%s' to %s.", value, type);
+                throw new IllegalStateException(message, e);
+            }
+        }
+
+        return null;
+    }
+
+    private static boolean isInvalidMethod(Class<?> type, Method method) {
+        if (!Modifier.isStatic(method.getModifiers()) ||
+                !Modifier.isPublic(method.getModifiers()) ||
+                !method.getReturnType().equals(type) ||
+                !method.getParameterTypes()[0].equals(String.class) ||
+                method.getParameterTypes().length != 1)
+        {
+            return true;
+        }
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Editors.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Editors.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Editors.java
new file mode 100644
index 0000000..33c9fc8
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/Editors.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.superbiz.resource.jmx.factory;
+
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+
+public class Editors {
+
+    private Editors() {
+        // no-op
+    }
+
+    public static PropertyEditor get(final Class<?> type) {
+        final PropertyEditor editor = PropertyEditorManager.findEditor(type);
+
+        if (editor != null) return editor;
+
+        final Class<Editors> c = Editors.class;
+
+        try {
+            final Class<?> editorClass = c.getClassLoader().loadClass(c.getName().replace("Editors", type.getSimpleName() + "Editor"));
+
+            PropertyEditorManager.registerEditor(type, editorClass);
+
+            return PropertyEditorManager.findEditor(type);
+        } catch (final ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/JMXBeanCreator.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/JMXBeanCreator.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/JMXBeanCreator.java
new file mode 100644
index 0000000..311879c
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/JMXBeanCreator.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.superbiz.resource.jmx.factory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Field;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+public class JMXBeanCreator {
+
+    private static Logger LOGGER = Logger.getLogger(JMXBeanCreator.class.getName());
+    private Properties properties;
+
+    public Object create() throws MBeanRegistrationException {
+        // instantiate the bean
+
+        final String code = properties.getProperty("code");
+        final String name = properties.getProperty("name");
+
+        requireNotNull(code);
+        requireNotNull(name);
+
+        try {
+            final Class<?> cls = Class.forName(code, true, Thread.currentThread().getContextClassLoader());
+            final Object instance = cls.newInstance();
+
+            final Field[] fields = cls.getDeclaredFields();
+            for (final Field field : fields) {
+
+                final String property = properties.getProperty(field.getName());
+                if (property == null) {
+                    continue;
+                }
+
+                try {
+                    field.setAccessible(true);
+                    field.set(instance, Converter.convert(property, field.getType(), field.getName()));
+                } catch (Exception e) {
+                    LOGGER.info(String.format("Unable to set value %s on field %s", property, field.getName()));
+                }
+            }
+
+            final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+            final ObjectName objectName = new ObjectName(name);
+            mbs.registerMBean(instance, objectName);
+
+            return instance;
+
+        } catch (final ClassNotFoundException e) {
+            LOGGER.severe("Unable to find class " + code);
+            throw new MBeanRegistrationException(e);
+        } catch (final InstantiationException e) {
+            LOGGER.severe("Unable to create instance of class " + code);
+            throw new MBeanRegistrationException(e);
+        } catch (final IllegalAccessException e) {
+            LOGGER.severe("Illegal access: " + code);
+            throw new MBeanRegistrationException(e);
+        } catch (final MalformedObjectNameException e) {
+            LOGGER.severe("Malformed MBean name: " + name);
+            throw new MBeanRegistrationException(e);
+        } catch (final InstanceAlreadyExistsException e) {
+            LOGGER.severe("Instance already exists: " + name);
+            throw new MBeanRegistrationException(e);
+        } catch (final NotCompliantMBeanException e) {
+            LOGGER.severe("Class is not a valid MBean: " + code);
+            throw new MBeanRegistrationException(e);
+        } catch (final javax.management.MBeanRegistrationException e) {
+            LOGGER.severe("Error registering " + name + ", " + code);
+            throw new MBeanRegistrationException(e);
+        }
+    }
+
+    private void requireNotNull(final String object) throws MBeanRegistrationException {
+        if (object == null) {
+            throw new MBeanRegistrationException("code property not specified, stopping");
+        }
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(final Properties properties) {
+        this.properties = properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/MBeanRegistrationException.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/MBeanRegistrationException.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/MBeanRegistrationException.java
new file mode 100644
index 0000000..a21b7ab
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/MBeanRegistrationException.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.superbiz.resource.jmx.factory;
+
+public class MBeanRegistrationException extends Exception {
+
+    public MBeanRegistrationException() {
+    }
+
+    public MBeanRegistrationException(String message) {
+        super(message);
+    }
+
+    public MBeanRegistrationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public MBeanRegistrationException(Throwable cause) {
+        super(cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/PrimitiveTypes.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/PrimitiveTypes.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/PrimitiveTypes.java
new file mode 100644
index 0000000..da9e56c
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/factory/PrimitiveTypes.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.superbiz.resource.jmx.factory;
+
+public enum PrimitiveTypes {
+    BOOLEAN {
+        @Override
+        public String getDefaultValue() {
+            return "false";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Boolean.class;
+        }
+    },
+    BYTE {
+        @Override
+        public String getDefaultValue() {
+            return "0";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Byte.class;
+        }
+    },
+    CHAR {
+        @Override
+        public String getDefaultValue() {
+            return "\u0000";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Character.class;
+        }
+    },
+    CHARACTER {
+        @Override
+        public String getDefaultValue() {
+            return "\u0000";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Character.class;
+        }
+    },
+    LONG {
+        @Override
+        public String getDefaultValue() {
+            return "0";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Long.class;
+        }
+    },
+    FLOAT {
+        @Override
+        public String getDefaultValue() {
+            return "0";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Float.class;
+        }
+    },
+    INT {
+        @Override
+        public String getDefaultValue() {
+            return "0";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Integer.class;
+        }
+    },
+    DOUBLE {
+        @Override
+        public String getDefaultValue() {
+            return "0";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Double.class;
+        }
+    },
+    SHORT {
+        @Override
+        public String getDefaultValue() {
+            return "0";
+        }
+
+        @Override
+        public Class<?> getWraper() {
+            return Short.class;
+        }
+    };
+
+    public abstract String getDefaultValue();
+    public abstract Class<?> getWraper();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/Hello.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/Hello.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/Hello.java
new file mode 100644
index 0000000..5b04d8f
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/Hello.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.superbiz.resource.jmx.resources;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class Hello implements HelloMBean {
+
+    private AtomicInteger count = new AtomicInteger(0);
+
+    @Override
+    public String greet(String name) {
+        if (name == null) {
+            throw new NullPointerException("Name cannot be null");
+        }
+
+        return "Hello, " + name;
+    }
+
+    @Override
+    public int getCount() {
+        return count.get();
+    }
+
+    @Override
+    public void setCount(int value) {
+        count.set(value);
+    }
+
+    @Override
+    public void increment() {
+        count.incrementAndGet();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/HelloMBean.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/HelloMBean.java b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/HelloMBean.java
new file mode 100644
index 0000000..e838353
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/java/org/superbiz/resource/jmx/resources/HelloMBean.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.superbiz.resource.jmx.resources;
+
+public interface HelloMBean {
+
+    public String greet(final String name);
+
+    public int getCount();
+
+    public void setCount(int count);
+
+    public void increment();
+
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/beans.xml b/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..c659db4
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<beans xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd"/>

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/resources.xml
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/resources.xml b/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/resources.xml
new file mode 100644
index 0000000..cff5fff
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/main/resources/META-INF/resources.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<Resources>
+  <Resource id="Hello" class-name="org.superbiz.resource.jmx.factory.JMXBeanCreator" factory-name="create">
+    code org.superbiz.resource.jmx.resources.Hello
+    name superbiz.test:name=Hello
+    count 12345
+  </Resource>
+</Resources>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/test/java/org/superbiz/resource/jmx/JMXTest.java
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/test/java/org/superbiz/resource/jmx/JMXTest.java b/examples/resources-jmx-example/resources-jmx-ejb/src/test/java/org/superbiz/resource/jmx/JMXTest.java
new file mode 100644
index 0000000..6a9438c
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/test/java/org/superbiz/resource/jmx/JMXTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.superbiz.resource.jmx;
+
+import org.apache.ziplock.maven.Mvn;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.superbiz.resource.jmx.resources.HelloMBean;
+
+import javax.annotation.Resource;
+import javax.ejb.EJB;
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Singleton;
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.lang.management.ManagementFactory;
+
+@RunWith(Arquillian.class)
+public class JMXTest {
+
+    @EJB
+    private TestEjb ejb;
+
+    @Deployment
+    public static EnterpriseArchive createDeployment() {
+
+        final JavaArchive ejbJar = new Mvn.Builder()
+                .name("jmx-ejb.jar")
+                .build(JavaArchive.class)
+                .addClass(JMXTest.class)
+                .addClass(TestEjb.class);
+
+        final EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class, "jmx.ear")
+                .addAsModule(ejbJar);
+
+        return ear;
+    }
+
+    @Test
+    public void test() throws Exception {
+        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        final ObjectName objectName = new ObjectName("superbiz.test:name=Hello");
+
+        Assert.assertNotNull(ejb);
+        
+        Assert.assertEquals(0, mbs.getAttribute(objectName, "Count"));
+        Assert.assertEquals(0, ejb.getCount());
+        
+        mbs.invoke(objectName, "increment", new Object[0], new String[0]);
+        Assert.assertEquals(1, mbs.getAttribute(objectName, "Count"));
+        Assert.assertEquals(1, ejb.getCount());
+        
+        ejb.increment();
+        Assert.assertEquals(2, mbs.getAttribute(objectName, "Count"));
+        Assert.assertEquals(2, ejb.getCount());
+
+        Attribute attribute = new Attribute("Count", 12345);
+        mbs.setAttribute(objectName, attribute);
+        Assert.assertEquals(12345, mbs.getAttribute(objectName, "Count"));
+        Assert.assertEquals(12345, ejb.getCount());
+        
+        ejb.setCount(23456);
+        Assert.assertEquals(23456, mbs.getAttribute(objectName, "Count"));
+        Assert.assertEquals(23456, ejb.getCount());
+
+        Assert.assertEquals("Hello, world", mbs.invoke(objectName, "greet", new Object[] { "world" }, new String[] { String.class.getName() }));
+        Assert.assertEquals("Hello, world", ejb.greet("world"));
+    }
+
+    @Singleton
+    @Lock(LockType.READ)
+    public static class TestEjb {
+
+        @Resource(name="jmx/Hello")
+        private HelloMBean helloMBean;
+
+        public String greet(String name) {
+            return helloMBean.greet(name);
+        }
+
+        public void setCount(int count) {
+            helloMBean.setCount(count);
+        }
+
+        public void increment() {
+            helloMBean.increment();
+        }
+
+        public int getCount() {
+            return helloMBean.getCount();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/eb76a0cd/examples/resources-jmx-example/resources-jmx-ejb/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/examples/resources-jmx-example/resources-jmx-ejb/src/test/resources/arquillian.xml b/examples/resources-jmx-example/resources-jmx-ejb/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..b015420
--- /dev/null
+++ b/examples/resources-jmx-example/resources-jmx-ejb/src/test/resources/arquillian.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<arquillian>
+  <container qualifier="tomee" default="true">
+    <configuration>
+      <property name="classifier">plus</property>
+      <property name="httpPort">-1</property>
+      <property name="stopPort">-1</property>
+      <property name="tomcatVersion"></property>
+      <property name="openejbVersion">${tomee.version}</property>
+      <property name="dir">target/apache-tomee-remote</property>
+      <property name="appWorkingDir">target/arquillian-test-working-dir</property>
+    </configuration>
+  </container>
+</arquillian>