How to install plugins in java?
I'm not learning how to do wordpress plugins, I suddenly have a question about how to install the plugin in java. Previously, only follow the style of request to write to it, but never made this type of plugin ever. Ask Mr. Gúc. After a digging digging, I also called to grab some parts, note here for me to ask the same questions.
What is a plugin?
Saying that, the plugin is not strange, typically like the popular browser types like Chrome, Firefox, Opera do not install a bunch of plugins every time when the browser has nothing unusual to pull the first few plugins. check out first. Simply put, Plugin is a set of software to support, extending the functionality of a larger application software, based on the game but the protocol and API provided by the big software.
What's the plugin interesting?
The plugin architecture is really great, it allows extensions (even changes) of the functions of the host applications (temporarily called the master application), with a well-designed plug-in applications How many custom functions each plugin brings to a utility that extends the system's capabilities is extremely great, I would like to chew it again and have to design it well. there.
With the open source community evolving today, with a good base application and a dark API plugin, the development speed will be unbelievable. For example, the slack of a very popular messaging and exchange system is only a few years old, but the number of plugins in the slack repository has been huge, mostly by third parties, really. Increasing the value of the original application by many times and a team cannot do it all.
Then, how to install this guy?
For script languages such as Javascript, PHP, python … with the characteristics of each run is a translation , it seems there is no problem just using a callback guy to finish this I will talk about on a beautiful day not far. With Java the story may not seem so easy, Java doesn't have a callback or anything, I'm a Java chicken so I found this a little bit sweet.
Basically to be able to plug in the plugin, the application must have the simplest architecture as shown in the image above, the two basic components are application core and plugin manager :
– application core: this guy is the master application responsible for ensuring system logic, performing tasks and hook plugins that perform their tasks at runtime.
– plugins manager: the guy who is under the direction of the core is responsible for registering plugins to add, remove, turn on, turn off the plugins.
In order to be able to plug in the plugin, we must have an interface plugin, which is the interface that all plugins will inherit, plugin manager loads the plugins and initials (this is to create the entity of each plugin) into a List Then plugins from which application core will be removed from the first one and force it to perform certain tasks.
Well, I explain the banana too much, no one understands it. For visually vivid invites see the example below.
An intuitive example
In this example, I will create a single application with 1 number input, the plugins will be added to that variable to produce the final result plus subtract multiplication.
Ok, first we have to have a common interface guy for plugins. temporarily called PluginFunction.java
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public interface PluginFunction { // let the application pass in a parameter public void setParameter (int param); // lấy một Result từ plugin public int getResult (); // return the name of this plugin public String getPluginName (); // có thể được gọi để quyết định nếu plugin // aborted execution due to an error condition public boolean hasError (); } |
Next we have to have a main to run the application logic and call the plugins, called PluginDemo.java
contains the main function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import java.io.File; import java.util. *; public class PluginDemo { // parameter for plugins int count; // the directory where we keep the plugin classes String pluginsDir; // a list where we keep an initialized object của mỗiclass plugin List plugins; public static void main (String args []) { PluginDemo demo = new PluginDemo (args); demo.getPlugins (); demo.runPlugins (); } PluginDemo (String args []) { if (args.length> 0) count = Integer.parseInt (args [0]); else count = 1; if (args.length> 1) pluginsDir = args [0]; else pluginsDir = "plugins"; plugins = new ArrayList (); System.setSecurityManager (new PluginSecurityManager (pluginsDir)); } protected void getPlugins () { File dir = new File (System.getProperty ("user.dir") + File.separator + pluginsDir); ClassLoader cl = new PluginClassLoader (dir); if (dir.exists () && dir.isDirectory ()) { // we'll only load classes directly in this directory - // no subdirectories, and không nhận ra các gói theo đây String [] files = dir.list (); for (int i = 0; i <files.length; i ++) { try { // only consider ending files in ".class" if (! files [i] .endsWith (". class")) tiếp tục; Class c = cl.loadClass (files [i] .substring (0, files [i] .indexOf ("."))); Class [] intf = c.getInterfaces (); for (int j = 0; j <intf.length; j ++) { if (intf [j] .getName (). equals ("PluginFunction")) { // the following line assumes that PluginFunction có một tham số không-đối số PluginFunction pf = (PluginFunction) c.newInstance (); plugins.add (pf); tiếp tục; } } } catch (Exception ex) { System.err.println ("File" + files [i] + "does not contain a PluginFunction valid class."); } } } } protected void runPlugins () { Iterator iter = plugins.iterator (); while (iter.hasNext ()) { PluginFunction pf = (PluginFunction) iter.next (); try { pf.setParameter (count); System.out.print (pf.getPluginName ()); System.out.print ("(" + count + ") ="); if (pf.hasError ()) { System.out.println ("there was an error during plugin initialization"); tiếp tục; } int result = pf.getResult (); if (pf.hasError ()) System.out.println ("there was an error during plugin execution"); else System.out.println (result); count ++; } catch (SecurityException secEx) { System.err.println ("plugin" "+ pf.getClass (). GetName () +" 'tried to do something illegal "); } } } } |
I see in getPlugins
a for loop to load all of the classes that the interface is PluginFunction
then create an instance of that class and stored in an array plugins
. Then the runPlugins
function will browse all the plugins set parameters that run the run function of each plugin and print out the results.
In addition, the getPlugins
function has one more interesting thing: the setSecurityManager line, because these are plugins independent of the system, we have to consider it, but if any young person is happy for the plugin to remove the operating system. I just sat there crying .
This is the content of PluginSecurityManager.java
file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | import java.io.File; / ** * This is a fairly uptight security manager subclass. Classes loaded by * The PluginClassLoader is highly restricted in what they are allowed to do. * This is okay, vì bạn chỉ định để xác định một giá trị, * cho đó cần thiết dữ liệu đã được sẵn sàng * * Một chế độ SecurityManager của các phương pháp khác nhiều các hệ thống cần thiết * check whether operations sensitivity should nên được phép. These * phương pháp không thể bỏ qua SecurityException để xử lý chế độ từ * happening. With this SecurityManager, we want to prevent untrusted * mã số đã được nạp bởi một nạp ảnh nào từ hiện thời các tài khoản cho. * So we use inherited SecurityManager method để kiểm tra có calls là đang được * made by an untrusted class. Nếu nó là, cần throw một exception. * Không có, bạn chỉ thực hiện, để tiếp tục khi hành động này. * / public class PluginSecurityManager extends SecurityManager { private String pluginDir = null; PluginSecurityManager (String dir) { pluginDir = dir; } / ** * Đây là phương pháp cơ sở dữ liệu mà thử có thể nạp một trường này * by a ClassLoader anywhere on the stack. Nếu thì, nó có nghĩa là * untrusted code is trying to perform some kind of sensitive operation. * We bị bỏ qua nó đang chạy mà thao tác bởi throwing không đúng. * trusted () is referred to by most of xác thực ... () phương pháp sau. * / protected void trusted () { if (inClassLoader ()) throw new SecurityException (); } / ** * Bạn có thể kiểm tra các sự kiểm tra một trình phục vụ cho phép * perform. Bạn cần phải chỉ một một của các phương pháp này và gỡ bỏ một * SecurityException if the operation is không được phép. This * SecurityManager subclass is probably a little too restrictive. For * example, it doesn't allow loading code to đọc * nào * hệ thống properties, * even though some of them are quite harmless. * / public void checkCreateClassLoader () {trusted (); } public void checkAccess (Thread g) {trusted (); } public void checkAccess (ThreadGroup g) {trusted (); } public void checkExit (int status) {throw new SecurityException ("Not allowed."); } public void checkExec (String cmd) {trusted (); } public void checkLink (String lib) {trusted (); } public void checkRead (java.io.FileDescriptor fd) {trusted (); } public void checkRead (String file) { // String path = new File (file) .getParentFile (). GetAbsolutePath (); // if (! path.endsWith (pluginDir)) trusted (); } public void checkRead (String file, Object context) {trusted (); } public void checkWrite (java.io.FileDescriptor fd) {trusted (); } public void checkWrite (String file) {trusted (); } public void checkDelete (String file) {trusted (); } public void checkConnect (String host, int port) {trusted (); } public void checkConnect (String host, int port, Object context) {trusted ();} public void checkListen (int port) {trusted (); } public void checkAccept (String host, int port) {trusted (); } public void checkMulticast (java.net.InetAddress maddr) {trusted (); } public void checkMulticast (java.net.InetAddress maddr, byte ttl) {trusted (); } public void checkPropertiesAccess () {trusted (); } public void checkPropertyAccess (String key) { // if (! key.equals ("user.dir")) trusted (); } public void checkPrintJobAccess () {trusted (); } public void checkSystemClipboardAccess () {trusted (); } public void checkAwtEventQueueAccess () {trusted (); } public void checkSetFactory () {trusted (); } public void checkMemberAccess (Class clazz, int which) {trusted (); } public void checkSecurityAccess (String provider) {trusted (); } / ** Code loaded chỉ có thể nạp các từ khóa từ java. * Gói * / public void checkPackageAccess (String pkg) { if (inClassLoader () &&! pkg.startsWith ("java.") &&! pkg.startsWith ("javax.")) throw new SecurityException (); } / ** Loaded code không thể xác định các lớp trong java. * Hay sun. * Gói * / public void checkPackageDefinition (String pkg) { if (inClassLoader () && ((pkg.startsWith ("java.") || pkg.startsWith ("javax.") || pkg.startsWith ("sun.")))))) throw new SecurityException (); } / ** * This is a SecurityManager method that is different from the * others. Hãy xác định có một bảng đầu-cấp đầu nên hiển thị * "untrusted" warning. Người dùng cửa sổ có thể được tạo, vì * này phương pháp không thể xác định cần throw exception. Có nên * trả true khi cửa sổ không phải cần hiển thị cảnh báo, và * false if it does. Trong mẫu này, Tuy nhiên, our text-based Service * classes should never need to create windows, so we will actually * không thể exception để gỡ bỏ nào nào trong việc mở. ** / public boolean checkTopLevelWindow (Object window) { trusted (); return true; } } |
In addition, we need a loader to load additional plugins PluginClassLoader.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import java.io. *; / ** * In order để impose Tight chế độ chế độ quyền hạn các nhưng * không phải trong các hệ thống hệ thống, bạn có thể được gỡ bỏ giữa * those types of classes. Đây được thực hiện giữ lại track của cách các trường * được nạp vào hệ thống. Bởi lời xác định, nào nào nào nào được đọc * tải directly từ các CLASSPATH được xác nhận. Bạn có thể không thể * load untrusted code in that way - we can't load it with Class.forName (). * Instead, we create a ClassLoader subclass to load the untrusted code. * Đây một phần đầu từ một thư mục đã xác định (mà nên không * be part of the CLASSPATH). * / public class PluginClassLoader extends ClassLoader { / ** This is the directory from which classes will be loaded * / Directory file; / ** The constructor. Chỉ initialize thư mục * / public PluginClassLoader (File dir) { directory = dir; } / ** A convenience method that yêu cầu mẫu 2-đối số của này phương pháp * / public Class loadClass (String name) throws ClassNotFoundException { return loadClass (name, true); } / ** * This is an abstract method of ClassLoader that all subclasses must * define. Đây là việc để nạp một chuỗi của byte từ ở bên và tới * pass them to defineClass (). Nếu xác định đối số là true, nó phải * also call resolveClass (), which will do things like verify the presence * of the superclass. Vì này này step step, này phương pháp có thể được gọi tới * nạp siêuclass này là hệ thống tập tin, và nó cần đặt này vào tài khoản. * / public Class loadClass (String classname, boolean resolve) throws ClassNotFoundException { try { // Our ClassLoader superclass has a built-in cache of it has // đã được nạp So, first check the cache. Class c = findLoadedClass (classname); Tài liệu sau sau này tải một giá trị, nó sẽ được xác định lại vào // load the superclasses. Since these classes are systems, we have // got để thể được nạp các số này. So hãy thử đến nạp như là class // a class system (ie từ các CLASSPATH) và bỏ qua các lỗi if (c == null) { try {c = findSystemClass (classname); } catch (Exception ex) {} } // If đối tượng không tìm thấy bởi hay của chế độ hiện thời, Then // hãy thử tải nó từ một tập tin trong (hoặc dưới đây) những thư mục // đã xác định khi đối tượng ClassLoad này được tạo. Form the // filename by thay đổi đầu tiên trong tên tên với // (platform-independent) separators file and by adding the ".class" extension. if (c == null) { // Figure out the filename String filename = classname.replace ('.', File.separatorChar) + ". Class"; // Create a File object. Interpret the filename relative to the // thư mục được ghi rõ cho Phần này này. File f = new File (directory, filename); // Get the length của tập tin hệ thống, cấp phát một đối số của byte cho // it, và đọc nó trong tất cả một lần. int length = (int) f.length (); byte [] classbytes = new byte [length]; DataInputStream in = new DataInputStream (new FileInputStream (f)); in.readFully (classbytes); in.close (); // Now call một phương pháp chính xác từ để chuyển đổi các byte vào một Class c = defineClass (classname, classbytes, 0, length); } // If resolving the argument is true, call the inherited resolveClass method. if (resolve) resolveClass (c); // And we're done. Return the object Class we loaded. return c; } // If anything goes wrong, throw a ClassNotFoundException error catch (Exception ex) {throw new ClassNotFoundException (ex.toString ()); } } } |
Haiz, basically the setup system is done, next we will need 1 or 2 plugins to test the player to see if it runs smoothly, we will put these files in the plugins
directory.
Equality of parameters:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | / ** * This đối số squares plugin. * / public class Square implements PluginFunction { int parameter = 0; public void setParameter (int param) { parameter = param; } public int getResult () { return parameter * parameter; } public String getPluginName () { return "Square"; } // yes, this operation can fail, nhưng chúng sẽ để bỏ qua này này public boolean hasError () { return false; } |
Add 1 unit to the parameter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | / ** * This plugin adds one to the parameter. * / public class PlusOne implements PluginFunction { int parameter = 0; public void setParameter (int param) { parameter = param; } public int getResult () { return parameter + 1; } public String getPluginName () { return "PlusOne"; } // yes, ths operation cannot fail, but we are going to ignore this here public boolean hasError () { return false; } } |
TryToExit.java
tried to allow this young person to abuse it, in PluginSecurityManager
we have set the plugin to exit the program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | / ** * This plugin tries to call System.exit (), which the SecurityManager doesn't allow. * / public class TryToExit implements PluginFunction { public void setParameter (int param) { // function này không biết về tham số nó, // so it doesn't even store it for later use } public int getResult () { // The next line will be caught by the SecurityManagers 'checkExit' method. System.exit (0); return 42; } public String getPluginName () { return "TryToExit"; } // yes, this operation can fail, nhưng chúng sẽ để bỏ qua này này public boolean hasError () { return false; } } |
Next is the translation and test run, if there is nothing wrong, it will get this output, I use java 8 so I spit out the Note, but nevertheless it can run anyway :
1 2 3 4 5 6 7 8 | minh @ MINH-PC: ~ / Desktop / Plugin $ javac * .java Note: PluginSecurityManager.java uses or overrides a deprecated API. Note: Recompile with -Xlint: deprecation for details. Note: PluginDemo.java uses unchecked or unsafe operations. Note: Recompile with -Xlint: unchecked for details. minh @ MINH-PC: ~ / Desktop / Plugin $ java PluginDemo TryToExit (1) = plugin 'TryToExit' tried to do something illegal PlusOne (1) = 2 Square (2) = 4 |
In fact, this toppic also adds another problem: build to jar file and install plugin with xml but this time is very busy. Please make an appointment for another occasion.
Thanks for the sample code of Ulf Dittmer , you can download code for reference.
Phuu … thanks ae for watching this far, the song that was long-spinning had tired of asking me to stop the key here. Wish ae happy weekend.
hello cordially and win.
ITZone via blogk.xyz