Showing posts with label osgi. Show all posts
Showing posts with label osgi. Show all posts

Friday, May 10, 2013

Darker Theme 1.1: CSS Selector and OSGI Weaving


I am proud to announce Darker theme plugin 1.1 [1] for Eclipse 4.x platform. The reasons to be proud are two:

  1. It gets 32 stars! As a one-day amateur work, I originally just try to experience and show the Eclipse 4 good stuffs[2]. But the community pushes the project forward. I decide to maintain the project constantly until we can get one better theme in the Eclipse itself of some time.
  2. One weaving facility has been added into the Darker. The Darker is the first/only theme plugin to get over some styling defects shipped with the standard Eclipse instance. With this on the Darker, I can announce that it can do almost anything to challenge IDEA all round on the aesthetics of dark UI! (However, I truely have no time to make this done^_^)

To update minor version, Of course, it not only contains several bug fixings, but also introduces new things. One thing is,

  • CSS selector.

The is an old pearl of e4/CSS works. But I am aware of its power until Lars[4]' pointing out in one issue[5]. In fact, the Eclipse 4 makes a hard work to provide one full CSS-spec-conformant styling engine.(At least, they want it to be full^_^) The CSS properties is just one aspect of CSS spec. The full story should includes the CSS selector. The CSS selector syntax provides a very powerful way to pick up some elements/objects to apply your style with.

Like Lars suggest "styling the Quick Access box"[5], this styling could be done by this following piece[7]:

Here, #SearchField Text is a traditional descendant selector syntax in CSS[8], which picks up the Text widget on the widget with ID #SearchField.

Simple and neat!

If you want to dig a little more, the Eclipse's wiki here[9] and the old Kai tutorial(in the bottom of that wiki page)[10] may be useful. The CSS styling engine gives more fun to Eclipse UI developers, although I am afraid that the layout problems seemly show barriers mentioned in that wike page in the meantime:)

The another new is just as I mentioned above,
  • OSGI Weaving.

This weaving facility use the OSGI weaving functionality introduced in OSGI R4.3[6]. It allows load-time bytecode weaving, which can grant your some AOP capacities without huge dependencies.

It is a must. Because the investigation into another request[15] shows the SWT CLabel, as the background widget of stateline, forces a fixed OS related widget color as its foreground color from Control. That is, the CSS property setting is dumb here. Obvoiusly, the problem is systematic and  it can not be fixed in a near future of Eclipse development(or maybe never). I will feel very unhappy and stupid if I say to our guies that like "please wait, I have filed a bug entry against Eclipse". Then, the OSGI weaving comes to help.

Maybe you have known Equinox weaving[11] or AspectJ[12]. Yes, the OSGI weaving is a simplified version of Equinox weaving(but note that they are still different codes). AspectJ is an big animial. I have bitter memories about the AspectJ in my Scala IDE journey[13]:) One big headache is, that the Scala IDE users regularly report some update or functionality does not take effect in their environment. One reason is just due to the weaving configuration file have not been updated or picked up successfully by their Eclipse instances. I hope Iulian Dragos(leader of Scala IDE, Typesafe) has solved this problem:)

For one little theme plugin, I definitely do not want to take the nigtmare to the users. As a developer, we should be cautious to any addition. Then, the OSGI weaving is my choice.  The detail of implementation needs some ASM bytecode generation knowledge and provides the context based weaving(like cflow pointcut in AspectJ). To be honest, AspectJ syntax is simpler than direct bytecode manipulation if you have much complex context/condition combinations. I am just preparing a game-changing AOP kind of tool, but it needs time to come to the world:)



With correct weaving to SWT CLabel, Darker get a right white text color for the dark status line.


One tricky part I just to point out here, is the starting sequence of the plugins. The weave-working plugin should takes effect before the Eclipse UI things, more detailly here SWT CLabel, loaded into runtime. If you define this logics in your UI plugin, the order is definitly wrong. I solve this problem with two
simple points:
  • separate the UI and weaving(non-UI) logics into different bundles;
  • start the weaving bundle immediately after framework started.
The interesting thing is I use another new R4.3 "Start Level" API[4].(The other way may be to use kinds of hook[14], but I think it is just overkill.) It avoids any forced configuration modification for users in the Eclipse. It is a good practice.

OK, after this update, I plan to fully focus on my wonderful backend stuffs in my hobby time.
Stay tuned!


[1]:  https://github.com/jinmingjian/eclipse.themes.darker
[2]:  http://jmj-eclipse.blogspot.jp/2012/12/practices-for-eclipse-4-programming.html
[3]:  http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/hook/weaving/WeavingHook.html
[4]:  http://www.vogella.com
[5]:  https://github.com/jinmingjian/eclipse.themes.darker/issues/14
[6]:  http://wiki.osgi.org/wiki/Release_4.3
[7]:  https://gist.github.com/jinmingjian/5546115
[8]:  http://www.w3.org/TR/CSS21/selector.html#descendant-selectors
[9]:  http://wiki.eclipse.org/Eclipse4/RCP/CSS
[10]: http://www.toedter.com/blog/?p=477
[11]: http://eclipse.org/equinox/weaving
[12]: http://www.eclipse.org/aspectj
[13]: http://www.scala-lang.org/gsoc2010
[14]: http://wiki.eclipse.org/Adaptor_Hooks
[15]: https://github.com/jinmingjian/eclipse.themes.darker/issues/11

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. 


Wednesday, July 15, 2009

When the PDE(JDT) met the Jar-in-Jar bundle

When the PDE(JDT) met the Jar-in-Jar bundle

"Jar-in-Jar" is a word using in the 3.5M5 new and noteworthy page. A Jar-in-Jar bundle is just the jarred bundle which contains other jars. (sometimes, called "nested Jar".)

Recently, when I use the db4o osgi bundle, I met a compilation problem. It said,
"the type com.db4o.ObjectContainer cannot be resolved. It is indirectly referenced from required .class files".

From one entry in its forum, I know that, it is an old problem after the db4o get into the world of osgi.

After a simple inspection, I find the reason. That is, the PDE can not resolve the Jar-in-Jar bundle. The old Bug157375(and Bug 111238 as well) addressed this problem. As Jeff suggested in the comments, the best practice for this is "packaging each JAR as a bundle and not nesting JARs at all".
However, as Jeff said as well, "Equionx(and other OSGi implementation?) will run JAR'd bundles with nested bundles just fine". So, this just causes a compilation error, but not a runtime problem. I think this bug is still a bug.

As Thomas Watson said, this bug "well actually is JDT" bug. Jeff simply suggested a bug-fixing idea: "basically if the bundle has JARs on the classpath then unzip in a temp spot and us the temp location for classpath computations". But the Bug 111238 seemly said more problems with extraction method. I have one idea, like using some detecting codes just to check the correct dependency of the jar-in-jar on the fly and to avoid the compilation blocking. In the other aspects, we can still use the original bundle.

Lastly, two workaround for this bug: 1. using the best practice pointed by Jeff; 2. unzipping the jar, then using the directory-style bundle.

Warning: If you are the man responsible for building your osgi bundle, please keep the best practice. "nested jars are evil"(zx^_^).