Tuesday, August 11, 2009

OSGI R3 Implementation Running on Google App Engine Now

OSGI R3 Implementation Running on Google App Engine Now

"OSGI on Google App Engine", this seem a little older topic now? When the first announcement of GAE/J, I just think whether it is possible to post the  newest effort about this topic to the community by me. However, the poor time prohibited me from conducting more things at that time. It was ZX who posted the local test result in the community. 

Time has been moving into the August, nothing new happened. I decided to revisit the little older topic. 

It is known that the "sandboxed" environment of GAE/J has blocked the main OSGI running efforts. I try to rethink the real obstacle from having fun in this sandbox. For the simplicity, I do not choose the Equinox or Felix. Because they have been optimized for the full J2SE platform in a long time. I choose the framework optimized for size, that is the "Concierge". It is one of four implementations listed in the “See also” section in the OSGI wikipediaThe Concierge is a OSGi R3 framework implementation. It is still a little nice for no-trivial bundles(back to the Eclipse R3.0?).
My adventure is below...


The Filesystem

This is one main problem mentioned in the zx's blog post. However, this is just one small problem for running OSGI on GAE/J. One suggestion has been  proposed by zx. That is, writing a custom storage adaptor hook. My suggestion is to take use of or consult the GaeVFS. Most of work about File-system-like GAE storage have been done in this project. I have tested some small file data storage testings. It works fine. I do no more attempt here. Because demonstrating running OSGI on the GAE/J does not need the storage. Most demands for data storage in OSGI is related to the efficiency or configuration of framework. Go ahead!

Customized Class Loading(and Reflection)


More problems will happen in this section:) In the local GAE/J, all classes are load by the IsolatedAppClassLoader. And, this class is hidden behind the API. However, in the Concierge(and other OSGI implementation), all classes in the different bundles are loaded by different bundle classloaders, which is customized from the Classloader. Definitely, the first bundle of core framework or launching core framework must be loaded by the Google runtime. If we want to cast some classes in the bundle into the class in the core system bundle, we will meet the runtime ClassNoFoundException error. The only workaround is using the launching framework to load the core framework by its customized classloader. I find that zx has found this workaround as well. The magic is in the Class FrameworkLauncher of the Equinox servletbridge.

However, the customized class loading infrastructure of GAE/J has another bug - GAE Issue 1503. Briefly speaking, the issue said that we can not read the bundles from the war-rooted file system although the reading action is alllowed by the GAE server(yeah, should/must be allowed). As we mentioned below, the GaeVFS can give a solution. But this workaround will make the debugging and deployment work very complex. And tobyr(from google?) said, "Unfortunately there is no workaround
for this at the moment
". Interestingly, I find that ZX has found this workaround as well. That is, you give the AllPermission to the classloader. I list the compact version here,

...
static final PermissionCollection allPermissions = new PermissionCollection() {

public void add(Permission permission) {
}

public boolean implies(Permission permission) {
return true;
}

public Enumeration elements() {
return new Enumeration() {

private boolean hasMore = true;

public boolean hasMoreElements() {
return hasMore;
}

public Object nextElement() {
if (hasMore)
hasMore = false;
return new AllPermission();
}
};
}

};
... 

using the allPermissions in the your classloaders like,
...
protected PermissionCollection getPermissions(CodeSource codesource) {
return allPermissions;
}
...

If you'd like to use the customzied classloaders, some reflection codes need to be written in your sources at least in the launch framework. My whole impression is that the GAE/J reflection support is much nice.  

To arrive here, in fact, we can running the non blocking bundle or using the non blocking services if we can build one osgi runtime against with the GAE/J. Yeah!


Threads


The sandbox adheres to said "NO" to the thread creation till now. The Cron jobs in the GAE/J is not the substitute for the Java thread apparently. I have tried to find the lightweight thread(or called "Green Thread", "Fiber"...)for the threadless environment. 

The defective solution is using the existed event-based concurrent mechanism.  Some implementations are using the Actor model, like the Scala. After digging into the implementation, I found that almost of them take use of the thread pool(they need to use the scheduling algorithms in the java.util.concurrent). So, all of them failed in the GAE/J sandbox. However, I must say, I like the idea behind the lightweight thread framework. They are still very useful for the performance tunning of the common serve. If the GAE/J allow the limited thread/threadpool creation someday, I think we will be infinitely close to full full-fledged platform.

There is no workable solution here?...One (maybe only) workable and a little elegant solution which could be run on GAE/J, is the continuation based coroutine. Continuation is another big topic. There is no room to write many interesting contents of continuation here. I just show some efforts and results. I spend half a day to develop a Fiber and a simple Scheduler based on the Javaflow. I can run the 1000 simple Fibers in on the local app engine sdk server. Cong! However, the Javaflow is still in the unofficial phase. There are bugs in the bytecode weaving course for one complicate method. This badly limit the usage of whole concurrent system in one production platform like GAE. There is not actual meaningfulness for this Javaflow based Fiber system now. Fortunately, in the MLVM, the native continuation support for Java has been proposed and an initial patch is available. I hope a high performance implementation of continuation tools will appear. Unfortunately, we will not see the native continuation support in the JDK7. What's the time of JDK8?...

The basic conclusion of this section is, that no workaround for the threads.


Piece Together

Based on the above exploring, it is still possible to run the OSGI platform if the OSGI runtime and its bundles do not block the thread. I show this right! The below screenshots show my initial efforts:

Welcome page

Initialization of the modified Concierge OSGI framework

bundles command in Concierge, see the bundle 1 is just in the resolved state

start the bundle 1 (a simple bundle: simple.test-1.0.0.jar )

bundles command, to see the bundle 1 is in the active state

stop the bundle 1

bundles Command, to see the bundle 1 is back to the resolved state

headers command

The screenshots show the dynamic cycle of one dummy bundles in the OSGI platform. Cong! I hope to upload the sources to my personal project after some cleaning. However, I provide the web accessing in this appspot site

After the successful running of the OSGI R3, is the OSGI R4 far away?


About the Google Eclispe plugin for app engine

The newest plugin for 3.5 is nice for the small project in my test(without GWT. I hope RAP could be run the GAE/J someday. yeah^_^). The size of whole plugin is a liitle large(300M+ on my disk, google plugin depends on some of WPT/WST). If some custom works can be done to GAE/J support, the plugin will be more bright. 


1 comment:

cbo said...

Hello,
do you plan to commit your source code on gequinox ? I wanted to check it out but unfortunately there was no source code committed.

Thank you in advance
- Christine