<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The moons of Verthandi - Blog by Dani Giribet</title>
	<atom:link href="http://dani.calidos.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dani.calidos.com</link>
	<description></description>
	<lastBuildDate>Wed, 11 Aug 2010 19:54:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Templating the OSGi way with Freemarker</title>
		<link>http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/</link>
		<comments>http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 19:52:08 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[bundles]]></category>
		<category><![CDATA[freemarker]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[templating]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=285</guid>
		<description><![CDATA[After some well-deserved rest the OSGi components on the server series is back with a vengeance and a somewhat independent post. For some background please check the other posts in the series. A common feature of Web applications is the need to output structured content, be it XML, XHTML markup, JSON or many others. A [...]]]></description>
			<content:encoded><![CDATA[<p>After some well-deserved rest the OSGi components on the server series is back with a vengeance and a somewhat independent post. For some background please check <a href="http://dani.calidos.com/category/computing/java/">the other posts in the series</a>.</p>
<p>A common feature of Web applications is the need to output structured content, be it XML, XHTML markup, JSON or many others. A number of technologies is used to do that but few seem to be that dynamic, usually only reloading templates when they change or loading them from URLs. Surely we can leverage OSGi to make things more interesting&#8230;</p>
<p>Therefore we should be following the OSGi dynamic philosophy as much as possible, exploiting the features made available by the framework such as dynamic discovery, services, bundle headers and the lot.</p>
<p>In the case of our cache app we are violating quite a few basic design principles by having the format embedded in the java code. So we should as well use a template separate from the code and if possible reuse some existing well-known templating engine from somewhere.</p>
<p>Given these basic design principles let&#8217;s get started.</p>
<p>Firstly, we need a robust and flexible templating engine. We select the mature <a href="http://freemarker.sourceforge.net/">Freemarker</a> engine which is reasonably speedy and has the power and flexibility we want. Make sure you check out the <a href="http://freemarker.sourceforge.net/docs/app_license.html">license</a>, of course.</p>
<p>We could stop at putting the library JAR in a bundle and package it so it can be used by any other bundle and that is what we do to be able to use it in OSGi. That however doesn&#8217;t exploit many of the nicer OSGi capabilities so we will create another bundle called &#8216;com.calidos.dani.osgi.freemarker-loader&#8217;.</p>
<p>What we want is to allow bundles to carry templates inside them and have our freemarker-loader templating bundle discover them automagically. This is the same technique that the Spring dynamic modules use and you can find more info <a href="http://eclipse.dzone.com/articles/osgi-42-extender-pattern-and">here</a>. The mechanism is described in this diagram:</p>
<p><img alt="OSGi freemarker templating diagram" src="http://dani.calidos.com/img/2010/osgi-08/osgi-template-components.png" title="OSGi freemarker templating diagram" class="alignnone" width="429" height="434" /></p>
<p>That is easy enough with a BundleTracker and a BundleTrackerCustomizer implementation. The BundleTracker class tracks bundles being added to the environment like this:</p>
<pre class="java:nocontrols:nogutter">
tracker = new BundleTracker(context, Bundle.RESOLVED, templateTracker);
tracker.open();
</pre>
<p>With this snippet the tracker instance will look for bundles in the RESOLVED state (which lets us track fragments). The &#8216;templateTracker&#8217; object is an instance of BundleTrackerCustomizer and will receive callbacks whenever bundles are added to the environment.</p>
<p>For instance, when a bundle is added we check for a special header in the bundle which tells us what is the relative path of available templates in the bundle being resolved:</p>
<pre class="java:nocontrols:nogutter">
public Object addingBundle(Bundle bundle, BundleEvent event) {

// we look for the header and act accordingly
String templatesLocation = (String) bundle.getHeaders().get(TEMPLATE_HEADER);
if (templatesLocation!=null) {

	Enumeration<URL> bundleTemplates = bundle.findEntries(templatesLocation, "*.ftl", true);
	HashSet<URL> templatesFromAddedBundle = new HashSet<URL>();
	while (bundleTemplates.hasMoreElements()) {

		URL templateURL = bundleTemplates.nextElement();
		addTemplate(bundle, templateURL,templatesLocation);
		templatesFromAddedBundle.add(templateURL);

	}

	templatesOfEachBundle.put(bundle.getBundleId(), templatesFromAddedBundle);

}
return null;

}	// addingBundle
</pre>
<p>An interesting method being used here is &#8216;findEntries&#8217; which loads all the entries in the provided templates folder and lets us add them to our holding structure. We also take care to implement the methods to remove the templates and update them accordingly whenever bundles are updated or unloaded from the environment.</p>
<p>Having TEMPLATE_HEADER with a value of &#8216;Freemarker-Templates&#8217; means that bundles having a header such as <code>Freemarker-Templates: /templates</code> will have any templates within that folder (<i>please note that the &#8216;/templates&#8217; bit is not added to template URLs!</i>).</p>
<p>The next thing we need to do is make the loaded templates available to the environment. To do that we make a freemarker Configuration object accessible as an OSGi service object. That Configuration instance is the main object Freemarker to load and use templates and has an interesting mechanism to override its template loading mechanism we use to make available our OSGi environment templates.</p>
<pre class="java:nocontrols:nogutter">
freemarkerConfig.setTemplateLoader( new URLTemplateLoader() {

@Override
protected URL getURL(String url) {
Stack<TemplateEntry> templateStack = templates.get(url);
if (templateStack!=null) {
	TemplateEntry templateStackTop = templateStack.peek();
	if (templateStackTop!=null) {
		return templateStackTop.getTemplateURL();
	}
	return null;
}
return null;
}

});
</pre>
<p>The service Configuration object is set with a template loader inner class that uses our template holding objects to retrieve templates stored in our OSGi context. Cool.</p>
<p>This also allows us to effectively disable the template refreshing cycles that Freemarker does by default (allegedly making it slightly more efficient). Now we only need to refresh a bundle containing the templates to get the new version. This can be modified by using the appropriate methods on the Configuration service of course. (<i>There is another method explained later</i>).</p>
<p>An interesting feature we can add to exploit the dynamic nature of OSGi is to make templates available in a stack. This means different bundles can dynamically overwrite templates by the same name. Moreover, once a template is removed the previous version becomes available. This can be used to make temporary changes to templates to add or remove diagnostics information, test new templates temporarily, etc.</p>
<p>We do that using a Stack of TemplateEntry objects, TemplateEntry being a helper class to store template entries.</p>
<p>This is all very nice but we have a problem when having multiple versions of the same bundle that hold multiple copies of the same template, this means they will stack and we have no way to access a particular version of a template. To solve this problem we store each template in three different stacks by three different URLs:</p>
<ul>
<li>&#8216;path/file.ftl&#8217;</li>
<li>&#8216;bundle://bundlename/path/file.ftl&#8217;</li>
<li>&#8216;bundle://bundlename:version/path/file.ftl&#8217;</li>
</ul>
<p>In this manner we can use the more generic URL in most cases but still can access specific versions when needed. It is important to think about the dynamic nature of OSGi as well as the possibility of several versions of the same bundle coexisting peacefully in the same environment.</p>
<p>From the perspective of any bundle using the service in the simplest case it only needs to look for a service named &#8216;freemarker.template.Configuration&#8217;. For convenience, the property &#8216;dynamicConfiguration&#8217; is set to &#8216;true&#8217; to coexist peacefully with other Configuration services (maybe coming from an official Freemarker bundle). For instance, if we know for sure our dynamic Configuration service is the only one present we can do:</p>
<pre class="java:nocontrols:nogutter">
context.getServiceReference(Configuration.class.getName());
</pre>
<p>That will give us the highest ranking Configuration service. If there are several such services we can use a call like this to get the one that has the dynamic OSGi loader:</p>
<pre class="java:nocontrols:nogutter">
context.getServiceReferences(Configuration.class.getName(), "dynamicConfiguration=true");
</pre>
<p>There is one last feature which lets bundle users feed an already configured template configuration object to the bundle by publishing a Configuration service with property &#8216;preparedConfiguration&#8217; set to &#8216;true&#8217;. This will get picked up by the bundle and its template loader put in sequence with the dynamic OSGi template loader. This means that any original Configuration settings are maintained (<i>For further information on service filtering based on properties please check the <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/framework/BundleContext.html">BundleContext</a> javadoc.</i>).</p>
<p>Best thing to do is to go and try it by downloading the bundles <a href="http://dani.calidos.com/img/2010/osgi-08/freemarker-bundles-bin.zip">here</a>. Source is also <a href="http://dani.calidos.com/img/2010/osgi-08/osgi-template-source.tar.gz">available</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Little Big Planet 2!</title>
		<link>http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/</link>
		<comments>http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 19:29:41 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[ps3]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=276</guid>
		<description><![CDATA[Els de Media Molecule, com sempre arrasant desde Guilford, UK. Demos impresionants en la roda de premsa de presentació del &#8216;Little Big Planet 2&#8242; durant l&#8217;E3. Els resultats són ben bé espectaculars, com podeu veure. PS: la web oficial de Media Molecule és un exemple molt bo d&#8217;una web corporativa genial que no es pren [...]]]></description>
			<content:encoded><![CDATA[<p>Els de <a href="http://www.mediamolecule.com/">Media Molecule</a>, com sempre arrasant desde Guilford, UK.</p>
<p><img alt="Little Big Planet 2 logo" src="http://dani.calidos.com/img/2010/littlebigplanet2.png" title="Little Big Planet 2" class="alignright" width="285" height="162" /></p>
<p>Demos impresionants en la roda de premsa de presentació del &#8216;Little Big Planet 2&#8242; durant l&#8217;<a href="http://www.e3expo.com/">E3</a>.</p>
<p>Els resultats són ben bé espectaculars, com podeu <a href="http://uk.ps3.ign.com/dor/objects/19675/littlebigplanet-2/videos/e310_lbp2_demo_061510.html;jsessionid=7lgg8e44kggl5?show=hi">veure</a>.</p>
<p>PS: la web oficial de Media Molecule és un exemple molt bo d&#8217;una web corporativa genial que no es pren seriosament a sí mateixa.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Components on the server (6): adding Integration Testing</title>
		<link>http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/</link>
		<comments>http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/#comments</comments>
		<pubDate>Fri, 07 May 2010 19:59:48 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Equinox]]></category>
		<category><![CDATA[integration testing]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=265</guid>
		<description><![CDATA[In this installment of the server-side OSGi series, we add integration testing capabilities to our project. Integration testing goes beyond plain unit testing and checks the interactions between real components. This is in contrast with unit testing, which generally uses mockups to represent components outside the one being tested. Please take a look at previous [...]]]></description>
			<content:encoded><![CDATA[<p>In this installment of the server-side OSGi series, we add integration testing capabilities to our project. Integration testing goes beyond plain unit testing and checks the interactions between real components. This is in contrast with unit testing, which generally uses mockups to represent components outside the one being tested. Please take a look at previous installments, as usual.</p>
<p>In the case of integration testing, it is manly used in a pre-production environment, with a valid build that has all unit tests passed. It can even be used in production to just after a deployment is made, taking care not to have destructive checks or massive load tests in the integration test code. YMMV.</p>
<p>To achieve integration testing we need to check the various OSGi components deployed interact in the way that is expected of them. Therefore we need to test the components in a group and not in isolation. To do that in the OSGi world means we need to have access to the OSGi context from within the tests to access services, call them and check their responses, etc.</p>
<p>To allow for this kind of integration testing within the OSGi environment, we make a slight modification to the excellent test.extender we have already patched in the previous installment.</p>
<p>Basically, the basic test.extender seeks out any JUnit test classes within the fragment bundle, creates an instance using an empty constructor and then fires up the tests. This is activated either by default when the fragment is loaded or by using &#8216;test <bundleid>&#8216; in the console. For further information please see the <a href="http://dani.calidos.com/2010/01/04/components-on-the-server-5-better-unit-testing/">previous post</a> about this subject.</p>
<p>For our integration testing, we add an extra command to test.extender:</p>
<pre class="java:nocontrols:nogutter">
public Object _integrationTest(CommandInterpreter intp) {
        String nextArgument = intp.nextArgument();
    	testExtender.integrationTest(Long.parseLong(nextArgument));
    	return null;
}
</pre>
<p>And we refactor the TestExtender to add the integrationTest method which reuses some of the code to instantiate test cases using a constructor that accepts the OSGi context as a parameter.</p>
<pre class="java:nocontrols:nogutter">
Constructor<?>[] constructors = clazz.getConstructors();
boolean foundConstructor = false;
for (int i = 0; i < constructors.length &#038;&#038; !foundConstructor; i++) {
	Constructor<?> constructor = constructors[i];
	Class<?>[] types = constructor.getParameterTypes();
	if (types.length==1 &#038;&#038; types[0].isInstance(context)) {
		foundConstructor = true;
		EClassUtils.testClass(inspectClass, constructor.newInstance(context));
	}
} // for
</pre>
<p>The OSGi context is passed onto the constructor and then the test class is run. It is obviously up to the test class to use the context appropriately for its integration testing.</p>
<p>In our cache project setup, we can do some useful integration testing on the cache.controller component, basically checking if the interaction with the provider components is behaving as we expect it. The integration testing is also added to a fragment that can be deployed optionally, of course.</p>
<p>We start by creating the fragment and adding a testing class like this:</p>
<p><img alt="Adding test class" src="http://dani.calidos.com/img/2010/osgi-06/junit-test-case.png" title="Adding test class" class="alignnone" width="472" height="540" /></p>
<p>Next, we add the constructor that accepts an OSGi context, which is very simple:</p>
<pre class="java:nocontrols:nogutter">
public CacheIntegrationTest(BundleContext ctx) {
	super();
	this.context = ctx;
}
</pre>
<p>In the setup and teardown methods we get and unget the cache service to perform the testing:</p>
<pre class="java:nocontrols:nogutter">

public void setUp() throws Exception {
	serviceReference = context.getServiceReference(Cache.class.getName());
	controller = (CacheControllerCore) context.getService(serviceReference);

}

public void tearDown() throws Exception {
	context.ungetService(serviceReference);
	controller = null;
}
</pre>
<p>In this case we get the controller cache service and store it in an instance used to perform the tests. This is quite simple and fulfills our intended purpose but we still have the flexibility to make more complex integration testing if needed.</p>
<p>Next we create as many test cases as needed:</p>
<pre class="java:nocontrols:nogutter">
public void testGet() {
	try {
		controller.init();
		double v = Math.random();
		String k = "/k"+v;
		controller.set(k, v);
		assertEquals(v, controller.get(k));
	} catch (CacheProviderException e) {
		e.printStackTrace();
		fail(e.getMessage());
	}

}
</pre>
<p>It should be noted that while the code looks like regular testing code, it is actually using real services from the OSGi environment as opposed to mockups. This means we are testing the real integration between components as well as the individual controller component code. The disadvantage here is that if there is an error in the controller we might mistake the problem with an issue with the services used. In conclusion, having integration code doesn&#8217;t negate the need to have unit tests.</p>
<p>Once we load the fragment onto the environment, first we need to obtain the bundle id of the integration fragment and then launch the integration testing in this manner:</p>
<p><code><br />
osgi> integrate 125<br />
Bundle : [125] : com.calidos.dani.osgi.cache.controller.integration<br />
_<br />
CLASS : [com.calidos.dani.osgi.cache.controller.CacheIntegrationTest]<br />
___________________________________________________________________________<br />
Method : [ testInit ] PASS<br />
Method : [ testInitInt ] PASS<br />
Method : [ testSize ] PASS<br />
14:21:43,077 WARN  CacheControllerCore Couldn't clear some of the provider caches as operation is unsupported<br />
14:21:43,077 WARN  CacheControllerCore Couldn't clear some of the provider caches as operation is unsupported<br />
Method : [ testClear ] PASS<br />
Method : [ testSet ] PASS<br />
Method : [ testGet ] PASS<br />
Method : [ testGetStatus ] PASS<br />
___________________________________________________________________________<br />
</code></p>
<p>The results tell us that all operations are OK but we need to bear in mind that the clear operation is not supported in some backend caches. If this is what is expected by the operator then all is fine.</p>
<p>We take advantage of the new integration testing functionality to make some extensive changes to logging and exception handling of the controller code. By running the integration tests we make sure all seems to work fine  (even though we still need some proper unit testing of the controller). Modifications are made quite quickly thanks to the integration tests.</p>
<p>To recap, we&#8217;ve added integration testing support to the existing &#8216;test.extender&#8217; bundle and created integration testing code for the cache controller component. This has allowed us to make code changes quickly with less risk of mistakes.</p>
<p><a href="http://dani.calidos.com/img/2010/osgi-06/test-extender-patch.txt">Here</a> you can find a patch for the test extender project as well as the patched <a href="http://dani.calidos.com/img/2010/osgi-06/test.extender-1.0-SNAPSHOT.jar">testing bundle</a> already compiled. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El manifest &#8211; Unlink your feeds</title>
		<link>http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/</link>
		<comments>http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/#comments</comments>
		<pubDate>Sat, 01 May 2010 11:48:54 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[microblogging]]></category>
		<category><![CDATA[social network]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=263</guid>
		<description><![CDATA[Gràcies al Roger per enllaçar al manifest &#8216;Unlink your feeds&#8216;, em subscric totalment a la iniciativa. La idea és anar amb molt de compte en enllaçar els posts i updates de microblogging entre els diferents serveis, no sempre és lo òptim. Com diu el mateix Roger: Un clam al cel perquè la gent deixi de [...]]]></description>
			<content:encoded><![CDATA[<p>Gràcies al <a href="http://www.ambcompte.net/general/internet/unlink-your-feeds-no-diguis-el-mateix-a-facebook-twitter-buzz/">Roger</a> per enllaçar al manifest &#8216;<a href="http://unlinkyourfeeds.tumblr.com/post/387644253/a-manifesto">Unlink your feeds</a>&#8216;, em subscric totalment a la iniciativa.</p>
<p>La idea és anar amb molt de compte en enllaçar els posts i updates de microblogging entre els diferents serveis, no sempre és lo òptim. Com diu el mateix Roger:</p>
<blockquote><p>
Un clam al cel perquè la gent deixi de reaprofitar el mateix missatge per a totes les xarxes socials. Crea soroll innecesari, molts cops perd context (hashtags a facebook, etc…) i molesta. Ok a que em diguis “avui he dinat molt bé”, però no necessito rebre-ho per triplicat.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash on iPhone OS: two extra reality checks</title>
		<link>http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/</link>
		<comments>http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 19:09:25 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Digital Video]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[daring fireball]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flash is dead]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=247</guid>
		<description><![CDATA[Unless you live in a remote and far away place you will have heard of the media impact of Apple&#8217;s decision to ban the Adobe Flash to iPhone solution and the various discussions that have ensued. I won&#8217;t bother with providing more links. I love John Gruber&#8217;s take and Louis Gerbarg&#8217;s as well. Both J.G. [...]]]></description>
			<content:encoded><![CDATA[<p>Unless you live in a remote and far away place you will have heard of the media impact of Apple&#8217;s decision to ban the <a href="http://www.loopinsight.com/2010/04/11/adobe-unveils-creative-suite-5/">Adobe Flash to iPhone</a> solution and the various <a href="http://daringfireball.net/linked/2010/04/10/lynch">discussions</a> that have <a href="http://www.devwhy.com/blog/2010/4/12/its-all-about-the-framework.html">ensued</a>. I won&#8217;t bother with providing <a href="http://www.macworld.com/article/150529/2010/04/macalope_flash.html">more links</a>. I love John Gruber&#8217;s take and Louis Gerbarg&#8217;s as well.</p>
<p>Both J.G. and L.G. have brought up many valid points: Adobe dragged their heels on Flash for mobile for a looooong time. There have been countless detabes and blog posts.</p>
<p>I&#8217;ll bring two further arguments, one logical and one historical, the latter being one that I believe hasn&#8217;t been brought up yet. </p>
<p><b>Logical argument: the fallacy of Flash being cross-platform</b></p>
<p> Moreover, why should we choose to lock ourselves onto Adobe&#8217;s propietary API instead of Apple&#8217;s propietary API? Why is Adobe&#8217;s API, specs and runtime superior to any others? Many would say the main reason (the only?) is that it&#8217;s <i>crossplatform</i>?</p>
<p>Wikipedia says that <a href="http://en.wikipedia.org/wiki/Crossplatform">cross-platform</a> means: </p>
<blockquote><p>&#8220;an attribute conferred to computer software or computing methods and concepts that are implemented and inter-operate on multiple computer platforms&#8221;.</p></blockquote>
<p>Oh, okay, so multiple means Windows, Mac and Linux <b>desktops</b>. Hello?!? Anyone there?!? This is 2010 and the 90&#8242;s called because they want their meaning of &#8220;platform&#8221; back. Nowadays, <i>multiple</i> means desktop <b>and</b> mobile. Therefore:</p>
<ul>
<li>Flash Lite is a joke. Where are the multiplicity of mobile devices supporting proper Flash 10.1 today? </li>
<li>Where is the pervasive <a href="http://androinica.com/2010/02/25/flash-10-1-will-not-be-supported-on-all-android-phones/">Android support</a> today? HTC Hero buyers are screwed, a phone bought as little as less than a year ago won&#8217;t be supported.</li>
<li>Where is the support for Windows Mobile devices? <a href="http://www.coated.com/no-adobe-flash-support-on-windows-mobile-6-5/">Not there until WinMo7</a>. You mean it will be supported on a OS that it&#8217;s not even there yet?</li>
</ul>
<p>Well, you could say that the Open Screen Project and the releasing of the FLV, SWF and the lot specs are true multiplatformness&#8230; Well, so far so good but where is the real market traction? Where are the tried-and-true implementations? Adobe has released this technology but until it gains traction it&#8217;s no more than a glorified press release. Apple can play this game too, with tech such as <a href="http://webkit.org/">WebKit</a> which is <a href="http://en.wikipedia.org/wiki/WebKit">used</a> in a zillion <a href="http://blogs.zdnet.com/Apple/?p=2208">places</a> including Adobe&#8217;s own Air platform. Press releases and freeing technologies are irrelevant until <i>adopted</i>. A good initiative which I applaud, but still not widely used.</p>
<p>No, Flash is not cross-platform anymore. What is the marketshare of the mobile devices capable of running Flash 10.1? Nowhere big enough for Adobe to be pulling muscle and demanding anything. It seems Adobe is using Flash devs and aficionados as cannon fodder or -as Gerbarg more aptly puts it-, &#8220;Adobe used its userbase and their livelihood as a bargaining chip&#8221;. Adobe dragged its feet for years in the mobile arena and now is paying for its mistakes.</p>
<p><b>Historical argument: <del datetime="2010-04-12T19:19:12+00:00">Macromedia</del> Adobe has screwed its own developers like this before</b></p>
<p>In the nineties Macromedia had a great product already. It was cross-platform (as per 90&#8242;s definition), had powerful scripting capabilities, an powerful extension architecture, a great browser plug-in runtime that was also cross-platform, video capabilities, awesome rapid development tools, stellar graphics integration, built-in debugger, great performance, etc. It was called Director and it was really cool.</p>
<p>Then Macromedia bought FutureSplash in 1996 which would be later renamed to Flash. It had far less capabilities that Director at the time (no real scripting at the beginning, etc.) and would remain technically inferior for sometime, having no debugging and many other features being missing for a long while. However, it had three distinct advantages. Strike one: having less features and being a newer codebase meant it could have a more lightweight runtime than the Director one. Strike two: it had support for vector graphics, which desktop CPUs at the time were just capable of displaying and animating adequately. Director came from a less CPU-intensive bitmap background, faster but consuming more space than vector definitions and looking less sleek in many cases.</p>
<p>One &#8220;advantage&#8221; remained. So what did Macromedia do? Take advantage of the FutureSplash technology acquisition and the Director established developer base? It could have easily added the vector drawing technology into Director (it supported many types of media already). Refactoring the code and runtime would be no trivial feat but doable. Any Director developer would have been OK with a new restriction being put into place that meant only vector-graphics resources being allowed any new Director web runtime, would have welcomed and embraced such a change.</p>
<p>Strike three: Macromedia realised that with the maturity and feature-complete of Director no long-winded upgrade path was in sight. Just adding vector graphics and a streamlined runtime would do for one or two Director upgrades, no more. They thoroughly screwed the existing loyal developer base royally and released a sleek new 1.0 Flash product. Then they spent years releasing upgrades that added features that had already been present in Director for some time. They created another cash cow, a cow that would ride the wave of the Web explosion of the .com era. Director out. And no, I&#8217;m not buying any of the &#8220;official&#8221; reasons for its languishing and Flash emergence. It was all about <i>money</i>.</p>
<p>I am not crying for Director&#8217;s demise -or rather, being put into life-support mode. It was a good platform and many (myself included) made good money using it. This doesn&#8217;t mean Adobe didn&#8217;t screw up many of its own developers and went in for the next cash cow.</p>
<p>I am not buying Flash developers and supporters taking offense and the moral high ground, the company (now Adobe) you support has done a much worse thing to its <i>own developers</i>. Why should Apple even care for developers of other platforms? Just because you learned a framework and are scared of it fading away doesn&#8217;t mean anything&#8230; Some of us have done this many times before and moved on&#8230;</p>
<p><b>Final word: put your code where your mouth is</b></p>
<p>Okay. Time to recap, folks. If Flash is such a great platform -it&#8217;s actually not bad but not that good either- go ahead and develop these killer apps on Android or WinMo7 whenever that comes out. With killer apps being available on competing platforms making a huge difference Apple will simply change the clause and allow you in. They&#8217;re not stupid. </p>
<p/>
Now stop crying and start coding. Myself, will try to put this out of my mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apple i Google: I això que no eren amics&#8230;</title>
		<link>http://dani.calidos.com/2010/03/27/apple-i-google-i-aixo-que-no-eren-amics/</link>
		<comments>http://dani.calidos.com/2010/03/27/apple-i-google-i-aixo-que-no-eren-amics/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 13:38:52 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=239</guid>
		<description><![CDATA[Els de Gizmodo ens han regalat una xafarderia un xic inusual&#8230; L&#8217;Eric Schmidt de Google i el Steve Jobs d&#8217;Apple prenent un café en un bar de Palo Alto. I això que teòricament estaven en &#8220;peu de guerra&#8220;. Serà que han enterrat la destral&#8230;?]]></description>
			<content:encoded><![CDATA[<p>Els de Gizmodo ens han regalat una xafarderia un xic inusual&#8230; L&#8217;Eric Schmidt de Google i el Steve Jobs d&#8217;Apple <a href="http://gizmodo.com/5503004/steve-jobs-and-eric-schmidt-spotted-together-again">prenent un café</a> en un bar de Palo Alto.</p>
<p>I això que teòricament estaven en &#8220;<a href="http://gizmodo.com/5483662/how-apple-and-googles-romance-turned-to-hate">peu de guerra</a>&#8220;. Serà que han enterrat la destral&#8230;?</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/03/27/apple-i-google-i-aixo-que-no-eren-amics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox for N900 with Flash disabled. Ah, the irony&#8230;</title>
		<link>http://dani.calidos.com/2010/02/02/firefox-for-n900-with-flash-disabled-ah-the-irony/</link>
		<comments>http://dani.calidos.com/2010/02/02/firefox-for-n900-with-flash-disabled-ah-the-irony/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 23:44:39 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Digital Video]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flash is dead]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[ipad]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=232</guid>
		<description><![CDATA[From the Firefox for Nokia N900 1.0 release notes themselves, stumbled upon this little gem: Initially, Firefox for N900 does not support browser plug-ins. Due to performance problems using Adobe Flash within Firefox on many websites, especially those with multiple plug-ins on them, we have disabled plugins for Firefox for Maemo 1.0. We plan to [...]]]></description>
			<content:encoded><![CDATA[<p>From the Firefox for Nokia N900 1.0 <a href="http://www.mozilla.com/en-US/mobile/1.0/releasenotes/">release notes</a> themselves, stumbled upon this little gem:</p>
<blockquote><p>
Initially, Firefox for N900 does not support browser plug-ins. Due to performance problems using Adobe Flash within Firefox on many websites, especially those with multiple plug-ins on them, we have disabled plugins for Firefox for Maemo 1.0. We plan to provide a browser add-on that will enable you to selectively enable plugins on certain sites, because some sites, like YouTube, work well.
</p></blockquote>
<p>So the good folks of the Mozilla Foundation have gone and released the thing. Given the recent turn of events, it&#8217;s interesting to see <a href="http://blogs.adobe.com/flashplatform/2010/01/apples_ipad_--_a_broken_link.html">the reality brick hitting the Adobe head</a>, so to speak. Couldn&#8217;t think of a more appropriate support for the <a href="http://www.apple.com/ipad/">Apple iPad</a>, really.</p>
<p>Even if the eventually release it with plug-in support enabled, they will probably stick with letting users enable Flash selectively&#8230; This is <a href="http://dani.calidos.com/2009/09/22/flash-the-wider-picture-of-an-identy-crisis/">yet another nail in the Flash coffin</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/02/02/firefox-for-n900-with-flash-disabled-ah-the-irony/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>El disseny d&#8217;interfícies no és cosa de molts</title>
		<link>http://dani.calidos.com/2010/01/17/el-disseny-dinterficies-no-es-cosa-de-molts/</link>
		<comments>http://dani.calidos.com/2010/01/17/el-disseny-dinterficies-no-es-cosa-de-molts/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 21:24:39 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[UXD]]></category>
		<category><![CDATA[disseny]]></category>
		<category><![CDATA[informatica]]></category>
		<category><![CDATA[usabilitat]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=229</guid>
		<description><![CDATA[Article boníssim sobre el disseny d&#8217;interfícies i l&#8217;impacte de qualsevol decisió de disseny sobre l&#8217;usabilitat. Ens parla dels compromisos inherents en qualsevol decisió de disseny. També del mal que pot fer el disseny d&#8217;aplicacions en un comité on tothom hi diu la seva. També planteja la idea d&#8217;objectivar les decisions que es prenguin i construïr [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.digital-web.com/articles/user_interface_design_taking_the_good_with_the_bad/">Article</a> boníssim sobre el disseny d&#8217;interfícies i l&#8217;impacte de qualsevol decisió de disseny sobre l&#8217;usabilitat.</p>
<p>Ens parla dels compromisos inherents en qualsevol decisió de disseny. També del mal que pot fer el disseny d&#8217;aplicacions en un comité on tothom hi diu la seva. També planteja la idea d&#8217;objectivar les decisions que es prenguin i construïr si cal una taula amb les avantatges i les consequències de cadascuna de les decisions.</p>
<p>Lectura obligada si ens dediquem al disseny i conceptualització de productes. Bookmark afegit.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/01/17/el-disseny-dinterficies-no-es-cosa-de-molts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Components on the server (5): better Unit Testing</title>
		<link>http://dani.calidos.com/2010/01/04/components-on-the-server-5-better-unit-testing/</link>
		<comments>http://dani.calidos.com/2010/01/04/components-on-the-server-5-better-unit-testing/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 23:20:15 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Equinox]]></category>
		<category><![CDATA[java servlets]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[tomcat]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=217</guid>
		<description><![CDATA[In this installment of the OSGi series, we add more complete Unit Testing support in the project. We also establish that some behaviour of the Servlet Bridge may not be what we want and then provide a way to customize it. Please make sure you read the previous installments before you continue with this article… [...]]]></description>
			<content:encoded><![CDATA[<p>In this installment of the OSGi series, we add more complete Unit Testing support in the project. We also establish that some behaviour of the Servlet Bridge may not be what we want  and then provide a way to customize it.</p>
<p><span id="more-217"></span></p>
<p>Please make sure you read the<a href="http://dani.calidos.com/category/computing/java/"> previous installments </a>before you continue with this article…</p>
<p>To ensure greater flexibility, performance and encapsulation, we will be using OSGi fragments.</p>
<p>http://static.springsource.org/osgi/docs/1.1.3/reference/html/appendix-tips.html</p>
<p>OSGi fragments attach to &#8220;host&#8221; bundles and can be used to extend functionality, provide configuration and even extra manifest entries.</p>
<p>On the first part, we move our unit tests to fragments. This has the benefit of being able to separate tests from actual code as well as allowing us to deploy using a smaller footprint in situations where we don&#8217;t want test code such as production deployments.</p>
<p>If we start with the cache code we&#8217;ve got so far we need to separate the test code from two bundles: &#8216;com.calidos.dani.osgi.cache.provider.memory&#8217; and &#8216;com.calidos.dani.osgi.cache.provider.memcached&#8217;. That is easy enough.</p>
<p>We create a new OSGi bundle fragment project like this:</p>
<p><img alt="New fragment" src="http://dani.calidos.com/img/2010/osgi-05/new-fragment.png" title="New fragment" width="472" height="566" /></p>
<p>We specify the bundle the new fragment is attaching to:</p>
<p><img alt="Specify host bundle" src="http://dani.calidos.com/img/2010/osgi-05/specify-bundle.png" title="Specify host bundle" width="455" height="107" /></p>
<p>The next step is to move the JUnit code from the main bundle onto the fragment. If we run the test independently we see that it passes as the classpath of the host and fragment bundles is merged into one.</p>
<p>We then add the fragment to our existing run configuration and it will be loaded onto our environment. So far so good, but there is no way to run the tests outside our controlled Eclipse.</p>
<p>Slim Ouertani at Javalobby shows us how to <a href="http://java.dzone.com/articles/osgi-junit-test-extender-using">run fragment tests from within the OSGi environment</a> in a great article. His code uses the new bundle tracker feature to discover any test fragments and exposing functionality to be able to run the tests.</p>
<p>You can get the source at kenai: <a href="http://kenai.com/projects/testosgifragment">http://kenai.com/projects/testosgifragment</a></p>
<p>We read the article thoroughly, fetch the source and build test.extender using maven:</p>
<p><code><br />
mvn install<br />
</code></p>
<p>The code works great but has a bug which is triggered when the code looks for the host of the fragment by reading the &#8216;Fragment-Host:&#8217; header. If the value specifies any kind of version qualifier it fails. It also crashes when trying to test a bundle or a fragment that doesn&#8217;t have the &#8216;Unit-Test&#8217; custom header.</p>
<p>The &#8216;Unit-Test&#8217; custom header lives on the fragment manifest and is used by test.extender to control who is able to be tested and if tests are done manually or automatically.</p>
<p>If no &#8216;Unit-Test&#8217; header is present or if its value is empty, test.extender will refuse to run any tests present on the bundle. If the value is &#8216;true&#8217; then test.extender will run the tests automatically whenever the test fragment bundle is loaded. If the value is anything else the tests won&#8217;t run automatically but you can still run them using the &#8216;test&#8217; and &#8216;testall&#8217; commands.</p>
<p>I have patched the code to accept a version qualifier for the fragment host as well as giving out an informative error message when attempting to test the wrong bundle.</p>
<p>Once this is done, we play with the test.extender by obtaining the fragment bundle id and issuing &#8216;test &lt;id&gt;&#8217; on the console:</p>
<p><code><br />
osgi&gt; test 80<br />
Bundle : [80] : com.calidos.dani.osgi.cache.provider.memory.test<br />
_<br />
CLASS : [com.calidos.dani.osgi.cache.provider.memory.test.MemoryCacheTest]<br />
___________________________________________________________________________<br />
Method : [ testClear ] PASS<br />
Method : [ testInit ] PASS<br />
Method : [ testInitInt ] PASS<br />
Method : [ testSize ] PASS<br />
Method : [ testSet ] PASS<br />
Method : [ testGet ] PASS<br />
Method : [ testGetStatus ] PASS<br />
___________________________________________________________________________<br />
_<br />
</code></p>
<p>We can also use the &#8216;testall&#8217; command which will look for all the testable fragment bundles and run the test there.</p>
<p>Having tested that functionality, we separate the tests from the memcached bundle and move them onto their own bundle.</p>
<p><a href="http://dani.calidos.com/img/2010/osgi-05/test-fragments.tar.gz">Here</a> you can download the two test fragments and the <a href="http://dani.calidos.com/img/2010/osgi-05/test-extender-patch">patch</a> to modify test.extender, neat.</p>
<p>Ok then, we move onto the next thing that is looking closely at the Servlet Bridge and its behaviour. What we are interested in is what happens when the container deploys and inits the Web app itself, starting up the servlet bridge. The bridge uses the container temporary folder to deploy the OSGi environment in a subfolder, copying any bundles into that subfolder. If the subfolder exists and there are bundles that have the same names, they won&#8217;t be copied. I have found this behaviour to be very confusing for newbies to the platform and very annoying for veterans. I&#8217;m not entirely sure if this is deliberate and has performance reasons or what. Calling the framework controls to prevent that is not optimal and manually removing the temporary folder isn&#8217;t, either. One possible solution would be to use a building system that increments the micro number every time there is a build and remember to clear up the container temporary folder from time to time. That is not always desirable or possible but fortunately, the servlet bridge implementation provides a way to customize it to our heart&#8217;s content.</p>
<p>Basically we have the following code in the bridge init() method:</p>
<pre class="java:nocontrols:nogutter">
	framework.init(getServletConfig());
	framework.deploy();
	framework.start();
	frameworkStarted = true;
</pre>
<p>In this case, &#8216;framework&#8217; is a instance of the FrameworkLauncher class which is created just before this code snippet. The FrameworkLauncher is the class responsible for deploying and launching OSGi. We note that the object is created by default as a plain FrameworkLauncher instance. However, the class to be used can be customized by specifying it in the web.xml file using the  &#8216;frameworkLauncherClass&#8217; servlet initialization parameter. As long as that class is a subclass of FrameworkLauncher the appropriate contract is fulfilled.</p>
<p>This means we can override some behaviour and delete the framework deployment folders upon startup:</p>
<pre class="java:nocontrols:nogutter">
@Override
public void init() {

super.init();

File servletTemp = (File) context.getAttribute("javax.servlet.context.tempdir");
File platformDirectory = new File(servletTemp, "eclipse");

if (platformDirectory.exists()) {
	deleteDirectory(platformDirectory);
}

}
</pre>
<p>Cool, so we need to export this as a jar file named dani-frameworklauncher.jar into the package project lib folder:</p>
<p><img alt="Export framework launcher" src="http://dani.calidos.com/img/2010/osgi-05/export-launcher.png" title="Export framework launcher" width="485" height="589" /></p>
<p>Next we change the servletbridge web.xml configuration parameter to load the new framework launcher:</p>
<p><code><br />
&lt;init-param&gt;<br />
&lt;param-name&gt;frameworkLauncherClass&lt;/param-name&gt;<br />
&lt;param-value&gt;com.calidos.dani.osgi.servletbridge.FrameworkLauncher2&lt;/param-value&gt;<br />
&lt;/init-param&gt;<br />
</code></p>
<p>To test, we can add a file onto the $APACHE_TOMCAT/work/Catalina/localhost/<webappname>/eclipse folder and restart Tomcat. Before this new launcher was in place, the file would be kept but now it is deleted alongside the rest. Any other methods can also be extended to customize the bridge behaviour without having to modify the launcher class.</p>
<p><a href="http://dani.calidos.com/img/2010/osgi-05/dani-framework-launcher.tar.gz">Here</a> you can download the framework launcher project, put it on the WEB-INF/lib folder alongside the servlet bridge and enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/01/04/components-on-the-server-5-better-unit-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automàticament Monster Lego</title>
		<link>http://dani.calidos.com/2009/12/27/automaticament-monster-lego/</link>
		<comments>http://dani.calidos.com/2009/12/27/automaticament-monster-lego/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 21:07:28 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[lego]]></category>
		<category><![CDATA[música]]></category>
		<category><![CDATA[the automatic]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=213</guid>
		<description><![CDATA[Fent unes reescoltes he trobat aquest genial remake del clàssic &#8216;Monster&#8217; dels galesos The Automatic. Genial!]]></description>
			<content:encoded><![CDATA[<p>Fent unes reescoltes he trobat aquest genial remake del clàssic &#8216;Monster&#8217; dels galesos <a href="http://theautomatic.co.uk/">The Automatic</a>. Genial!</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/yrLumdqIrDM&#038;hl=es_ES&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/yrLumdqIrDM&#038;hl=es_ES&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2009/12/27/automaticament-monster-lego/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
