Too long has not written something, today share a Java web of our simple dynamic load jar package, no need to hot deployment and update the previous class to go online Service application, Java's reflection mechanism content here do not do science (below the basic no code, only provide ideas, code Party bypass).
Environment: Java8+tomcat (the class plus in Tomcat is not the same as the loader of the javase, it is not considered);
Data interaction: WebService (JSON)
Idea: We all know that in general, Javaweb normal operation needs to be compiled into a class file to explain the operation, many times the system updates need to restart the service or service automatic hot deployment, regardless of the two modes, will make the session failure and some of the tasks are interrupted.
PHP is popular, not only the scripting language does not need to compile, and which module needs to update only need to update a file without the need to restart the service can be seamlessly updated. Based on this advantage, the idea is to use Java dynamic load mode + JSP script mode for project deployment, update, as far as possible to achieve code security.
When we create a web app, we need to update the class if there is a logic error inside the class, and the Web app needs to be restarted, but in fact, there are fewer opportunities to give you in a production environment, unless you can control the user for a period of time. Sometimes think that if you write a JSP script, it will appear that the code level is very low (as long as the security, fast, elegant, JSP is also a good choice), so every day until 12 o'clock late at night will not interrupt the system to update.
In fact, just load the jar file dynamically and update it regularly:
/* * to change this license header, choose license headers In project properties. * to change this template file, choose Tools | Templates * and open the template in the editor. */package cn.skyatom.dynamicloader;import java.lang.reflect.method;import java.net.url;import java.net.urlclassloader;import sun.misc.classloaderutil;/** * Dynamic load Reflection mechanism loader * * @author ZWK */public class Loader { /** * Global Jar Pack Loader */ private static java.util.map<string, urlclassloader> globjarloader = new java.util.HashMap<String, URLClassLoader> (); /** * get all the loaders &NBSP;&NBSP;&NBsp; * @return */ public static java.util.list<urlclassloader> getallclassloader () { java.util.iterator<urlclassloader> lds = globjarloader.values (). Iterator (); java.util.list<urlclassloader> list = new java.util.ArrayList<URLClassLoader> ( while); Lds.hasnext ()) {&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;URLCLASSLOADER&NBSP;CL = lds.next (); list.add (CL); } return list; } /** * implementing a method with parametric constructors * * @param jarid jar Bag id * @ param clazname Full class name * @param methodname Execution Method * @param ctypes constructor parameter types * @param cvalues constructor parameter values * @param types parameter Types * @param values parameter values * @return * @throws java.lang.exception */ public static object excmethod (string jarid, string clazname, string Methodname, class<?>[] ctypes, object[] cvalues, class<?>[] types, object[] values) throws Exception { Urlclassloader loader =&nBsp;globjarloader.get (Jarid); if (loader == null ) { return null; } Class<?> Myclaz = loader.loadclass (clazname); object c = myclaz.getconstructor (ctypes). newinstance (cvalues); method m = myclaz.getmethod (methodname, types); object rs = m.invoke (c, values); c = null; return rs; } /** * methods for executing empty constructors * * @param jarid jar Package id * @param clazname full class name * @param methodname method names * @param types parameter Types * @param values parameter values * @return */ public static object excmethod (string jarid, string clazname, string methodname, class<?> [] types, object[] values) throws Exception { urlclassloader loader = globjarloader.get (Jarid); if (loader == null) { return null; } Class<?> myclaz = loader.loadclass (Clazname); object c = myclaz.newinstance (); method m = myclaz.getmethod (methodname, types); Object rs = m.invoke (c, values); c = null; return rs; } /** * Execute static methods * * @param jarid jar bag id * @param clazname Full class name * @param methodname method name * @param types parameter types * @param values parameter values * @return */ public static object Excstaticmethod (string jarid, string clazname, string methodname, class<?> [] types, object[] values) throws Exception { urlclassloader loader = globjarloader.get (Jarid); if (loader == null) { return null; } class<?> myclaz = loader.loadclass (Clazname); method m = myclaz.getmethod (methodname, types); object rs = m.invoke (null, values); return rs; } /** * To execute a method with a parametric constructor * * @param obj objects * @param methodname Execution Methods * @param ctypes constructor parameter types * @param cvalues constructor parameter values * @param types parameter types * @param values parameter values * @return * @throws Java.lang.exception */ public static object excmethodbyobject (Bindclaz obj, string methodname, class<?>[] ctypes, object[] cvalues, class<?>[] types, object[] values) throws Exception { class<?> myclaz = obj.cclaz; object c = obj.cobject; method m = myclaz.getmethod (methodname, types); object rs = m.invoke (c, values); c = null; return rs; } /** * methods for executing empty constructors * * @param obj * @param methodname method name * @param types parameter types * @param values parameter values * @return */ public static objEct excmethodbyobject (Bindclaz obj, string methodname, class<?>[] types, object[] values) throws Exception { Class<?> myclaz = obj.cclaz; object c = obj.cObject; Method m = Myclaz.getmethod (methodname, types); object rs = m.invoke (c, values); c = null; return rs; } /** * Execute static method * * @ Param jarid jar Package id * @param clazname full class name * @param methodname method name * @param types parameter Types * @param values parameter values * @return */ public static object excstaticmethodbyobject (BindClaz obj, string methodname, class<?>[] types, object[] values) throws exception { class<?> myclaz = obj.cclaz; method m = myclaz.getmethod ( Methodname, types); object rs = m.invoke ( null, values); return rs; } /** * Create Objects * * @param &Nbsp;jarid jar Package id * @param clazname full class name * @param ctypes parameter types * @param cvalues Parameter values * @return */ public static bindclaz createobject (string jarid, string clazname, class<?> [] ctypes, object[] cvalues) throws Exception { urlclassloader loader = globjarloader.get (Jarid); if (loader == null) { return null; } class<?> myclaz = loader.loadclass (Clazname); if (ctypes != null) { object c = myclaz.getconstructor (ctypes). newinstance (cvalues); bindclaz bc = new bindclaz (); bc.cClaz = myclaz; bc.cObject = c; return bc; } else { object c = myclaz.newinstance (); bindclaz bc = new bindclaz (); bc.cClaz = myclaz; bc.cobject = c ; return bc; } } /** * release all jar packages */ public static void &NBSP;RELEASEALLJARPCK () { if (globjarloader == null) { return; } java.util.Iterator< String> jids = globjarloader.keyset (). Iterator (); while (Jids.hasnext ()) { string jid =&nbsP;jids.next (); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;RELEASEJARPCK (Jid); } Globjarloader.clear (); } /** * Release Package Resources * * @param jarid &NBSP;&NBSP;&NBSP;*/&NBSP;&NBSP;&NBSP;&NBSP;PUBLIC&NBSP;STATIC&NBSP;VOID&NBSP;RELEASEJARPCK (String jarid) { if (Globjarloader.get (Jarid) != null) {// classloaderutil.releaseloader (Globjarloader.get (Jarid));//Release Loader Globjarloader.remove (Jarid); } } /** * loading * * @param jarid from Web protocol * @param weburl * @throws exception */ public static void Loadjarpckbyweb (String jarid, string weburl) throws Exception { if (Globjarloader.get (Jarid) != null) { classloaderutil.releaseloader (GlobJarLoader.get ( Jarid));//Release Loader } url jarurl = new java.net.url (Weburl); urlclassloader myclassloader = new urlclassloader (new URL[]{jarurl}, Thread.CurrentThread (). Getcontextclassloader ()); &nbsP; globjarloader.put (Jarid, myclassloader); } /** * Load Jar Package Resource * * @param jarid jar Bag id * @param jarpath jar package file path * @throws Exception &NBSP;*/&NBSP;&NBSP;&NBSP;&NBSP;PUBLIC&NBSP;STATIC&NBSP;VOID&NBSP;LOADJARPCK (String jarid, String jarpath) throws Exception { if ( Globjarloader.get (Jarid) != null) { classloaderutil.releaseloader (Globjarloader.get (Jarid));//Release Loader } URL jarurl = new Java.io.File (Jarpath). Touri (). ToURL (); urlclassloader myclassloader = new URLClassLoader (New url[]{jarurl}, thread.currentthread (). Getcontextclassloader ()); globjarloader.put (Jarid, myclassloader); } /** * classes created by bindings */ public static class BindClaz { public object cobject = null;//objects created by reflection public class<?> cclaz = null;//current class }}
A simple dynamic load execution method, followed by a required code generator, will save development time and the corresponding operational efficiency:
The last generated code is put into the JSON file (JSP map), just fill in the corresponding parameters.
* * For Web applications, I wrote a timer in the app that regularly updates the latest version of the Jar expansion pack, and once there is an updated logic business, there is no need to restart the application or load (the load will have to be done sooner or later, if the condition permits).
I hope to give a little inspiration to the students who read here.
Redundant code also does not paste, based on the above thinking estimated to spend a few hours, you can also write a dynamic loading module about OK. Who says that Java cannot be developed as quickly as PHP, and that it can walk in a different way
Javaweb No hot deployment extension