Recently doing something strange that requires the Java application to be able to accept user-submitted scripts and execute, the network part I chose NANOHTTPD to provide basic HTTP server support, and in Java can host many scripting languages for a long time, such as Rhino, Jython and JRuby, but they are too large, and it is difficult to implement a sandbox protection server environment. In the end I looked at Lua, the language known as the binder. The first challenge was to choose the library that was used, the pure Java implementation of the LUA interpreter has a lot, what Luaj,luajava,kahlua, and the unknown Mochalua,jill and so on (a lot more), many of them are pure Java implementation, Luajava used the JNI, considered repeatedly after I chose Luaj, after all, is a pure Java implementation, to be able to use.
Luaj also has the corresponding JME and JSE platform, JSE version is the JME version of the superset, also with Luajava module Luajava, can directly in. Lua call Java method, create Java instance, is very convenient.
Toss for a few days, think to Luaj also have enough understanding, so put some related code collation as follows:
123456789 |
Create a global environment for LUA execution. Luavalue Global= Jseplatform.Debugglobals();To get the loadstring variable, this variable stores a method equivalent to the eval in JavaScript. Luavalue LoadString= Global.Get("LoadString" ; The first call () method calls LoadString, which uses the static method of luevalue.valueof () to encapsulate Java data into data that LUA can use, and the second calling () method is to execute an expression in a string. The result is a "Hello world!" output. LoadString. call (Luavalue. Valueof ( "print (' Hello world! ')" ). call (; Similar to this is the loadfile, but its role is to accept a file path, read the contents of this file, the execution called call. Global. get ( Call Call |
Luaj until the end of the code to block the thread, this time to open a new thread dedicated to run, but the pit daddy is Luaj run can not be interrupted (even if you interrupt the thread), such as your. Lua has a while true do End loop, then you will never be able to break it , unless you exit your entire Java application ...
What, is there a pit daddy? I google for the most of the day, found that Luaj seems to have no official solution (at the same time discuss this kind of thing is a little poor!) )... I also migrated the code to Luajava, found that the call to the L.close () method is not interrupted execution, and finally grabbed a lifeline.
This straw comes from Computercraft, a module that simulates a computer in Minecraft, is also used as a luaj, but can interrupt the execution of a piece of code, so I use Jd-gui to view its source code, and finally effectively implement the LUAJ in the execution of the interrupt.
Let me first introduce some of the methods that are in Lua:
The Debug.sethook () method is precise enough to set the hook callback for each function, and this callback can do anything you want to do;
The Coroutine.create () method can create a collaborative thread,
The Coroutine.yield () method can pause this collaborative thread (which is exactly what we want),
The Coroutine.resume () method is used to recover this synergistic thread.
Next look at the code:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 66676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
PackageNet.airtheva;ImportJava.io.File;ImportOrg.luaj.vm2.LuaThread;ImportOrg.luaj.vm2.LuaValue;ImportOrg.luaj.vm2.lib.OneArgFunction;ImportOrg.luaj.vm2.lib.ZeroArgFunction;ImportOrg.luaj.vm2.lib.jse.JsePlatform;PublicClass Luaworker{Class _workerImplementsRunnable{@OverridePublicvoid run(){misstopping=False; misstopped=False;Produces a synergistic thread. Mluathread= Mcoroutinecreate.Pager(mloadstring.Pager(Luavalue.ValueOf("While true do print ('! ') End)));Executes the orchestration thread (the thread will be blocked). Mcoroutineresume.Pager(Mluathread);}}Thread Mthread; Luavalue Mglobal; Luavalue mloadstring; Luavalue Mdebugsethook; Luavalue mnativecoroutinecreate; Luavalue mcoroutinecreate; Luavalue Mcoroutineyield; Luavalue Mcoroutineresume; Luavalue Mluathread;Boolean misstopping=True;Boolean misstopped=True;Public Luaworker(){Mglobal= Jseplatform.Debugglobals(); Mloadstring= Mglobal.Get("LoadString"); Mdebugsethook= Mglobal.Get("Debug").Get("Sethook"); Luavalue Coroutine= Mglobal.Get("Coroutine"); Mnativecoroutinecreate= Coroutine.Get("Create"); Coroutine.Set("Create",New Oneargfunction(){@OverridePublic Luavalue Call(Luavalue value){Debug.L("Called."); Luathread thread= Mnativecoroutinecreate.Pager(Value).Checkthread(); Mdebugsethook.Invoke(New Luavalue[]{Thread,New Oneargfunction(){@OverridePublic Luavalue Call(Luavalue value){If(misstopping){Luathread.yield (Luavalue.nil); Mcoroutineyield.Pager();Pause this thread, the above line can also play the same effect. misstopped=True;}Return Luavalue.NIL;}}, Luavalue.ValueOf("CRL"),The computercraft here is luavalue.nil, but I can't seem to stop here ... Luavalue.ValueOf(100000)This 100000 is according to copy, in fact I do not know what this means, and so in-depth use of LUA should know.});return thread;}}); Mcoroutinecreate= Coroutine.Get("Create"); Mcoroutineyield= Coroutine.Get("Yield"); Mcoroutineresume= Coroutine.Get("Resume");}Publicvoid Start(){Mthread=NewThread(new _worker () ; Mthread. start (; } public void stop ({ //may not be recovered well. misstopping = true; Mthread. interrupt (; mthread = null; } /span> |
Then the Luajava found in eclipse in the normal operation, exported to. Jar after Luajava work is not normal, toss two days after finally found that the original is coding problem, if you also have problems can try to specify-dfile.encoding= UTF-8 (Pit Daddy's windows). But because Luajava also do not know how to stop, and its interface is not so rich, so finally back to the bosom of Luaj, here is just a record (after all, pit me for two days!) )。
http://airtheva.net/wordpress/?p=159
Using LUA scripting in Java, Javaj calls Lua script functions (GO)