diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e02cf48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.project +/.settings +/src diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ea644d2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + net.aimeizi + maven-framework-project + 1.0.0 + pom + + spring3-javaconfig-example + spring3-helloworld-example + spring3-javaconfig-import-example + spring3-mvc-simple + spring3-jmx-example + spring3-rmi-example + + \ No newline at end of file diff --git a/spring3-helloworld-example/.gitignore b/spring3-helloworld-example/.gitignore new file mode 100644 index 0000000..9dff9cc --- /dev/null +++ b/spring3-helloworld-example/.gitignore @@ -0,0 +1,4 @@ +/.project +/.settings +/target +/.classpath diff --git a/spring3-helloworld-example/pom.xml b/spring3-helloworld-example/pom.xml new file mode 100644 index 0000000..7bee7ae --- /dev/null +++ b/spring3-helloworld-example/pom.xml @@ -0,0 +1,28 @@ + + 4.0.0 + + net.aimeizi + maven-framework-project + 1.0.0 + + spring3-helloworld-example + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + + + 3.2.3.RELEASE + + + \ No newline at end of file diff --git a/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/App.java b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/App.java new file mode 100644 index 0000000..18f237e --- /dev/null +++ b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/App.java @@ -0,0 +1,26 @@ +package net.aimeizi.helloworld.example; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class App { + + @SuppressWarnings("resource") + public static void main(String[] args) { + + /** + * Create a new ApplicationContext, loading the + * definitions from the given XML file + */ + ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); + /** + * Return an instance, which may be shared or + * independent, of the specified bean. + */ + HelloWorldService obj = (HelloWorldService) context.getBean("helloWorldService"); + obj.setName("Spring 3.2.3"); + String message =obj.sayHello(); + System.out.println(message); + } + +} diff --git a/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/HelloWorldService.java b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/HelloWorldService.java new file mode 100644 index 0000000..8387d5b --- /dev/null +++ b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/HelloWorldService.java @@ -0,0 +1,18 @@ +package net.aimeizi.helloworld.example; + +import org.springframework.stereotype.Service; + +@Service("helloWorldService") +public class HelloWorldService { + + private String name; + + public void setName(String name) { + this.name = name; + } + + public String sayHello() { + return "Hello from HelloWorld Service! " + name; + } + +} diff --git a/spring3-helloworld-example/src/main/resources/applicationContext.xml b/spring3-helloworld-example/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..a13878d --- /dev/null +++ b/spring3-helloworld-example/src/main/resources/applicationContext.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring3-javaconfig-example/.gitignore b/spring3-javaconfig-example/.gitignore new file mode 100644 index 0000000..9dff9cc --- /dev/null +++ b/spring3-javaconfig-example/.gitignore @@ -0,0 +1,4 @@ +/.project +/.settings +/target +/.classpath diff --git a/spring3-javaconfig-example/pom.xml b/spring3-javaconfig-example/pom.xml new file mode 100644 index 0000000..498c35b --- /dev/null +++ b/spring3-javaconfig-example/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + net.aimeizi + maven-framework-project + 1.0.0 + + spring3-javaconfig-example + + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + cglib + cglib + 3.0 + + + + + 3.2.3.RELEASE + + + \ No newline at end of file diff --git a/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/App.java b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/App.java new file mode 100644 index 0000000..31b1a8f --- /dev/null +++ b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/App.java @@ -0,0 +1,26 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class App { + + @SuppressWarnings("resource") + public static void main(String[] args) { + + /** + * Create a new ApplicationContext, deriving bean definition from the + * given annotated class and automatically refreshing the context. + */ + ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + /** + * Return an instance, which may be shared or independent, of the + * specified bean. + */ + HelloWorldService obj = (HelloWorldService) context.getBean("helloWorldBean"); + obj.setName("Spring 3.2.3"); + obj.sayHello(); + + } + +} diff --git a/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java new file mode 100644 index 0000000..47887f7 --- /dev/null +++ b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java @@ -0,0 +1,14 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AppConfig { + + @Bean(name="helloWorldBean") + public HelloWorldService helloWorldService() { + return new HelloWorldService(); + } + +} diff --git a/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java new file mode 100644 index 0000000..9942f44 --- /dev/null +++ b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java @@ -0,0 +1,19 @@ +package net.aimeizi.javaconfig.example; + +public class HelloWorldService { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void sayHello() { + System.out.println("Hello from Java Configuration. " + this.getName()); + } + +} diff --git a/spring3-javaconfig-example/src/main/resources/applicationContext.xml b/spring3-javaconfig-example/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..5ce0381 --- /dev/null +++ b/spring3-javaconfig-example/src/main/resources/applicationContext.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/spring3-javaconfig-import-example/.gitignore b/spring3-javaconfig-import-example/.gitignore new file mode 100644 index 0000000..9dff9cc --- /dev/null +++ b/spring3-javaconfig-import-example/.gitignore @@ -0,0 +1,4 @@ +/.project +/.settings +/target +/.classpath diff --git a/spring3-javaconfig-import-example/pom.xml b/spring3-javaconfig-import-example/pom.xml new file mode 100644 index 0000000..7c51f32 --- /dev/null +++ b/spring3-javaconfig-import-example/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + + net.aimeizi + maven-framework-project + 1.0.0 + + spring3-javaconfig-import-example + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + cglib + cglib + 3.0 + + + + + 3.2.3.RELEASE + + + \ No newline at end of file diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/App.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/App.java new file mode 100644 index 0000000..d2023df --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/App.java @@ -0,0 +1,21 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class App { + + @SuppressWarnings("resource") + public static void main(String[] args) { + + ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + + HelloWorldService hello = (HelloWorldService) context.getBean("helloWorldBean"); + hello.sayHello("Spring 3.2.3"); + + GoodbyeService bye = (GoodbyeService) context.getBean("goodbyeBean"); + bye.sayGoodbye("Spring 3.2.3"); + + } + +} diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java new file mode 100644 index 0000000..a3e7e28 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java @@ -0,0 +1,10 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Configuration +@Import(value={HelloConfig.class,GoodbyeConfig.class}) +public class AppConfig { + +} diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppXml.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppXml.java new file mode 100644 index 0000000..333d8c2 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppXml.java @@ -0,0 +1,21 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class AppXml { + + @SuppressWarnings("resource") + public static void main(String[] args) { + + ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); + + HelloWorldService hello = (HelloWorldService) context.getBean("helloWorldBean"); + hello.sayHello("Spring 3.2.3"); + + GoodbyeService bye = (GoodbyeService) context.getBean("goodbyeBean"); + bye.sayGoodbye("Spring 3.2.3"); + + } + +} diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeConfig.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeConfig.java new file mode 100644 index 0000000..2459139 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeConfig.java @@ -0,0 +1,14 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GoodbyeConfig { + + @Bean(name="goodbyeBean") + public GoodbyeService goodByeService() { + return new GoodbyeService(); + } + +} diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeService.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeService.java new file mode 100644 index 0000000..30207df --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeService.java @@ -0,0 +1,9 @@ +package net.aimeizi.javaconfig.example; + +public class GoodbyeService { + + public void sayGoodbye(String name){ + System.out.println("Goodbye from Java Configuration. "+ name); + } + +} diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloConfig.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloConfig.java new file mode 100644 index 0000000..31e34c2 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloConfig.java @@ -0,0 +1,14 @@ +package net.aimeizi.javaconfig.example; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HelloConfig { + + @Bean(name="helloWorldBean") + public HelloWorldService helloWorldService() { + return new HelloWorldService(); + } + +} diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java new file mode 100644 index 0000000..591bbb6 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java @@ -0,0 +1,9 @@ +package net.aimeizi.javaconfig.example; + +public class HelloWorldService { + + public void sayHello(String name) { + System.out.println("Hello from Java Configuration. " + name); + } + +} diff --git a/spring3-javaconfig-import-example/src/main/resources/applicationContext.xml b/spring3-javaconfig-import-example/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..530595d --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/resources/applicationContext.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/spring3-javaconfig-import-example/src/main/resources/goodbye.xml b/spring3-javaconfig-import-example/src/main/resources/goodbye.xml new file mode 100644 index 0000000..cbc5959 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/resources/goodbye.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/spring3-javaconfig-import-example/src/main/resources/hello.xml b/spring3-javaconfig-import-example/src/main/resources/hello.xml new file mode 100644 index 0000000..6ba9341 --- /dev/null +++ b/spring3-javaconfig-import-example/src/main/resources/hello.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/spring3-jmx-example/.gitignore b/spring3-jmx-example/.gitignore new file mode 100644 index 0000000..7075a2f --- /dev/null +++ b/spring3-jmx-example/.gitignore @@ -0,0 +1,4 @@ +/target +/.classpath +/.project +/.settings diff --git a/spring3-jmx-example/README.md b/spring3-jmx-example/README.md new file mode 100644 index 0000000..061831e --- /dev/null +++ b/spring3-jmx-example/README.md @@ -0,0 +1,20 @@ +# spring3-jmx-example + +copy jmxremote.access jmxremote.password + +service:jmx:rmi://localhost/jndi/rmi://localhost:8888/jemosJmxConnector + +jemosAdmin / secure + +![](src/main/resources/jmx-1.jpg) + +![](src/main/resources/jmx-2.jpg) + +![](src/main/resources/jmx-3.jpg) + + +* [http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-1.html](http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-1.html) + +* [http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-2.html](http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-2.html) + +* [http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-3.html](http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-3.html) \ No newline at end of file diff --git a/spring3-jmx-example/pom.xml b/spring3-jmx-example/pom.xml new file mode 100644 index 0000000..e96d41c --- /dev/null +++ b/spring3-jmx-example/pom.xml @@ -0,0 +1,95 @@ + + 4.0.0 + + net.aimeizi + maven-framework-project + 1.0.0 + + net.aimeizi.jmx.example + spring3-jmx-example + + + + junit + junit + 4.8.2 + test + + + log4j + log4j + 1.2.16 + compile + + + org.springframework + spring-context + 3.0.5.RELEASE + compile + + + org.springframework + spring-core + 3.0.5.RELEASE + compile + + + org.springframework + spring-jmx + 2.0.8 + compile + + + org.springframework + spring-test + 3.0.5.RELEASE + jar + test + + + javax.annotation + jsr250-api + 1.0 + + + commons-io + commons-io + 2.0.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2.1 + + + buildable-project + install + + assembly + + + + + + project + + + + + + + \ No newline at end of file diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfig.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfig.java new file mode 100644 index 0000000..5aad4aa --- /dev/null +++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfig.java @@ -0,0 +1,41 @@ +package net.aimeizi.jmx.example; + +public class SystemConfig implements SystemConfigMBean { + + private int threadCount; + private String schemaName; + + public SystemConfig(int numThreads, String schema){ + this.threadCount=numThreads; + this.schemaName=schema; + } + + @Override + public void setThreadCount(int noOfThreads) { + this.threadCount=noOfThreads; + } + + + @Override + public int getThreadCount() { + return this.threadCount; + } + + + @Override + public void setSchemaName(String schemaName) { + this.schemaName=schemaName; + } + + + @Override + public String getSchemaName() { + return this.schemaName; + } + + @Override + public String doConfig(){ + return "No of Threads="+this.threadCount+" and DB Schema Name="+this.schemaName; + } + +} \ No newline at end of file diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigMBean.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigMBean.java new file mode 100644 index 0000000..2e31062 --- /dev/null +++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigMBean.java @@ -0,0 +1,15 @@ +package net.aimeizi.jmx.example; + +public interface SystemConfigMBean { + + public void setThreadCount(int noOfThreads); + + public int getThreadCount(); + + public void setSchemaName(String schemaName); + + public String getSchemaName(); + + public String doConfig(); + +} diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigManagement.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigManagement.java new file mode 100644 index 0000000..514dea3 --- /dev/null +++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigManagement.java @@ -0,0 +1,30 @@ +package net.aimeizi.jmx.example; + +import java.lang.management.ManagementFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + +public class SystemConfigManagement { + private static final int DEFAULT_NO_THREADS=10; + private static final String DEFAULT_SCHEMA="default"; + + public static void main(String[] args) throws MalformedObjectNameException, InterruptedException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { + //Get the MBean server + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + //register the MBean + SystemConfig mBean = new SystemConfig(DEFAULT_NO_THREADS, DEFAULT_SCHEMA); + ObjectName name = new ObjectName("net.aimeizi.jmx.example:type=SystemConfig"); + mbs.registerMBean(mBean, name); + do{ + Thread.sleep(3000); + System.out.println("Thread Count="+mBean.getThreadCount()+":::Schema Name="+mBean.getSchemaName()); + }while(mBean.getThreadCount() !=0); + + } + +} \ No newline at end of file diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/TomcatJMX.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/TomcatJMX.java new file mode 100644 index 0000000..c2180e2 --- /dev/null +++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/TomcatJMX.java @@ -0,0 +1,171 @@ +package net.aimeizi.jmx.example; + +import java.lang.management.MemoryUsage; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Formatter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServerConnection; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +/** + * 使用JMX监控Tomcat + * @author welcome + * + */ +public class TomcatJMX { + + @SuppressWarnings({ "rawtypes", "unused" }) + public static void main(String[] args) { + try { + + String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:8999/jmxrmi"; + + JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); + + Map map = new HashMap(); + String[] credentials = new String[] { "monitorRole", "admin" }; + map.put("jmx.remote.credentials", credentials); + JMXConnector connector = JMXConnectorFactory.connect(serviceURL,map); + MBeanServerConnection mbsc = connector.getMBeanServerConnection(); + + // 端口最好是动态取得 + ObjectName threadObjName = new ObjectName( + "Catalina:type=ThreadPool,name=http-8080"); + MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName); + + String attrName = "currentThreadCount";// tomcat的线程数对应的属性值 + MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes(); + System.out.println("currentThreadCount:"+ mbsc.getAttribute(threadObjName, attrName)); + + // heap + for (int j = 0; j < mbsc.getDomains().length; j++) { + System.out.println("###########" + mbsc.getDomains()[j]); + } + Set MBeanset = mbsc.queryMBeans(null, null); + System.out.println("MBeanset.size() : " + MBeanset.size()); + Iterator MBeansetIterator = MBeanset.iterator(); + while (MBeansetIterator.hasNext()) { + ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator.next(); + ObjectName objectName = objectInstance.getObjectName(); + String canonicalName = objectName.getCanonicalName(); + System.out.println("canonicalName : " + canonicalName); + if (canonicalName + .equals("Catalina:host=localhost,type=Cluster")) { + // Get details of cluster MBeans + System.out.println("Cluster MBeans Details:"); + System.out + .println("========================================="); + // getMBeansDetails(canonicalName); + String canonicalKeyPropList = objectName.getCanonicalKeyPropertyListString(); + } + } + // ------------------------- system ---------------------- + ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime"); + System.out.println("厂商:" + + (String) mbsc.getAttribute(runtimeObjName, "VmVendor")); + System.out.println("程序:" + + (String) mbsc.getAttribute(runtimeObjName, "VmName")); + System.out.println("版本:" + + (String) mbsc.getAttribute(runtimeObjName, "VmVersion")); + Date starttime = new Date((Long) mbsc.getAttribute(runtimeObjName, + "StartTime")); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + System.out.println("启动时间:" + df.format(starttime)); + + Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime"); + System.out.println("连续工作时间:" + TomcatJMX.formatTimeSpan(timespan)); + // ------------------------ JVM ------------------------- + // 堆使用率 + ObjectName heapObjName = new ObjectName("java.lang:type=Memory"); + MemoryUsage heapMemoryUsage = MemoryUsage + .from((CompositeDataSupport) mbsc.getAttribute(heapObjName, + "HeapMemoryUsage")); + long maxMemory = heapMemoryUsage.getMax();// 堆最大 + long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配 + long usedMemory = heapMemoryUsage.getUsed(); + System.out.println("heap:" + (double) usedMemory * 100 + / commitMemory + "%");// 堆使用率 + + MemoryUsage nonheapMemoryUsage = MemoryUsage + .from((CompositeDataSupport) mbsc.getAttribute(heapObjName, + "NonHeapMemoryUsage")); + long noncommitMemory = nonheapMemoryUsage.getCommitted(); + long nonusedMemory = heapMemoryUsage.getUsed(); + System.out.println("nonheap:" + (double) nonusedMemory * 100 + / noncommitMemory + "%"); + + ObjectName permObjName = new ObjectName( + "java.lang:type=MemoryPool,name=Perm Gen"); + MemoryUsage permGenUsage = MemoryUsage + .from((CompositeDataSupport) mbsc.getAttribute(permObjName, + "Usage")); + long committed = permGenUsage.getCommitted();// 持久堆大小 + long used = heapMemoryUsage.getUsed();// + System.out.println("perm gen:" + (double) used * 100 / committed + + "%");// 持久堆使用率 + + // -------------------- Session --------------- + ObjectName managerObjName = new ObjectName( + "Catalina:type=Manager,*"); + Set s = mbsc.queryNames(managerObjName, null); + for (ObjectName obj : s) { + System.out.println("应用名:" + obj.getKeyProperty("path")); + ObjectName objname = new ObjectName(obj.getCanonicalName()); + System.out.println("最大会话数:" + + mbsc.getAttribute(objname, "maxActiveSessions")); + System.out.println("会话数:" + + mbsc.getAttribute(objname, "activeSessions")); + System.out.println("活动会话数:" + + mbsc.getAttribute(objname, "sessionCounter")); + } + + // ----------------- Thread Pool ---------------- + ObjectName threadpoolObjName = new ObjectName( + "Catalina:type=ThreadPool,*"); + Set s2 = mbsc.queryNames(threadpoolObjName, null); + for (ObjectName obj : s2) { + System.out.println("端口名:" + obj.getKeyProperty("name")); + ObjectName objname = new ObjectName(obj.getCanonicalName()); + System.out.println("最大线程数:" + + mbsc.getAttribute(objname, "maxThreads")); + System.out.println("当前线程数:" + + mbsc.getAttribute(objname, "currentThreadCount")); + System.out.println("繁忙线程数:" + + mbsc.getAttribute(objname, "currentThreadsBusy")); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @SuppressWarnings({"resource" }) + public static String formatTimeSpan(long span) { + long minseconds = span % 1000; + + span = span / 1000; + long seconds = span % 60; + + span = span / 60; + long mins = span % 60; + + span = span / 60; + long hours = span % 24; + + span = span / 24; + long days = span; + return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d",days, hours, mins, seconds, minseconds).toString(); + } +} \ No newline at end of file diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemTest.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemTest.java new file mode 100644 index 0000000..b307aff --- /dev/null +++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemTest.java @@ -0,0 +1,11 @@ +package uk.co.jemos.experiments.jmx; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class MemTest { + public static void main(String[] args) { + + new ClassPathXmlApplicationContext("classpath:jemos-jmx-appCtx.xml"); + + } +} \ No newline at end of file diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryHeapFiller.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryHeapFiller.java new file mode 100644 index 0000000..368b96e --- /dev/null +++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryHeapFiller.java @@ -0,0 +1,22 @@ +package uk.co.jemos.experiments.jmx; + +import java.util.ArrayList; +import java.util.Collection; + +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class MemoryHeapFiller { + + private static final Collection GARBAGE = new ArrayList(); + + @Scheduled(fixedDelay = 2000) + public void addGarbage() { + System.out.println("Adding data..."); + for (int i = 0; i < 1000000; i++) { + GARBAGE.add(Math.random()); + } + } + +} diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryThreadDumper.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryThreadDumper.java new file mode 100644 index 0000000..8ec67d1 --- /dev/null +++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryThreadDumper.java @@ -0,0 +1,119 @@ +package uk.co.jemos.experiments.jmx; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +/** + * @author mtedone + * + */ +@Component +public class MemoryThreadDumper { + + // ------------------->> Constants + + /** The application logger */ + private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger + .getLogger(MemoryThreadDumper.class); + + // ------------------->> Instance / Static variables + + // ------------------->> Constructors + + // ------------------->> Public methods + + /** + * It dumps the Thread stacks + * + * @throws IOException + */ + public void dumpStacks() { + + // choose our dump-file + String stackFileName = "C:/tmp/stacks.dump"; + + ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] threadInfos = mxBean.getThreadInfo( + mxBean.getAllThreadIds(), 0); + Map threadInfoMap = new HashMap(); + for (ThreadInfo threadInfo : threadInfos) { + threadInfoMap.put(threadInfo.getThreadId(), threadInfo); + } + + File dumpFile = new File(stackFileName); + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new FileWriter(dumpFile)); + this.dumpTraces(mxBean, threadInfoMap, writer); + + LOG.warn("Stacks dumped to: " + stackFileName); + + } catch (IOException e) { + throw new IllegalStateException( + "An exception occurred while writing the thread dump"); + } finally { + IOUtils.closeQuietly(writer); + } + + } + + // ------------------->> Getters / Setters + + // ------------------->> Private methods + + private void dumpTraces(ThreadMXBean mxBean, + Map threadInfoMap, Writer writer) + throws IOException { + Map stacks = Thread.getAllStackTraces(); + writer.write("Dump of " + + stacks.size() + + " thread at " + + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z") + .format(new Date(System.currentTimeMillis())) + "\n\n"); + for (Map.Entry entry : stacks.entrySet()) { + Thread thread = entry.getKey(); + writer.write("\"" + thread.getName() + "\" prio=" + + thread.getPriority() + " tid=" + thread.getId() + " " + + thread.getState() + " " + + (thread.isDaemon() ? "deamon" : "worker") + "\n"); + ThreadInfo threadInfo = threadInfoMap.get(thread.getId()); + if (threadInfo != null) { + writer.write(" native=" + threadInfo.isInNative() + + ", suspended=" + threadInfo.isSuspended() + + ", block=" + threadInfo.getBlockedCount() + ", wait=" + + threadInfo.getWaitedCount() + "\n"); + writer.write(" lock=" + threadInfo.getLockName() + + " owned by " + threadInfo.getLockOwnerName() + " (" + + threadInfo.getLockOwnerId() + "), cpu=" + + mxBean.getThreadCpuTime(threadInfo.getThreadId()) + / 1000000L + ", user=" + + mxBean.getThreadUserTime(threadInfo.getThreadId()) + / 1000000L + "\n"); + } + for (StackTraceElement element : entry.getValue()) { + writer.write(" "); + writer.write(element.toString()); + writer.write("\n"); + } + writer.write("\n"); + } + } + + // ------------------->> equals() / hashcode() / toString() + + // ------------------->> Inner classes + +} diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryWarningService.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryWarningService.java new file mode 100644 index 0000000..1fceee3 --- /dev/null +++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryWarningService.java @@ -0,0 +1,116 @@ +package uk.co.jemos.experiments.jmx; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryType; + +import javax.annotation.PostConstruct; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; + +import org.springframework.beans.factory.annotation.Autowired; + +/** + * A component which sends notifications when the HEAP memory is above a certain + * threshold. + * + * @author mtedone + * + */ +public class MemoryWarningService implements NotificationListener { + + // ------------------->> Constants + + /** This bean's name */ + public static final String MBEAN_NAME = "jemos.mbeans:type=monitoring,name=MemoryWarningService"; + + /** The application logger */ + private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger + .getLogger(MemoryWarningService.class); + + @Autowired + private NotificationEmitter memoryMxBean; + + @Autowired + private MemoryThreadDumper threadDumper; + + // ------------------->> Instance / Static variables + + /** A pool of Memory MX Beans specialised in HEAP management */ + private static final MemoryPoolMXBean tenuredGenPool = findTenuredGenPool(); + + // ------------------->> Constructors + + // ------------------->> Public methods + + /** + * {@inheritDoc} + */ + @Override + public void handleNotification(Notification notification, Object handback) { + + if (notification.getType().equals( + MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) { + long maxMemory = tenuredGenPool.getUsage().getMax(); + long usedMemory = tenuredGenPool.getUsage().getUsed(); + LOG.warn("Memory usage low!!!"); + double percentageUsed = (double) usedMemory / maxMemory; + LOG.warn("percentageUsed = " + percentageUsed); + threadDumper.dumpStacks(); + + } else { + LOG.info("Other notification received..." + + notification.getMessage()); + } + + } + + // ------------------->> Getters / Setters + + /** + * It sets the threshold percentage. + * + * @param percentage + */ + public void setPercentageUsageThreshold(double percentage) { + if (percentage <= 0.0 || percentage > 1.0) { + throw new IllegalArgumentException("Percentage not in range"); + } else { + LOG.info("Percentage is: " + percentage); + } + long maxMemory = tenuredGenPool.getUsage().getMax(); + long warningThreshold = (long) (maxMemory * percentage); + tenuredGenPool.setUsageThreshold(warningThreshold); + } + + @PostConstruct + public void completeSetup() { + memoryMxBean.addNotificationListener(this, null, null); + LOG.info("Listener added to JMX bean"); + } + + // ------------------->> Private methods + + /** + * Tenured Space Pool can be determined by it being of type HEAP and by it + * being possible to set the usage threshold. + */ + private static MemoryPoolMXBean findTenuredGenPool() { + for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { + // I don't know whether this approach is better, or whether + // we should rather check for the pool name "Tenured Gen"? + if (pool.getType() == MemoryType.HEAP + && pool.isUsageThresholdSupported()) { + return pool; + } + } + throw new AssertionError("Could not find tenured space"); + } + + // ------------------->> equals() / hashcode() / toString() + + // ------------------->> Inner classes + +} diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/LoggerConfigurator.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/LoggerConfigurator.java new file mode 100644 index 0000000..7dc669c --- /dev/null +++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/LoggerConfigurator.java @@ -0,0 +1,71 @@ +package uk.co.jemos.experiments.jmx.mbeans; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedOperationParameter; +import org.springframework.jmx.export.annotation.ManagedOperationParameters; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.stereotype.Component; + +/** + * MBean which allows clients to change or retrieve the logging level for a + * Log4j Logger at runtime. + * + * @author mtedone + * + */ +@Component +@ManagedResource(objectName = LoggerConfigurator.MBEAN_NAME, // +description = "Allows clients to set the Log4j Logger level at runtime") +public class LoggerConfigurator { + + // ------------------->> Constants + + public static final String MBEAN_NAME = "jemos.mbeans:type=config,name=LoggingConfiguration"; + + // ------------------->> Instance / Static variables + + // ------------------->> Constructors + + // ------------------->> Public methods + + @ManagedOperation(description = "Returns the Logger LEVEL for the given logger name") + @ManagedOperationParameters({ @ManagedOperationParameter(description = "The Logger Name", name = "loggerName"), }) + public String getLoggerLevel(String loggerName) { + + Logger logger = Logger.getLogger(loggerName); + Level loggerLevel = logger.getLevel(); + + return loggerLevel == null ? "The logger " + loggerName + + " has not level" : loggerLevel.toString(); + + } + + @ManagedOperation(description = "Set Logger Level") + @ManagedOperationParameters({ + @ManagedOperationParameter(description = "The Logger Name", name = "loggerName"), + @ManagedOperationParameter(description = "The Level to which the Logger must be set", name = "loggerLevel") }) + public void setLoggerLevel(String loggerName, String loggerLevel) { + + Logger thisLogger = Logger.getLogger(this.getClass()); + thisLogger.setLevel(Level.INFO); + + Logger logger = Logger.getLogger(loggerName); + + logger.setLevel(Level.toLevel(loggerLevel, Level.INFO)); + + thisLogger.info("Set logger " + loggerName + " to level " + + logger.getLevel()); + + } + + // ------------------->> Getters / Setters + + // ------------------->> Private methods + + // ------------------->> equals() / hashcode() / toString() + + // ------------------->> Inner classes + +} diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/MemoryWarningServiceConfigurator.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/MemoryWarningServiceConfigurator.java new file mode 100644 index 0000000..0df6500 --- /dev/null +++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/MemoryWarningServiceConfigurator.java @@ -0,0 +1,62 @@ +package uk.co.jemos.experiments.jmx.mbeans; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedOperationParameter; +import org.springframework.jmx.export.annotation.ManagedOperationParameters; +import org.springframework.jmx.export.annotation.ManagedResource; +import org.springframework.stereotype.Component; + +import uk.co.jemos.experiments.jmx.MemoryWarningService; + +@Component +@ManagedResource(objectName = MemoryWarningServiceConfigurator.MBEAN_NAME, // +description = "Allows clients to set the memory threshold") +public class MemoryWarningServiceConfigurator implements + ApplicationContextAware { + + // ------------------->> Constants + + /** The application logger */ + private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger + .getLogger(MemoryWarningServiceConfigurator.class); + + public static final String MBEAN_NAME = "jemos.mbeans:type=config,name=MemoryWarningServiceConfiguration"; + + private ApplicationContext ctx; + + // ------------------->> Instance / Static variables + + // ------------------->> Constructors + + // ------------------->> Public methods + + @ManagedOperation(description = "Sets the memory threshold for the memory warning system") + @ManagedOperationParameters({ @ManagedOperationParameter(description = "The memory threshold", name = "memoryThreshold"), }) + public void setMemoryThreshold(double memoryThreshold) { + + MemoryWarningService memoryWarningService = (MemoryWarningService) ctx + .getBean("memoryWarningService"); + memoryWarningService.setPercentageUsageThreshold(memoryThreshold); + + LOG.info("Memory threshold set to " + memoryThreshold); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + ctx = applicationContext; + + } + + // ------------------->> Getters / Setters + + // ------------------->> Private methods + + // ------------------->> equals() / hashcode() / toString() + + // ------------------->> Inner classes + +} diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx-appCtx.xml b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtx.xml new file mode 100644 index 0000000..3602d56 --- /dev/null +++ b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtx.xml @@ -0,0 +1,78 @@ + + + + + + + + classpath:jemos-jmx.properties + classpath:jmxconnector-credentials.properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx-appCtxImpl.xml b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtxImpl.xml new file mode 100644 index 0000000..9409861 --- /dev/null +++ b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtxImpl.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx-experiments-0.0.1-snapshot-project.zip b/spring3-jmx-example/src/main/resources/jemos-jmx-experiments-0.0.1-snapshot-project.zip new file mode 100644 index 0000000..0583dbe Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jemos-jmx-experiments-0.0.1-snapshot-project.zip differ diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx.properties b/spring3-jmx-example/src/main/resources/jemos-jmx.properties new file mode 100644 index 0000000..0b5b109 --- /dev/null +++ b/spring3-jmx-example/src/main/resources/jemos-jmx.properties @@ -0,0 +1 @@ +jemos.jmx.rmi.port=8888 \ No newline at end of file diff --git a/spring3-jmx-example/src/main/resources/jmx-1.jpg b/spring3-jmx-example/src/main/resources/jmx-1.jpg new file mode 100644 index 0000000..7c59804 Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-1.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmx-2.jpg b/spring3-jmx-example/src/main/resources/jmx-2.jpg new file mode 100644 index 0000000..3cdc7b6 Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-2.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmx-3.jpg b/spring3-jmx-example/src/main/resources/jmx-3.jpg new file mode 100644 index 0000000..68bda79 Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-3.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-1.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-1.jpg new file mode 100644 index 0000000..1d7f9e2 Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-1.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-2.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-2.jpg new file mode 100644 index 0000000..c7699aa Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-2.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-3.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-3.jpg new file mode 100644 index 0000000..878d872 Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-3.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-4.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-4.jpg new file mode 100644 index 0000000..cecc461 Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-4.jpg differ diff --git a/spring3-jmx-example/src/main/resources/jmxconnector-credentials.properties b/spring3-jmx-example/src/main/resources/jmxconnector-credentials.properties new file mode 100644 index 0000000..d378df8 --- /dev/null +++ b/spring3-jmx-example/src/main/resources/jmxconnector-credentials.properties @@ -0,0 +1,2 @@ +jmx.username=jemosAdmin +jmx.password=secure \ No newline at end of file diff --git a/spring3-jmx-example/src/main/resources/jmxremote.access b/spring3-jmx-example/src/main/resources/jmxremote.access new file mode 100644 index 0000000..339402c --- /dev/null +++ b/spring3-jmx-example/src/main/resources/jmxremote.access @@ -0,0 +1 @@ +jemosAdmin readwrite \ No newline at end of file diff --git a/spring3-jmx-example/src/main/resources/jmxremote.password b/spring3-jmx-example/src/main/resources/jmxremote.password new file mode 100644 index 0000000..45587f8 --- /dev/null +++ b/spring3-jmx-example/src/main/resources/jmxremote.password @@ -0,0 +1 @@ +jemosAdmin secure \ No newline at end of file diff --git a/spring3-jmx-example/src/main/resources/log4j.properties b/spring3-jmx-example/src/main/resources/log4j.properties new file mode 100644 index 0000000..2876335 --- /dev/null +++ b/spring3-jmx-example/src/main/resources/log4j.properties @@ -0,0 +1,7 @@ +log4j.rootCategory=INFO, S + +log4j.logger.uk.co.jemos.experiments=INFO + +log4j.appender.S = org.apache.log4j.ConsoleAppender +log4j.appender.S.layout = org.apache.log4j.PatternLayout +log4j.appender.S.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n \ No newline at end of file diff --git a/spring3-jmx-example/src/test/java/uk/co/jemos/experiments/jmx/test/system/JmxStartupSystemTest.java b/spring3-jmx-example/src/test/java/uk/co/jemos/experiments/jmx/test/system/JmxStartupSystemTest.java new file mode 100644 index 0000000..3e75068 --- /dev/null +++ b/spring3-jmx-example/src/test/java/uk/co/jemos/experiments/jmx/test/system/JmxStartupSystemTest.java @@ -0,0 +1,59 @@ +package uk.co.jemos.experiments.jmx.test.system; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; + +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; + +import uk.co.jemos.experiments.jmx.mbeans.LoggerConfigurator; + +/** + * System test to test the JMX server startup + * + * @author mtedone + * + */ +@ContextConfiguration(locations = { "classpath:jemos-jmx-test-appCtxImpl.xml" }) +public class JmxStartupSystemTest extends AbstractJUnit4SpringContextTests { + + // ------------------->> Constants + + // ------------------->> Instance / Static variables + + @Autowired + private MBeanServerConnection mbeanClient; + + // ------------------->> Constructors + + // ------------------->> Public methods + + @Before + public void init() { + Assert.assertNotNull("The MBean Server client cannot be null!"); + Assert.assertNotNull("The Memory MX Bean cannot be null!"); + } + + @Test + public void helloWorld() throws Exception { + + ObjectName objectName = new ObjectName(LoggerConfigurator.MBEAN_NAME); + mbeanClient.invoke(objectName, "setLoggerLevel", new Object[] { + "uk.co.jemos.experiments", "TRACE" }, new String[] { + String.class.getName(), String.class.getName() }); + + } + // ------------------->> Getters / Setters + + // ------------------->> Private methods + + // ------------------->> equals() / hashcode() / toString() + + // ------------------->> Inner classes + +} diff --git a/spring3-jmx-example/src/test/resources/jemos-jmx-test-appCtxImpl.xml b/spring3-jmx-example/src/test/resources/jemos-jmx-test-appCtxImpl.xml new file mode 100644 index 0000000..de93956 --- /dev/null +++ b/spring3-jmx-example/src/test/resources/jemos-jmx-test-appCtxImpl.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/spring3-jmx-example/使用JMX监控Tomcat.md b/spring3-jmx-example/使用JMX监控Tomcat.md new file mode 100644 index 0000000..624e546 --- /dev/null +++ b/spring3-jmx-example/使用JMX监控Tomcat.md @@ -0,0 +1,84 @@ +# 使用JMX监控Tomcat + +## 1. 激活Tomcat的JMX远程配置 + +要通过JMX远程监控Tomcat,首先需要激活Tomcat的JMX远程配置。 + +① 先修改Tomcat的启动脚本,windows下为bin/catalina.bat(linux下为catalina.sh),添加以下内容,8999是jmxremote使用的端口号,第二个false表示不需要鉴权: + +```bash +set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false +set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG% +``` + +*要注意以上语句的位置不能太后面,可以加在【if "%OS%" == "Windows_NT" setlocal】一句后的大段的注释后面。* + +参考官方说明: + +[http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote](http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote) + +② 上面的配置是不需要鉴权的,如果需要鉴权则添加的内容为: + +```bash +set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access +set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG% +``` + +③ 然后复制并修改授权文件 + +$JAVA_HOME/jre/lib/management下有jmxremote.access和jmxremote.password的模板文件,将两个文件复制到$CATALINA_BASE/conf目录下 + +◆ 修改$CATALINA_BASE/conf/jmxremote.access 添加内容: + monitorRole readonly + controlRole readwrite + +◆ 修改$CATALINA_BASE/conf/jmxremote.password 添加内容: + monitorRole admin + controlRole admin + +注意: 如果进行了以上步骤导致Tomcat启动不了,那么很可能是密码文件的权限问题 + +需要修改jmxremote.password文件的访问权限,只有运行Tomcat的用户才能拥有访问权限 : + Windows的NTFS文件系统下,选中文件,点右键 -->“属性”-->“安全”--> 点“高级”--> 点“更改权限”--> 去掉“从父项继承....”--> 弹出窗口中选“删除”,这样就删除了所有访问权限。再选“添加”--> “高级”--> “立即查找”,选中你的用户(或用户组,如果选用户不行那就选用户组),例administrator,点“确定",“确定"。来到权限项目窗口,勾选“完全控制”,点“确定”,OK了。 + +官方的提示: + The password file should be read-only and only accessible by the operating system user Tomcat is running as. + +④ 重新启动Tomcat,在Windows命令行输入“netstat -a”查看配置的端口号是否已打开,如果打开,说明上面的配置成功了。 + +⑤ 使用jconsole测试JMX。 + +运行$JAVA_HOME/bin目录下的jconsole.exe,打开J2SE监视和管理控制台,然后建立连接,如果是本地的Tomcat则直接选择然后点击连接,如果是远程的,则进入远程选项卡,填写地址、端口号、用户名、口令即可连接。。Mbean属性页中给出了相应的数据,Catalina中是tomcat的,java.lang是jvm的。对于加粗的黑体属性值,需双击一下才可看内容。 + +![](src/main/resources/jmx-tomcat-1.jpg) + +![](src/main/resources/jmx-tomcat-2.jpg) + +使用远程连接查看tomcat + +![](src/main/resources/jmx-tomcat-3.jpg) + +![](src/main/resources/jmx-tomcat-4.jpg) + +## 2. 使用JMX监控Tomcat示例代码 + +```java +String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.10.93:8999/jmxrmi"; +JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); + +Map map = new HashMap(); +// 用户名密码,在jmxremote.password文件中查看 +String[] credentials = new String[] { "monitorRole", "admin" }; +map.put("jmx.remote.credentials", credentials); +JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map); +MBeanServerConnection mbsc = connector.getMBeanServerConnection(); + +// 端口最好是动态取得 +ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8080"); +MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName); + +// tomcat的线程数对应的属性值 +String attrName = "currentThreadCount"; +MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes(); +System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName)); +``` \ No newline at end of file diff --git a/spring3-mvc-simple/.gitignore b/spring3-mvc-simple/.gitignore new file mode 100644 index 0000000..dcf31b9 --- /dev/null +++ b/spring3-mvc-simple/.gitignore @@ -0,0 +1,6 @@ +/target +/.classpath +/.project +/.gradle +/.settings +/build diff --git a/spring3-mvc-simple/build.gradle b/spring3-mvc-simple/build.gradle new file mode 100644 index 0000000..164a1a7 --- /dev/null +++ b/spring3-mvc-simple/build.gradle @@ -0,0 +1,16 @@ +apply plugin: 'war' +apply plugin: 'jetty' +apply plugin: 'eclipse-wtp' + +repositories { + mavenCentral() +} + +dependencies { + providedCompile 'javax.servlet:servlet-api:2.5' + compile 'org.springframework:spring-webmvc:3.2.2.RELEASE' + runtime 'javax.servlet:jstl:1.1.2' +} + +/* Change context path (base url). otherwise defaults to name of project */ +jettyRunWar.contextPath = '' \ No newline at end of file diff --git a/spring3-mvc-simple/pom.xml b/spring3-mvc-simple/pom.xml new file mode 100644 index 0000000..81a626b --- /dev/null +++ b/spring3-mvc-simple/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + maven-framework-project + net.aimeizi + 1.0.0 + + + net.aimeizi.springmvc.example + spring3-mvc-simple + war + + spring3-mvc-simple + http://maven.apache.org + + + + servlet-api + javax.servlet + 2.5 + provided + + + + spring-webmvc + org.springframework + 3.2.2.RELEASE + + + + jstl + javax.servlet + 1.1.2 + + + + + spring3-mvc-simple + + + org.eclipse.jetty + jetty-maven-plugin + 9.2.1.v20140609 + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + 2.2 + + + + org.apache.tomcat.maven + tomcat6-maven-plugin + 2.2 + + + + + + + + diff --git a/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/controller/SampleController.java b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/controller/SampleController.java new file mode 100644 index 0000000..0aeafd3 --- /dev/null +++ b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/controller/SampleController.java @@ -0,0 +1,15 @@ +package org.spring3.mvc.simple.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class SampleController { + + @RequestMapping("home") + public String loadHomePage(Model m) { + m.addAttribute("name", "SpringMVC"); + return "home"; + } +} diff --git a/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/springconfig/WebConfig.java b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/springconfig/WebConfig.java new file mode 100644 index 0000000..2aac7c6 --- /dev/null +++ b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/springconfig/WebConfig.java @@ -0,0 +1,22 @@ +package org.spring3.mvc.simple.springconfig; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +@Configuration +@EnableWebMvc +@ComponentScan(basePackages = "org.spring3.mvc.simple.controller") +public class WebConfig { + + @Bean + public InternalResourceViewResolver viewResolver() { + InternalResourceViewResolver resolver = new InternalResourceViewResolver(); + resolver.setPrefix("/WEB-INF/view/"); + resolver.setSuffix(".jsp"); + return resolver; + } + +} diff --git a/spring3-mvc-simple/src/main/resources/sample-servlet.xml b/spring3-mvc-simple/src/main/resources/sample-servlet.xml new file mode 100644 index 0000000..2f1d7a4 --- /dev/null +++ b/spring3-mvc-simple/src/main/resources/sample-servlet.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring3-mvc-simple/src/main/webapp/WEB-INF/view/home.jsp b/spring3-mvc-simple/src/main/webapp/WEB-INF/view/home.jsp new file mode 100644 index 0000000..21dbc67 --- /dev/null +++ b/spring3-mvc-simple/src/main/webapp/WEB-INF/view/home.jsp @@ -0,0 +1,9 @@ + + + + Sample Application + + +

Hello, ${name}!

+ + \ No newline at end of file diff --git a/spring3-mvc-simple/src/main/webapp/WEB-INF/web.xml b/spring3-mvc-simple/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..ae339c0 --- /dev/null +++ b/spring3-mvc-simple/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,26 @@ + + + + + sample + + org.springframework.web.servlet.DispatcherServlet + + + contextClass + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + contextConfigLocation + org.spring3.mvc.simple.springconfig + + + + + sample + / + + + \ No newline at end of file diff --git a/spring3-mvc-simple/src/main/webapp/WEB-INF/webxml.xml b/spring3-mvc-simple/src/main/webapp/WEB-INF/webxml.xml new file mode 100644 index 0000000..80345d1 --- /dev/null +++ b/spring3-mvc-simple/src/main/webapp/WEB-INF/webxml.xml @@ -0,0 +1,22 @@ + + + + + sample + + org.springframework.web.servlet.DispatcherServlet + + + contextConfigLocation + /WEB-INF/sample-servlet.xml + + + + + sample + / + + + \ No newline at end of file diff --git a/spring3-rmi-example/.gitignore b/spring3-rmi-example/.gitignore new file mode 100644 index 0000000..9dff9cc --- /dev/null +++ b/spring3-rmi-example/.gitignore @@ -0,0 +1,4 @@ +/.project +/.settings +/target +/.classpath diff --git a/spring3-rmi-example/pom.xml b/spring3-rmi-example/pom.xml new file mode 100644 index 0000000..30ea2d8 --- /dev/null +++ b/spring3-rmi-example/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + + net.aimeizi + maven-framework-project + 1.0.0 + + spring3-rmi-example + + + + 3.1.1.RELEASE + + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + + log4j + log4j + 1.2.16 + + + + \ No newline at end of file diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/CacheService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/CacheService.java new file mode 100644 index 0000000..93c81a3 --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/CacheService.java @@ -0,0 +1,29 @@ +package net.aimeizi.rmi.cache.service; + +import java.util.concurrent.ConcurrentHashMap; + +import net.aimeizi.rmi.model.User; + +public class CacheService implements ICacheService { + + ConcurrentHashMap userMap; + + /** + * Get User Map + * + * @return ConcurrentHashMap User Map + */ + public ConcurrentHashMap getUserMap() { + return userMap; + } + + /** + * Set User Map + * + * @param ConcurrentHashMap User Map + */ + public void setUserMap(ConcurrentHashMap userMap) { + this.userMap = userMap; + } + +} diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/ICacheService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/ICacheService.java new file mode 100644 index 0000000..d5fb5fb --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/ICacheService.java @@ -0,0 +1,16 @@ +package net.aimeizi.rmi.cache.service; + +import java.util.concurrent.ConcurrentHashMap; + +import net.aimeizi.rmi.model.User; + +public interface ICacheService { + + /** + * Get User Map + * + * @return ConcurrentHashMap User Map + */ + public ConcurrentHashMap getUserMap(); + +} diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/client/RMIServiceClient.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/client/RMIServiceClient.java new file mode 100644 index 0000000..66c0fae --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/client/RMIServiceClient.java @@ -0,0 +1,46 @@ +package net.aimeizi.rmi.client; + +import net.aimeizi.rmi.model.User; +import net.aimeizi.rmi.server.IRMIUserService; +import net.aimeizi.rmi.server.RMIUserService; + +import org.apache.log4j.Logger; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class RMIServiceClient { + + private static Logger logger = Logger.getLogger(RMIUserService.class); + + /** + * Main method of the RMI Service Client + * + */ + public static void main(String[] args) { + + logger.debug("RMI Service Client is starting..."); + + //RMI Client Application Context is started... + ApplicationContext context = new ClassPathXmlApplicationContext("rmiClientAppContext.xml"); + + //Remote User Service is called via RMI Client Application Context... + IRMIUserService rmiClient = (IRMIUserService) context.getBean("RMIUserService"); + + //New User is created... + User user = new User(); + user.setId(1); + user.setName("Bruce"); + user.setSurname("Willis"); + + //The user is added to the remote cache... + rmiClient.addUser(user); + + //The users are gotten via remote cache... + rmiClient.getUserList(); + + //The user is deleted from remote cache... + rmiClient.deleteUser(user); + + logger.debug("RMI Service Client is stopped..."); + } +} diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/model/User.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/model/User.java new file mode 100644 index 0000000..bd85314 --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/model/User.java @@ -0,0 +1,77 @@ +package net.aimeizi.rmi.model; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public class User implements Serializable { + + private long id; + private String name; + private String surname; + + /** + * Get User Id + * + * @return long id + */ + public long getId() { + return id; + } + + /** + * Set User Id + * + * @param long id + */ + public void setId(long id) { + this.id = id; + } + + /** + * Get User Name + * + * @return long id + */ + public String getName() { + return name; + } + + /** + * Set User Name + * + * @param String + * name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Get User Surname + * + * @return long id + */ + public String getSurname() { + return surname; + } + + /** + * Set User Surname + * + * @param String + * surname + */ + public void setSurname(String surname) { + this.surname = surname; + } + + @Override + public String toString() { + StringBuilder strBuilder = new StringBuilder(); + strBuilder.append("Id : ").append(getId()); + strBuilder.append(", Name : ").append(getName()); + strBuilder.append(", Surname : ").append(getSurname()); + return strBuilder.toString(); + } + +} diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/IRMIUserService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/IRMIUserService.java new file mode 100644 index 0000000..5f08d02 --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/IRMIUserService.java @@ -0,0 +1,32 @@ +package net.aimeizi.rmi.server; + +import java.util.List; + +import net.aimeizi.rmi.model.User; + +public interface IRMIUserService { + + /** + * Add User + * + * @param User user + * @return boolean response of the method + */ + public boolean addUser(User user); + + /** + * Delete User + * + * @param User user + * @return boolean response of the method + */ + public boolean deleteUser(User user); + + /** + * Get User List + * + * @return List user list + */ + public List getUserList(); + +} diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/RMIUserService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/RMIUserService.java new file mode 100644 index 0000000..6f4e01f --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/RMIUserService.java @@ -0,0 +1,72 @@ +package net.aimeizi.rmi.server; + +import java.util.ArrayList; +import java.util.List; + +import net.aimeizi.rmi.cache.service.ICacheService; +import net.aimeizi.rmi.model.User; + +import org.apache.log4j.Logger; + +public class RMIUserService implements IRMIUserService { + + private static Logger logger = Logger.getLogger(RMIUserService.class); + + //Remote Cache Service is injected... + ICacheService cacheService; + + /** + * Add User + * + * @param User user + * @return boolean response of the method + */ + public boolean addUser(User user) { + getCacheService().getUserMap().put(user.getId(), user); + logger.debug("User has been added to cache. User : "+getCacheService().getUserMap().get(user.getId())); + return true; + } + + /** + * Delete User + * + * @param User user + * @return boolean response of the method + */ + public boolean deleteUser(User user) { + getCacheService().getUserMap().put(user.getId(), user); + logger.debug("User has been deleted from cache. User : "+user); + return true; + } + + /** + * Get User List + * + * @return List user list + */ + public List getUserList() { + List list = new ArrayList(); + list.addAll(getCacheService().getUserMap().values()); + logger.debug("User List : "+list); + return list; + } + + /** + * Get RMI User Service + * + * @return IRMIUserService RMI User Service + */ + public ICacheService getCacheService() { + return cacheService; + } + + /** + * Set RMI User Service + * + * @param IRMIUserService RMI User Service + */ + public void setCacheService(ICacheService cacheService) { + this.cacheService = cacheService; + } + +} diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/starter/RMIServerStarter.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/starter/RMIServerStarter.java new file mode 100644 index 0000000..f418991 --- /dev/null +++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/starter/RMIServerStarter.java @@ -0,0 +1,11 @@ +package net.aimeizi.rmi.server.starter; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class RMIServerStarter { + + public static void main(String[] args) { + new ClassPathXmlApplicationContext("rmiServerAppContext.xml"); + } + +} diff --git a/spring3-rmi-example/src/main/resources/log4j.xml b/spring3-rmi-example/src/main/resources/log4j.xml new file mode 100644 index 0000000..6d99593 --- /dev/null +++ b/spring3-rmi-example/src/main/resources/log4j.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/spring3-rmi-example/src/main/resources/rmiClientAppContext.xml b/spring3-rmi-example/src/main/resources/rmiClientAppContext.xml new file mode 100644 index 0000000..67396c8 --- /dev/null +++ b/spring3-rmi-example/src/main/resources/rmiClientAppContext.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/spring3-rmi-example/src/main/resources/rmiServerAppContext.xml b/spring3-rmi-example/src/main/resources/rmiServerAppContext.xml new file mode 100644 index 0000000..412bda9 --- /dev/null +++ b/spring3-rmi-example/src/main/resources/rmiServerAppContext.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +