Kross - Embedded scripting


dipesh.jpg

Interview Sebastian Sauer

What is Kross?

Kross is the scripting engine for http://www.koffice.org and provides a complete framework to embed scripting interpreters transparently into native applications and bridge that way worlds dynamic together.

KDE does provide a rich set of bindings for different languages. PyQt/PyKDE, QtRuby and even developing KDE-related tasks with Java and C# is supported.

If it comes to embedded scripting the choose got cut down to QSA and KjsEmbed which both provide an embedded JavaScript-interpreter with a very small subset of the functionality, existing modules and 3rd-party support other languages like Python or Ruby are enjoying. There is no cpan-like collection of 3rd party modules for nearly everything, maintained and improved by large communities and reusable for own tasks.

The open source world is about choices, about reusing functionality and about flexibility. So, why not increase the number of supported languages which could be embedded into an application? Well, writing the code to embed the Ruby-interpreter into an own application, writing more code to add Python, LUA or Perl support and then write bindings for your applications internals for each single supported language would be the consequence and that's only for one single application cause every application provides own bindings, the developers prefer one interpreter over another and at the end we would reinvent the wheel for each single application that likes to embed the interpreter the developer likes most.

What is needed, is an transparent and scripting-interpreter independent way to deal with embedded scripting. That is where Kross comes into the game.

First it is transparent cause the application that uses Kross doesn't need to know what scripting-language is used at all. All the application needs to know is, that there exists a library which provides scripting-functionality. Well, in fact the application doesn't need to know that too cause maybe Kross is provided and used within an application-plugin (that's how Krita and Kexi are including Kross) or maybe just as KPart if that's what the application prefers.

All the application needs, is the loaded plugin to pass objectinstances to it. The plugin and Kross will know how to handle those instances with some - again interpreter-indepent - binding-code the application provides. Such bindings are implementing the interfaces that should be exposed to Kross and Kross itself will then take care of the scripting-backend or -backends.

In fact even the core of Kross doesn't know what interpreter does finally evaluate the scripting code or how the evaluation is done. All this is handled by interpreter-plugins loaded dynamic at runtime on demand. That means, we have a strict isolation of the interpreter-dependend code and the application itself does not depend on any interpreter! Even better, the interpreter-related code could be packaged separate and only installed if it's really needed/wanted by the enduser. That leaves us enough room to embed for example Java, Mono, LUA or Prolog if someday someone things, that his application needs it, without any dependency we would introduce that way. Even better, all applications that are using Kross, could from now on use the new interpreter too and that without one single line of touched code in the application or it's bindings and even without any recompile.

Where is Kross in use today?

Currently it is in use within KOffice. To be more exact, Kexi and Krita as shipped with KOffice 1.5 provide full Python and Ruby scripting. KSpread supports scripting with the hopefully soon arising KOffice 2.0 and support for other KOffice-applications like KWord is planned.

What languages does Kross support?

Python and Ruby are fully integrated and support for Kjs/KjsEmbed and Java are planned. Both already supported interpreters are implementing the bridge with just a small hand of files (~5 per interpreter if I remember correct :-). The main work is done within the Kross-core the application and the interpreters are using to talk with each other. Well, in theory it shouldn't be that difficult to even let one interpreter talk with another interpreter that way.

It's even better. We don't reinvented the wheel rather then providing access to already existing technologies. So, you are even able to use the whole power of PyQt, PyKDE and QtRuby in your native KDE-application. You are able to build complex GUI's that way, include them at runtime dynamicly as part of your application, connect signals and slots, trade object-instances, manipulate your KApp, access DCOP, QWidget's or whatever you like to archive. As example at Kexi we decided, that we don't like to depend on PyQt to display a simple GUI for a small ~100 line "Export Database-table or -query to XHTML File" python-script. So, we wrote additional ~100 lines of python-script to fallback to TkInter if PyQt is not installed and guess what; it works great. In theory even PyGtk should work (I never tried it), what means we are able to access Gtk at runtime without depending on it.

Could you provide an example of usage?

As example Kexi already ships with a bunch of scripts that extend the functionality of the application. Also we provide a "Get new scripts" functionality to install or update script-packages over the internet.
At http://www.kde-files.org/index.php?xcontentmode=617 we offer a complete Webserver for Kexi that runs within own Threads in the main native application and we offer the CopyCenter which uses some of the great external modules python provides to be able to merge data from/with a Kexi database to e.g. a QtSQL-database or a Excel-compatible CSV-file. The scripts where written within just some days to outline what is already possible today.

How can a developer add Kross support to their program?

There was a great tutorial written by Cyrille Berger located at http://kross.dipe.org . Since some weeks we got it managed to hide all the Kross-internals by introduction of some template-magic. Let's look at a simple example (see also the trunk/koffice/kspread/scripting code for a more detailed example);

// We like to wrap that class and publish the myFactoryMethod-method to scripting languages.
class MyNativeClass
{
public:
MyNativeClass* myFactoryMethod(const QString& name) {...}
}

// So, here is the wrapper class
class MyWrapperClass : Kross::Api::Class<MyWrapperClass>
{
public:
MyWrapperClass(MyNativeClass* instance)
{
// just publish the method above and say who should handle
// the arguments by defining them as template-arguments.
this->addFunction1<MyWrapperClass, Kross::Api::Variant>
("myFactoryMethodName", instance, &MyNativeClass::myFactoryMethod);
}
}

that was it already... we are able now to call the factory-method from within scripting code and will get an instance of MyWrapperClass as result. Basicly all kind of types could be wrapped that way dynamicly and we are even able to delegate methodcalls dynamic that way :)

What is the advantage of Kross over DBUS, KJSEmbed and Kommander?

Well, DBUS is a great piece of work, but it's main area seems to be IPC/RPC (Inter-process and remote-process) while KJSEmbed and Kross are about embedding scripting direct into an application as part of it. That way scripts are running in the address-room of an application and are able to manipulate the application.
KJSEmbed is heavily bind to KJS (KDE JavaScript) and does not allow to integrate any other scripting language. Users need to use Javascript or don't use scripting at all. It is not possible to use additional already existing solutions like PyQt, QtRuby, Java or LUA.
Kommander is a damn great tool and allows easy integration of with a designer build GUIs and uses DCOP (now replaced with DBUS). It comes very close to what I would expect a flexible scripting solution should offer. Maybe someday we could integrate Kross into it as well and extend that way the great user-interface it has with a flexible and fast transparent in-process scripting solution.

Why are Kross scripts better than writing plugins directly in the program?

That is a difficult question cause I guess there is no correct answer beside "it's up to the user if he likes to use C++ or e.g. python".

What security concerns are there with Kross scripts?

That is one of the biggest problem we have currently. Python does not deal with insecure, untrusted scripts and does not provide any sandbox-like execution-environment. While Ruby supports security-levels and while I integrated the great Zope RestrictedPython environment into Kross, I would not trust them to be as save as a Java sandbox could be. We could try to limit the damage by using signed scripts as outlined at the http://www.kexi-project.org/wiki/wikiview/index.php?Scripting#Security_issues , but that doesn't look like the most powerful and secure solution. So, currently I don't see another solution then using Java for untrusted scripts or extending KJSEmbed4 to be able to deal with insecure scripts.

Will KOffice get macro scripting ability?

That is another task we where working on. We means in that context a team from within my university which worked last year on integration of macros for Kexi. At this point I like to thank Hr. Christoph Knabe from the TFH-Berlin a lot for his great support and for allowing us to work on the Macro-front. So, current state is that it's very alpha and it's not really ready yet to be used widthly. So, maybe next year we could talk more detailed about this :)

Will Kross be used outside KOffice?

I hope so, but I guess each developer have to decide by his own if it makes sense and if his user would prefer a scripting independ solution. At the end its all about having the choice rather then being limited.

How did you come up with the idea for Kross?

Let me fix the "why this guy had this idea and why he choosed that ugly K-name" impression some may got. The time I joined Kexi and started to look for a scripting-solution we could integrate I found the Kexi wiki-page http://www.kexi-project.org/wiki/wikiview/index.php?Scripting which for sure looked quit difference before. In fact someone - Cedric Pasteur or Lucijan Busch? - had once the idea to integrate a interpreter-independend solution and wrote about it at the wiki and the working-title was "Kross". So, what I did was to absolutly agree with what I read there and just started to implement it :-)

How hard was Kross to implement?

It is hard and it will stay hard. Mostly cause I like to do it as good as possible. Everytime other developers asked me if the thing is ready to be integrated I answered; "Not really, cause my personal feeling is that it's still very alpha and the API may change a lot". I agree that it was absolutly not PR-wise cause that way I may screwed some developers away last two years Kross growed. Finally there was one developers who doesn't agreed with my usual statement and just started to use it and that was absolutly the correct decision cause since that time the thing went from a moving developer-target into a very stable usable solution. So, a lot of thanks to Cyrille Berger!

Is there something like Kross on the MS Windows platform? Is Kross' scope similar to Visual Basic for Applications (VBA)?

VBA is also just one single scripting backend. Kross was designed with the concept in mind to provide an abstraction layers to interpreters and hide the differences to the application that likes to use scripting. So, it follows more the .net idea without the large codebase, patents or a vendor-lock. It's all about reusing already existing technologies and provide access to them without introduction of any dependencies.

Is Kross basically finished, or is development and feature expansion still in full swing?

Well, as sayed before I stopped to say, that it's a moving target cause that may screw potential users away. But there still stays a lot to do. As example we like to integrate KJS/KJSEmbed and Java into it. Another goal is to improve the speed much more by using C++ templates internal everywhere and to have full transparently DBUS-integration. Also I hope to find some day some more time to look how we could connect with the great Kommander.

Where can we find out more?

http://kross.dipe.org

If there are any questions, you are also able to reach me direct via mail()dipe()org or at IRC. My yet not any longer secret nickname there is "dipesh" :)