Berichten met label java
GraniteDS and AIR for mobile
Geplaatst door Walter Treur in Flex / AIR, iPhone/ iPad, java, mobility, technical op 5 september 2011
In this article I will briefly show how to resolve some obstacles I came across when I developed my first application with AIR for mobile and GraniteDS. The most noteworthy reason of using AIR to create mobile applications is of course the multi-platform deployment using a single codebase. Furthermore, with Granite you are able to disclose the services of an existing Java backend to a mobile platform without significant changes to the backend. This offers great potential for enterprises who are struggling with the fragmented mobile market and don’t want to completely rewrite their existing Java backend.
I will assume you have some familiarity with AIR for mobile and Granite. It’s mostly the same as for Flex but there are some things you have to take into account.
1. Get the right version of Granite
The latest version of Granite is 2.2.1 GA. However, in the most recent version of AIR and Flex Adobe made some changes in the API which breaks backwards compatibility for some features of Granite. Therefore this release of Granite won’t work using the newest SDK. Refer to this post on the Granite form for more info on how to make these changes yourself. If you don’t want be bothered with building Granite yourself just download this version of GraniteDS to get started immediately.
2. Connecting to the right server
A problem for AIR applications in general (both desktop and mobile) is setting the right server settings. It is quite simple when running within the browser: The server address is changed with a single reconfiguration of the swf-file and all clients are using the new address on a browser refresh. With AIR it is a bit different and you’re not always at liberty to ‘hardcode’ the service settings in the AIR distribution package.
Granite offers a method for dynamic server configuration using the server initializer component:
Tide.getInstance().addComponentWithFactory( "serviceInitializer", DefaultServiceInitializer, { contextRoot: '/my-app', serverName: “10.0.0.1”, serverPort: “8080” });
Note that once a connection is made, it is not possible to reconnect with another configuration, because the service initializer is only used once. You have to restart the application to enable the new connection settings or reset Tide’s RemoteObject. Unfortunately Tide’s API doesn’t support this reset. I came up with a small workaround which requires you to extend the EJB class with an extra reset method with the following body:
public class Ejb extends org.granite.tide.ejb.Ejb { /** * Reset the Tide Connection to allow new server settings */ public function resetConnection():void { if (_ro) { _ro.disconnect(); } _ro = null; } }
This method resets Tide’s RemoteObject so the next remote call will force a reinitialization using the current settings of serviceInitializer. Refer to Granite’s issue tracker or forum thread for more details.
3. Automatic logout
Applications running on mobile platforms are always susceptible to unpredictable interruptions. For example when a phone call or text is received. Mobile AIR applications provide a deactivate event which is dispatched when the application is halted somehow. The application I wrote was using Tide’s Identity class for user login. Therefore I added an event handler to automatically logout the user and push the LoginView on top of the navigator stack:
private function deactivateHandler(event:Event):void { if (identity.loggedIn) { identity.logout(); } navigator.popAll(); // Purge the navigator history to disable back button usage navigator.pushView(LoginView); }
4. Build, build, build!
This isn’t directly related to Granite or AIR for mobile. But since they can both be used for enterprise scale applications I thought I’d mention it shortly: Make sure you have a proper build script. Now, I’ve got an example from Chris Black which provides a good starting point. I’ve only added the metadata compiler options required for Tide and of course a reference to the Granite libraries and generated Actionscript classes.
<mxmlc ... > <!-- .... --> <!-- location of generated as classes with gas3 --> <source-path path-element="${gen.src.dir}" /> <compiler.library-path dir="${basedir}/libs" append="true"> <include name="granite-essentials.swc" /> <include name="granite.swc" /> </compiler.library-path> <keep-as3-metadata name="Bindable" /> <keep-as3-metadata name="ChangeEvent" /> <keep-as3-metadata name="Destroy" /> <keep-as3-metadata name="Id" /> <keep-as3-metadata name="In" /> <keep-as3-metadata name="Inject" /> <keep-as3-metadata name="Managed" /> <keep-as3-metadata name="ManagedEvent" /> <keep-as3-metadata name="Name" /> <keep-as3-metadata name="NonCommittingChangeEvent" /> <keep-as3-metadata name="Observer" /> <keep-as3-metadata name="Out" /> <keep-as3-metadata name="PostConstruct" /> <keep-as3-metadata name="Transient" /> <keep-as3-metadata name="Version" /> </mxmlc>
One plus one
I can imagine one must be thinking: ‘Everyone could have figured that out!’ And I totally agree, because that’s exactly what this article is about. With some experience with Flex, a developer can write a mobile application on top of a Java EE backend. It doesn’t take much to utilize an existing backend from a mobile platform. Since the latest release of AIR the performance for iOS and Android is pretty good and together with the Granite Enterprise Platform the barrier to emerge an enterprise application to a mobile platform has become much lower.
New version of TopThreads JConsole plugin
Geplaatst door Peter Doornbosch in java op 26 januari 2011
Some time ago, I created the “TopThreads” plugin for JConsole, that helps you to determine why your Java application is causing such a high CPU load, by showing the most busy threads in your application and giving you the opportunity to inspect thread-stacktraces at the same time. It turned out to be quite usefull and from the responses I got, I can tell people find it still usefull today. A few days ago, I released a new version of this plugin, with one very usefull new feature: CPU usage.
Top thread?
If you’ve used the topthreads plugin, you probably seen this before: suddenly, a thread that is not supposed to be very busy, pops up at the top of the table with usage figures in the 90’s. You wonder WTF is going on, that this thread is taking so much CPU power, until you realize that this figure is only relative to the rest of the application threads. And if the application is hardly doing anything, threads that do a little more than anything might get alarming high figures (and red color). After i ran into this pitfall a few times, i decided i needed to know an absolute usage figures too.

If you enable this feature (settings -> show process cpu usage too), the top row of the table shows the CPU usage of the process as a whole. This is simply the sum of the CPU usage of all threads. The percentage shown in this row however, is the percentage this process is using the CPU, which should be approximately the same value a process viewer like top, Activity Monitor or the TaskManager would report. Although this is not always the case – more about that in a minute – it’s at least a good indication whether the process is busy or idle. And even though it may not always be as acurate as i would like it to be, it proved itself to be proficiant to help me avoid confusion.
The usual suspect: the garbage collector
In normal situations (whatever that me be…
), the CPU usage figure is approximately the same as the figures other tools report. However, especially when the process is very busy, the CPU usage shown is far too low. After some testing, i’m rather confident that this is mainly caused by the garbage collector. As it turns out, TopThreads does not get information for all the JVM threads, which can easily be verified by comparing a thread dump with the thread listing in JConsole. For example, threads that never appear in JConsole (not in the TopThreads tab, but neither in the JConsole thread view) are the “Low Memory Detector”, compiler threads (HotSpot), “Signal Dispatcher” and “Surrogate Locker Thread (CMS)” and the garbage collector threads (the mark-and-sweep thread and the parallel gc threads). I can image that some of these threads can put a lot of load on the CPU when the application is very busy. And one thing is for sure: the cpu cycles that are taken by these threads are not counted in the totals that the TopThreads plugin computes, simply because it doesn’t know about these.
Despite these shortcomings, i find the new feature quite usefull myself. Let me know what you think.
Other improvements in this release:
- the initial poll time is not fixed to 10 seconds, but depends on the (initial) number of threads. For small apps, the updates will be much more frequent.
- there are more preferences to set and these are moved to a separate settings dialog. Settings are stored using the Java Preferences API.
- improved stacktrace panel behavivour, including automatic scroll to the top.
- better handling of security exceptions, that might occur when connecting to a remote VM.
Please let me know what you think, feedback is always welcome!
Apachecon NA 2010, some trends
Geplaatst door Angelo van der Sijpt in Uncategorized op 7 december 2010
With Apachecon NA 2010 about a month behind us, I’d like to share some of the trends I picked up there.
Big Data, the cloud
One of the main trends I noticed is the interest in Big Data (mainly Apache Cassandra) and Big Data processing in various shapes and forms (e.g. Apache Lucene, Apache Hadoop). In relation to many of these, we find a ring of ‘cloudness’: the products tend to allow distribution and replication of data and functionality.
But it doesn’t stop there. It’s no surprise to find cloud-references in talks about Apache Tuscany (including a talk on Building cloud native software, which I regrettably missed), but for instance Tomcat is making its move into cloud territory with Stratos.
OSGi all around
Of course I have a vested interest in OSGi, and my talk during the OSGi track on friday shows this. However, apart from in its own track, OSGi and OSGi-based technologies popped up in a number of other tracks. To name a few,
- Apache Sling is an OSGi based web application platform, and showed up in the Content Technologies track,
- Apache Geronimo 3.0 (in the Content Technologies track) is now based on OSGi, and
- in the Enterprise Track, a number of sessions were decidated to Apache Aries, which focuses on the OSGi Enterprise specification.
It is an interesting development that OSGi is now mainly being referenced in the web- and enterprise spaces, whereas it started out as a specification for embedded devices.
Does this mean that OSGi is really getting traction in the software community? Yes and no. I believe the thing that is really getting traction is the notions of modularity on the one hand, and µServices on the other. OSGi is currently the main technology that marries those two notions.
Business is not a dirty word
I noticed there were roughly three kinds of talks,
- Community talks are all about how Apache works, and how open source software fits into the world around it,
- Technology talks focus on some Apache project, or a combination of projects, and go into the technical details, and
- Industry talks that show how the projects are used in industry.
The last kind of talk shows how industry, the ‘people with the problem’ use open source technology to run their business. No, I probably don’t really care about the products and services you deliver, but I am very interested in your case studies in using open source in your daily life.
A few days ago, Slashdot ran a story Paid Developers Power the Linux Kernel. In the light of sessions on open source in industry (I counted about half a dozen on this year’s schedule), this is not that surprising: if you’re a good enough developer to become a committer in an open source project, it’s very unlikely you’re working as a janitor during the daytime. All of us work for a corporation in some way, and many of us work on open source project during our paid time. I believe this is a good thing!
FitNesse and OSGi
Geplaatst door Angelo van der Sijpt in Uncategorized, java, technical op 25 mei 2010
As a demonstrator for a customer, I recently built a set of fixtures that allow FitNesse acceptance tests to talk to an OSGi framework. This code is by no means production quality, but merely intended to show the concept and explain the challenges.
I will not explain the details of the acceptance tests here, however, if there’s one point I would like to get across, it’s your fixtures should be as narrow as possible to easily accommodate for implementation changes. Study the different UserAdmin fixtures for more details. Also, I assume some familiarity with OSGi.
FitNesse and OSGi. Why?
Of course its fun, there is some real benefit to be gained here. While the industry well understands the need for unit- and integration testing, also in a modular context, it becomes more complex to create the necessary link between business and code. Yes, using a modular architecture we can behave in a more agile fashion, but all that agility is no good if the business doesn’t hop on the train, and explain well what it needs. FitNesse allows the business to explain its goals in business-lingo, while forcing the specification to be precise enough to be executable: if a concept cannot be explained by simple scenarios, something is wrong, but that’s a different story.
The modular nature of OSGi means that behavior of an application is more emergent than deterministic, making it harder to reason about its correctness: we can prove that our code and bundles are correct (unit tests), that everything works together as it should (integration tests), and that it looks right (user interface tests). However, proving that the business rules (which may well be one of those emergent properties) are handled correctly in a given setting, is another can of worms: we need to connect our acceptance tests to the OSGi framework.
The big picture
The solution presented below uses a special ‘fixtures’ bundle, which can be deployed along side other bundles in your framework. This bundles exposes an interface (in our case, through an HTTPServlet), which is used by a set of connectors, which in turn are used by FitNesse.
The details
The ingredients are two parts connector code, one part boiler plate, and one part genuine OSGi-aware fixtures.
The connectors
Starting at the level closest to FitNesse, we find a set of fixtures that FitNesse can use. For us, these contain merely boiler plate code.
public void removeUser(String name) throws Exception { doRemoteCall(buildRemoteCall("UserAdmin", name), Void.class); }
This code instructs our RemoteInvoker to do some call to the outside world. For more details, see RemoteInvoker.java in the UserAdminRemoteFixtures project.
The fixture bundle
Moving one step closer to our service, and into the OSGi framework, we find a FixtureServlet, whose task it is to receive calls from the RemoteInvoker, and turn them into actual method calls on the fixtures.
The fixtures, then, are almost regular OSGi aware objects. I chose to use the Apache Felix Dependency Manager for the dependency management of the fixtures. So, for our UserAdmin fixture, the dependencies are
manager.add(createService() .setInterface(UserAdminListener.class.getName(), null) .setImplementation(userAdmin) .add(createServiceDependency() .setService(UserAdmin.class) .setRequired(true)));
Here, we state that we have some instance of a fixture userAdmin that registers itself as a UserAdminListener and needs a UserAdmin. How straightforward is that?
The final step takes us to the actual fixture,
public class UserAdminFixture implements UserAdminListener { private volatile UserAdmin m_userAdmin; ... public void addUser(String name) { m_usersCreatedInLastCall = 0; m_userAdmin.createRole(name, Role.USER); } ... }
which is just another component using a the UserAdmin service.
Putting it all together
All we now need to do is deploy the fixture bundle in our project, and instruct FitNesse to use the remote connector. The zip file at the bottom of this post contains two shell scripts to do exactly that.
Future work
As I stated at the top of this story, this is by no means production quality code, but the concepts stand as they are. Given the way FitNesse works, the connectors do not need much extra work, perhaps support for collections. However, we could use
- a way to reduce the boiler plate code,
- a way to ensure that that both side of the fixtures use the same function naming, and
- better integration, for instance by only firing up a framework once a FitNesse suite is started.
Let’s play with it!
I have built a zip file containing everything you need to get started, including a set of scenarios that can run with both a homebrew implementation of a User Admin, and the actual Apache Felix User Admin. A Readme gives you more information on getting it all up and running.
Online video: Beyond OSGi software architecture
Geplaatst door Richard van der Laan in Uncategorized op 22 januari 2010
Op 11 november 2009 gaf Marcel Offermans samen met Jeroen van Grondelle (Be Informed) een duo presentatie over “Beyond OSGi software architecture”. De video van deze presentatie is inmiddels online beschikbaar. De gehele presentatie van 50 minuten kan je hier downloaden. Maar de eerste tien minuten zijn hieronder gelijk online te bekijken.
OSGi is niet meer weg te denken uit het Enterprise Java domein. Dit lightweight framework krijgt al een aantal jaren flinke aandacht en is met name bekend om z’n modulaire applicaties op basis van bundles. Minder bekend is het services model, waarbij applicaties worden ontwikkeld op basis van service interfaces en van elkaar ontkoppelde implementaties (POJO’s) van die interfaces. Krachtige eigenschappen van dit model zijn:
- complexiteitsreductie door stricte scheiding van services;
- declaratieve services en dependency management (IoC);
- aspect oriëntatie op basis van stub services;
- security model.
Lean software is een nieuwe manier om enterprise applicaties te bouwen op basis van OSGi, die ook goed aansluit bij Agile methoden, waarbij non-functional requirements ingevuld kunnen worden in een compact gebleven framework. In die context kijken we naar:
- applicaties deployen op allerlei platformen en omgevingen;
- applicaties automatisch installeren en updaten;
- applicaties voorzien van management interfaces;
- product software uitbreidbaar maken middels een SDK;
- product software verkopen als combinatie van standaard onderdelen en optionele uitbreidingen;
- modulaire User Interfaces.
De slides van de presentatie zijn te vinden op de NLJUG website.
Swing & OSGi — please play nice!
Geplaatst door Angelo van der Sijpt in Uncategorized, java op 18 november 2009
In a recent blog by Peter Karich, he showed how to create a pluggable Swing application using OSGi. While this works fine for smaller examples, you might run into more serious issues once you application starts to grow.
Plugging Swing: it leaks?
Let’s start with an application not unlike the one from aforementioned blog; it uses a window as host, and has a pluggable menu, and a pluggable table.
You can find the code we used at the end of this entry (or, for the impatient, here).
Using this pluggable system, we could end up with several curious situations. For instance, you might have a mixed look and feel in you application.
Or worse, you might end up with a UI that (sometimes) fails to start, and spits a stacktrace your way.
It leaks, but why?
Our host, and all components have been stored in separate bundles, meaning we don’t have full control about the order in which actions are performed (more about that later). However, we do know there are orders of execution that are less than ideal; let’s force one of those.
The project contains an Ant script to make things easier. From the root of the extracted project, run
$ > ant run1This starts the framework, installing the necessary bundles, but does not start them (note that this step uses Pax Runner, and therefore needs internet access). We can now start our bundles in the order we like.
A tale of two look-and-feels
After starting the framework, wait for the “Welcome to Felix” message, and run
[java] Welcome to Felix [java] ================ [java] start 2 start 1
The situation arises because the look and feel is a static concept in Swing. The menu bundle creates its JMenu before (see Menu.java, ln 30) the host sets its look and feel (Host.java, ln 51), and keep that look and feel, even when the host bundle changes it later.
Tables, ScrollPanes and NPEs
The NullPointerException above is a different story, but it goes back to the same staticness of Swing too. To force this situation, start only bundle 4.
[java] Welcome to Felix [java] ================ [java] start 4 [java] Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException [java] at net.luminis.swingosgi.part1.scrolltable.impl.TableComponent$1.run(TableComponent.java:31) [java] at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) [java] at java.awt.EventQueue.dispatchEvent(EventQueue.java:633) [java] at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296) [java] at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211) [java] at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201) [java] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196) [java] at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188) [java] at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Let’s take a look at the line where this NPE happens:
JScrollPane scrollPane = new JScrollPane(table); scrollPane.getColumnHeader().setBackground(Color.blue); m_panel.add(scrollPane);
We know that the ColumnHeader is null. This is because its JTable’s responsibility to create the header, but this is only done once the table knows it is part of an AWT hierarchy. The following lines come from the 1.5 JDK on a Mac; configureEnclosingScrollPane() creates the column header. This addNotify method comes from Component, and notifies of, exactly, the event of being added to an AWT container.
public void addNotify() { super.addNotify(); configureEnclosingScrollPane(); }
Order, order!
So, the static nature of Swing and the dynamic nature of OSGi seem to hurt each other seriously here.
One way to get the application right is by fixing the order in which Swing components can be created. By starting bundle 1 first in our application, we at least fix the look and feel. Getting the scrolling table to run correctly is an entirely different story.
Regarding order, a few possible solutions spring to mind immediately,
- Put all UI stuff in one bundle
- Use OSGi bundle start levels
Sure, all UI in a single bundle will give you the control necessary, but it also defeats the purpose. OSGi start levels can at least solve the ordering issues, but will not get you out of the NullPointerException and might have more impact than you desire.
What order?
As we have seen, absolute order does not solve our problem. How about separating creation and initialization? Still, we need to impose some order, or at least some hierarchy.

We represent each Swing component by an OSGi service, and leverage the OSGi service dependency resolution to build up our hierarchy; this way, we know the host service will be started last.
- Resolve services Once the host bundle starts, we know all components are locked and loaded; the host can now start setting up Swing’s static elements like the look and feel.
- Create components Component creation ripples downward: the host gets its direct children, adding them to its container, and in the process triggering the children to get their child components.
- Initialize components Once the component creation is done, the host instructs each component to initialize; we can now be certain that all components are part of the AWT hierarchy.
To reach this situation, we introduce a new OSGi service that wraps the component.

All components are handled by a service implementing ComponentProvider; notice how methods are required to be called on the EventDispatchThread, making sure that all components are created on the EDT, while retaining the order necessary.
public interface ComponentProvider { /** * Constant to identify ComponentProvider services. */ public static final String COMPONENT_ID_KEY = "component.id"; /** * This function should always be called from the EDT. The implementor * may assume that this function is called once and before {@link #addedToContainer()} * * @return the implementors (Swing) component which it provides. */ public JComponent getComponent(); /** * Triggered when the component is added to a container. The implementation * can validate some stuff. This function must be called on the EDT. * Implementors may assume this function is called after {@link #getComponent()}. */ public void addedToContainer(); }
The getComponent function is analogous to the create step above; the addedToContainer triggers the initialize.
Let’s try that out!
To check that this actually works OK, run
$ > ant run2from the root of the project, and start the bundles in any order you like. The UI will only show up once all required components are available; notice that the Table and the ScrollPane component can be used interchangeably.
Is it all good?
For the most part, yes. You do give up some flexibility: the UI is assembled at runtime, but it is no longer possible to (easily) plug components into a running system without special provisions. Then again, how often do you deploy new Swing-based functionality to a running application?
In the example application, we use ServiceTrackers to keep track of the components needed by the host. In a real system, you should consider using some dependency management mechanism; we have used the Apache Felix Dependency Manager in the past.
The project and the story
The project mentioned above is available as a zipped Eclipse project. You can directly import this into Eclipse, or just unzip it and run the Ant build file.
To run the examples, you will need Apache Ant. Also, since we use Pax Runner, you will need an internet connection.
The presentation we gave about this at Devoxx 09 is at SlideShare.
ApacheCon US 2009 – Celebrating a decade of open source leadership
Geplaatst door Marcel Offermans in java op 10 november 2009
The Apache Software Foundation celebrated its 10th anniversary last week at the ApacheCon US in Oakland, California. The event, which lasted from November 2nd to 6th, consisted of many different types of events, ranging from full-day trainings to lightning talks, from a hackathon to technical and marketing sessions. On friday, the event featured a full-day track about OSGi, where all OSGi related Apache projects like Felix, ACE, Sling and Tuscany where present. The big announcement of the conference was the fact that Subversion wanted to join Apache. In fact, during the event, just like with any other project, there was a vote to accept Subversion into the incubator. As with many projects, this triggered some discussion, debating the merits of doing a release during incubation, even though this is a project with many seasoned Apache committers on board.
A conference like no other
Apache probably is the strongest brand in the open source space, but the conference itself focusses strongly on content. Here you will see no sponsored talks by commercial vendors, no sales people trying to sell you anything, it’s all about the code, the community and collaborating with each other. In that sense it’s quite different from most other conferences and if you like meeting and discussing fellow developers, this is a great place to visit. Many events facilitate discussion, and power and internet connectivity are available everywhere.
What open source is all about
Brian Behlendorf summarized the three main cultural elements of Apache quite well:
- write good code and debate it to the bone
- be humble
- collaborate
In essence, Apache is a meritocracy, of which only individuals can become a member. It’s sometimes also described as a do-ocracy as projects are driven by contributions: if you want something done, just do it. Another important aspect is that everything that is done on the Apache projects is discussed and archived on the mailing list. All discussions, code diffs and decisions must be recorded there.
Presenting Apache ACE
Tuesday evenings “birds of a feather” session featured a discussion about Apache ACE, where questions mostly centered around the use cases for ACE and possible integrations with other OSGi components. One of the conclusions is that there are probably three different phases of deployment:
- Using Apache Felix File Installer, which allows you to drop components in a local folder to have them installed.
- Using Apache Felix Karaf’s provisioning components, which allow you to define features which basically group components and allow you to define dependencies on other features.
- Using Apache ACE, which allows you to group components and automatically deploy them to many remote systems.
Friday’s OSGi track started with an introduction to OSGi and moved into more advanced topics during the day. The Apache ACE talk was received well, with several people expressing an interest in wanting to use it and contribute to it.
Final thoughts
Summarizing the week, Floris and I had a great time talking to many interesting people and learning about various projects. ApacheCon is a great conference, and I’m already looking forward to the next one.
Using GWT to create an OSGi-aware web application
Geplaatst door Angelo van der Sijpt in Uncategorized op 9 juli 2009
Update 2010-02-20 Both Pax Runner 1.3.0 and GWT 2.0 have caused quite some changes to this post. I have tried to stay up to date as well as I could (the zipped project now uses GWT 2.0), but you might find some inconsistencies when following the tutorial.
Google Web Toolkit is cool, and so is OSGi. However, when building a web UI for Apache ACE, I found out that creating a web application that can use OSGi services is not that easy. By the end of this tutorial, you will have created a GWT project that delivers a usable jar. If you’re impatient, skip to the end for the downloadable Eclipse project.
Step 1: Create a GWT project
Create a regular GWT project using the regular webAppCreator; this will give you a project that includes an Ant buildfile, we will need that later on.
angelos:workspace angelos$ ./gwt-mac-1.6.4/webAppCreator -out GwtDemo net.luminis.gwt.gwtdemo Created directory GwtDemo/src Created directory GwtDemo/war Created directory GwtDemo/war/WEB-INF Created directory GwtDemo/war/WEB-INF/lib Created directory GwtDemo/src/net/luminis/gwt Created directory GwtDemo/src/net/luminis/gwt/client Created directory GwtDemo/src/net/luminis/gwt/server Created file GwtDemo/src/net/luminis/gwt/gwtdemo.gwt.xml Created file GwtDemo/war/gwtdemo.html Created file GwtDemo/war/gwtdemo.css Created file GwtDemo/war/WEB-INF/web.xml Created file GwtDemo/src/net/luminis/gwt/client/gwtdemo.java Created file GwtDemo/src/net/luminis/gwt/client/GreetingService.java Created file GwtDemo/src/net/luminis/gwt/client/GreetingServiceAsync.java Created file GwtDemo/src/net/luminis/gwt/server/GreetingServiceImpl.java Created file GwtDemo/build.xml Created file GwtDemo/README.txt Created file GwtDemo/.project Created file GwtDemo/.classpath Created file GwtDemo/gwtdemo.launch Created file GwtDemo/war/WEB-INF/lib/gwt-servlet.jar
If you want to, you can import this project directly into your Eclipse. If you check the mark “use Google Web Toolkit” in the project properties, you can use all the same goodies that creating the project in Eclipse would have given you. Remember to replace the buildpath entries for gwt-user.jar and gwt-dev-*.jar by a Library import for GWT.
Step 2: Include the necessary OSGi references
Create an ‘ext’ directory, and add org.osgi.core.jar to that. In Eclipse, add this jar to your build path.
Step 3: Use OSGi services from your web applicaiton
We will first add a simple Activator on the server side.
package net.luminis.gwt.server; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { private static BundleContext m_context; public static BundleContext getContext() { return m_context; } public void start(BundleContext context) throws Exception { m_context = context; } public void stop(BundleContext context) throws Exception { } }
Then, we up the GreetingServiceImpl to actually use this BundleContext (note that we use it directly here, but you could use it to get other services, create a ServiceTracker, etc.)
public String greetServer(String input) { String serverInfo = getServletContext().getServerInfo(); String userAgent = getThreadLocalRequest().getHeader("User-Agent"); return "Hello, " + input + "! I am running " + serverInfo + ". It looks like you are using:" + userAgent + "The framework we run from has " + Activator.getContext().getBundles().length + " bundles in it."; }
Step 4: Add OSGi dependencies for the compiler
Add our OSGi dependencies to the classpath, so the compiler can find all of it.
<!-- Add any additional non-server libs (such as JUnit) -->Right, let’s give it a try!
angelos:GwtDemo angelos$ ant war Buildfile: build.xml ...some output removed... war: [zip] Building zip: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.war BUILD SUCCESSFUL Total time: 36 seconds
You will find a war in your project directory now. There still is one ingredient we need. We need to make this into a proper bundle. We can use bnd to help us with that.
Step 5: use bnd to create a proper war
Download bnd, and put into a lib directory, and add it to your buildfile.
We create a new target that transforms our war into a jar.
<target name="jar">
<copy file="gwtdemo.war" tofile="gwtdemo.jar"/>
<echo file="gwtdemo.bnd">Import-Package: junit.framework;resolution:=optional, com.google.gwt.*;resolution:=optional, org.w3c.*;resolution:=optional, sun.misc;resolution:=optional, javax.imageio;resolution:=optional, javax.servlet.*;resolution:=optional, *
Bundle-Name: GWT Demo
Bundle-ClassPath: WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar
Bundle-SymbolicName: net.luminis.gwt.gwtdemo
Webapp-Context: gwtdemo
Bundle-Activator: net.luminis.gwt.server.Activator
</echo>
<bndwrap jars="gwtdemo.jar" output="gwtdemo.jar"/>
<jar file="gwtdemo.jar" update="true">
<manifest>
<attribute name="Bundle-ClassPath" value="WEB-INF/classes, WEB-INF/lib/gwt-servlet.jar, ."/>
</manifest>
</jar>
<delete file="gwtdemo.bnd"/>
</target>What’s happening here?
- we copy our war to the same file, but with a jar extension,
- we create a file for bnd to use, stating that we
- want optional imports for junit and the gwt benchmarks, and non-optional imports for everything else (that what the * is for),
- have some classes that we want bnd to scan for finding dependencies,
- want to use a given Webapp-Context (this is a Pax war extender specific entry),
- let bnd do its magic,
- update our manifest: we put the . back on the classpath. This is important for the web application to find all resources, but if we would tell bnd to do it like this, it would treat . as the root of the classpath.
- Finally, we delete that temporary bnd file.
What does that give us?
angelos:GwtDemo angelos$ ant jar Buildfile: build.xml ...some output removed... jar: [copy] Copying 1 file to /Users/angelos/workspace/workspace/GwtDemo [bndwrap] gwtdemo 41 910305 [bndwrap] Warnings [bndwrap] Superfluous export-package instructions: [WEB-INF.classes.net, gwtdemo.gwt.standard.images, WEB-INF, gwtdemo, WEB-INF.classes.net.luminis.gwt, gwtdemo.gwt.standard, WEB-INF.classes.net.luminis, WEB-INF.lib, WEB-INF.classes, gwtdemo.gwt.standard.images.ie6, WEB-INF.classes.net.luminis.gwt.client, WEB-INF.classes.net.luminis.gwt.server, gwtdemo.gwt] [jar] Updating jar: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.jar [delete] Deleting: /Users/angelos/workspace/workspace/GwtDemo/gwtdemo.bnd BUILD SUCCESSFUL Total time: 23 seconds
That’s it! You can now deploy this jar into a framework that uses the pax web tools. Right, let’s give that a try.
Download pax-runner, and unzip that somewhere. Copy in your new jar, an try the following command
angelos:pax-runner angelos$ sh bin/pax-run.sh --profiles=war,compendium gwtdemo.jar
Now visit http://localhost:8080/gwtdemo:

Summary
So, what did we need?
- A fairly regular GWT project, create with an Ant file,
- some code that tries to use OSGi services,
- some bnd magic to make the war into a jar,
- Pax tools to get it all running quickly.
If you don’t want to use pax runner, you can need to deploy pax-web-extender-war(jar, snapshot 23 June) and an http server, preferably pax-web-service(jar), into your framework.
You can download the gwtdemo Eclipse project to play around with it. I have not provided the GWT runtime in this download; you should edit line 4 of the build.xml to point to your installation of GWT.
Google Wave – Ze doen het weer….
Geplaatst door Richard de Zwart in Uncategorized op 28 juni 2009
Google presenteerde recentelijk een van de nieuwe ontwikkelingen waarmee ze bezig zijn: Waves. Volgens de documentatie op de Google Wave API website is een wave:
“A wave is a threaded conversation, consisting of one or more participants (which may include both human participants and robots). The wave is a dynamic entity which contains state and stores historical information. A wave is a living thing, with participants communicating and modifying the wave in real time.”
Google Wave draait in je browser. Het is een Javascript applicatie die je browser omtovert tot een collaboration-tool die de concurrentie met een heleboel duurbetaalde tools probleemloos aankan. En het is gratis. De gehele code-base wordt ge-opensourced zodat iedereen heel snel en makkelijk met zijn eigen Wave implementatie aan de slag kan
Is het mooi?
Ja, wat je ziet op de demo die ze gaven op de Google IO conference is absoluut spectaculair. Het duurt even voordat het tot je doordringt (thick skull, sorry), maar dan zie je (als techneut in ieder geval) dat het heel knap is wat ze daar aanbieden. Of je het wilt hebben, of dat het de wereld gaat veranderen of de hoeveelheid CO2 in de atmosfeer gaat verminderen? Geen idee, maar hieronder licht ik even de punten toe die mij erg aanspraken.
Real-time
Alles wat je in een Wave intikt, is onmiddellijk zichtbaar bij alle andere mensen die jouw Wave open hebben staan. Dit biedt dus in ieder geval Instant Messaging, maar dan zonder het wachten op “Mr.X is typing a message”. Er is een open protocol ontwikkelt dat deze communicatie regelt. Even ter herinnering: dit is in je browser. Dus real-time communicatie tussen 2 of meer browsers.
Concurrent
Je werkt met alle betrokkenen tegelijk aan een Wave. Iedereen kan reply-en binnen een Wave, maar kan ook
corrigeren wat een ander nog aan het intikken is. In dat proces wordt bijgehouden wie wat heeft gedaan.
Multi-media
Letterlijk. Het maakt niet uit welk type medium je wilt gebruiken: tekst, beeld, film, geluid. Je kunt het allemaal drag-n-droppen in een wave. Als je een serie plaatjes in een Wave gooit, krijgen alle deelnemers onmiddellijk thumbnails te zien.
Playback
Alle wijzigingen op de Wave staan op een time-line die je kunt terugspelen. Als je met een groep mensen aan een stuk tekst werkt kun je de hele conversatie terughalen, wat noodzakelijk kan zijn omdat iedereen alle tekst kan wijzigen en je alleen het uiteindelijke resultaat ziet. Er is een demo van een schaak-applicatie die in een Wave draait. Behalve dat iedereen op de Wave onmiddellijk de gedane zetten ziet, kun je het hele spel opnieuw afspelen door de time-line te manipuleren. Als ontwikkelaar van een dergelijke app hoef je niets te doen voor de real-time en play-back functionaliteit. Die zit in de Wave en krijg je er gratis bij!
Robots
Er is al een grote hoeveelheid robots geschreven die deelnemen aan een conversatie zoals mensen dat kunnen doen. Deze robots werken voor je als een soort tool of plug-in. Er is bijvoorbeeld een spelling-checker robot die jouw Wave edit terwijl je ermee bezig bent. En zelfs een vertaal-robot die jouw tekst bij jouw Franse collega in het Frans vertaald laat zien. Maar ook robots die tekst herkennen als links en ze meteen clikable maken, of robots die een link naar video herkennen en je meteen de optie geven om een player te embedden.
APIs
Er is een uitgebreide API beschikbaar om zelf robots te maken of om een Wave in je eigen (web)applicatie te embedden. Je vindt er meer over op: http://code.google.com/apis/wave.
Conclusie
Het is eigenlijk nog te vroeg om conclusies te trekken. De developers wereld is er al flink opgesprongen en heeft een veelheid aan robots en gadgets geproduceerd. Dat zegt niet alles. Zoals uit mijn enthousiasme al blijkt is het voor techneuten echt een heel interessant platform. Of het een killer-app is weet ik niet. Het zou heel goed de manier van communicatie kunnen veranderen, omdat je mail, chat en IM in één en dezelfde vormt giet. Ik denk dat het net zo gaat als met de iPhone. Op zichzelf niet briljant, maar doorr de juiste onderliggende technologie maakt het applicaties mogelijk die echt briljant zijn en het product tot grotere hoogte tillen.
JavaOne Reloaded
Geplaatst door Marcel Offermans in Uncategorized op 5 juni 2009
On tuesday, june 23rd, luminis organizes a JavaOne reloaded event, where all the news and highlights from the 2009 JavaOne are presented. This will take place in the Arnhem offices, starting at 18:00. If you want to be present, please send a mail to Marcel. This year’s JavaOne is special for many reasons. Oracle just bought Sun. Microsoft gives their first keynote. JavaFX comes of age. Larry Ellison hints at a JavaFX frontend for OpenOffice. Enough reasons to be present!





