lunedì 23 agosto 2010

Oracle on Dalvik, ZFS

As any other java developer, I'm following the lawsuite of Oracle on Google and found this: Dalvik: how Google routed around Sun’s IP-based licensing restrictions on Java ME
It dates back to November 12th, 2007 and cites:

* The Apache License v2 forces the contributor to license the IP along with the code but only the IP that the contributor owns (you can’t give away stuff others own, obviously). This means that if Android does, in fact, use some of Sun’s IP, it is entirely possible for Sun to sue any hardware vendor that ships Android with their phones and prevent them from shipping. Also, Sun could knock at your own door and ask you to license the Java IP that you need to be able to run Android on your phone (in case, say, you bought an OEM phone and installed the software yourself) even if there is no trace of ‘java’ on your phone memory.

It's intersting to read just below, and you find something about ZFS:

* Sun is under fire for IP issues related to ZFS and they claimed that it’s an “attack on free software”. I’m curious to see how they’re going to spin their own IP attack on Android (because I bet there’s going to be one).

The author refers to NetApp against Sun, now Oracle, on ZFS, see link on status on july 2010

I'm sad for Java VM and Android, but I think Google should find an agreement because it's going to loose. Google doesn't have, to my knowledge, other patents to exchange for with Oracle.
Otherwise Google has to indemnify its partners and set apart a lot of money in case of defeat, just to protect Android's momentum in the mobile market.
Any VM implementation is at risk, it's not for JVM only, so no Android 4.0 based on other languages.
Or perhaps Google should acquire NetApp and others to have a bunch of patents to exchange for Dalvik, go Google !

lunedì 2 febbraio 2009

Remember: close your Hibernate Session after a rollback

Yet another time Hibernate stroke me down, and I keep forgetting about this so I write it down forever: always close your Hibernate Session after a rollback happens.
This time I had an hard time trying to understand what was going on.
I'm trying Google Guice and warp-persist with wicket, so I wrote a simple one page application to test transaction management.
One transactional method threw an exception, I caught it in the upper application layer and tried to manage the error: my test did nothing other than write a log line.
I had my transaction rolled back, but my entity object was anyway written in the database. What took me away from the right direction was that an (almost) identical application instead worked (no record written in the db).
Eventually a managed to understand: I tried a session.flush() just before throwing my exception and everything was rolled back.
My fault was to think my session was sort of rolled back too, or at least empty.
Instead it was in Flushmode.AUTO, and the roll back happened BEFORE anything was written by my session to the db.
My entity object continued to be bound to that session.
After I caught the exception and logged one line, control went back to the application and a flush was eventually done by warp-persist open-session-in-view-filter, writing the record in the db.
My other almost identical application worked just because it did a different query inside that transaction, and Hibernate decided (do you remember Flushmode.AUTO ?) it was better to flush my session before executing that query, and so it applied rollback accordingly.
I think it's better to set flushmode.COMMIT: it's more natural to think that way, in my opinion. Anyway, if you catch exception from a transaction, close your session and get a new one.

venerdì 5 settembre 2008

ISPCONFIG SUPHP and OPEN_BASEDIR

I'm a system administrator of a linux hosting server (ubuntu 8.0.4).
I chose to adopt ispconfig together with suphp.
I had PEAR not working, and in phpinfo() the variable open_basedir pointed only to the root of the hosting space (something like /var/www/web7).
I needed to add /tmp and /usr/share/php to each open_basedir vhost, but with suphp you use php CGI, so you can't use php_admin_value.
I was going crazy too to find out where open_basedir was set: not in Vhosts_ispconfig.conf, not in php.ini ....
I found the way out looking at /etc/suphp.conf at the line:

x-httpd-php=php:/home/admispconfig/ispconfig/tools/suphp/usr/bin/php-wrapper

So I took a look at php-wrapper, and there it was:

exec php-cgi -d open_basedir=${BASEDIR} -d upload_tmp_dir=${TMPDIR} -d session.save_path=${SESSDIR} -d safe_mode=${SAFE_MODE}

where BASEDIR=`dirname ${DOCUMENT_ROOT}`
So, if you have the same problem as I, define a new variable:

OPEN_BASEDIR="/tmp:/usr/share/php:"${BASEDIR}

and put it in the above line as follows:

exec php-cgi -d open_basedir=${OPEN_BASEDIR} -d upload_tmp_dir=${TMPDIR} -d session.save_path=${SESSDIR} -d safe_mode=${SAFE_MODE}

NOTE: if you successively upgrade ispconfig package, remember to re-apply the above patch.

domenica 27 luglio 2008

Web character encoding: many places to config it right

I start this entry only with few out-of-order notes: I'll put more info when I have more time.
To avoid surprises, choose UTF-8 and don't leave defaults: configure all the pieces you use.
For me, they are:
- tomcat 5.5: in server.xml, for all your connectors, set:
connectionTimeout="20000"
redirectPort="8443"

URIEncoding="UTF-8"
useBodyEncodingForURI="true"

/>
(see: http://tomcat.apache.org/tomcat-5.5-doc/config/http.html)
(see for SEAM: https://cloud.prod.atl2.jboss.com/jira/browse/JBSEAM-3148?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel)

- in JSF+facelets: (encoding of xml files + view + meta)
- to check, in browser you have to see meta and http header (mind double headers-> correct IIS or APACHE)
- html form: add accept-encoding

A must read: http://www.javaworld.com/javaworld/jw-04-2004/jw-0419-multibytes.html?page=7

mercoledì 12 dicembre 2007

Seam Spring and connections lost

Using high level frameworks as seam and spring, you think you are safe from dangerous things like loosing open connections to your db .... but it happened.
I don't know why yet, but using spring transactions with seam and an hibernate transaction manager my webapp was eating connections, expecially when starting (and not ending) long running conversations. Reload many times the page with @Begin and my webapp was lost.
My solution was to switch to JTA, and it was really simple when:

1) found the right hint at http://archives.free.net.ph/message/20071121.214555.86512d04.en.html to choose the right JTA implementation for my postgresDB (that for now is not in the supported list of BTM, I hope for the better ;-) );
2) read BTM article to configure it in spring;
3) downloaded latest jdbc driver for postgres, with a must have fix.

IMPORTANT:
you have to configure hibernate.connection.release_mode to after_statement (with JTA) beacause Spring changes default to on_close, and long running conversations keep the hibernate session open (and hopefully disconnected from db connection).
Moreover, as written in Seam docs, set hibernate.transaction.flush_before_completion to true, so to flush the session before commit of surrounding transaction.

<!-- I have this in my hibernate.cfg.xml -->
<property name="hibernate.connection.release_mode">after_statement</property>
<property name="hibernate.transaction.flush_before_completion">true</property>



OTHER NEEDED CONFIGURATIONS:
---------------------------------------------------------------
Spring's application.xml:

<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close">
<property name="className" value="org.postgresql.xa.PGXADataSource" />
<property name="uniqueName" value="pgsql" />
<property name="minPoolSize" value="0" />
<property name="maxPoolSize" value="${db.maxActive}" />
<property name="driverProperties">
<props>
<prop key="databaseName">ibusiness_web</prop>
<prop key="user">${db.user}</prop>
<prop key="password">${db.pwd}</prop>
</props>
</property>
</bean>

<!-- Bitronix Transaction Manager embedded configuration -->
<bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="spring-btm" />
</bean>

<!-- create BTM transaction manager -->
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig,dataSource" destroy-method="shutdown" />


<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="configLocation" value="/WEB-INF/classes/hibernate.cfg.xml" />
</bean>

<bean id="seamSessionFactory" class="org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean">
<property name="sessionName" value="hibernateSession"/>
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="seamSessionFactory" />
</property>
</bean>


<!-- Spring JtaTransactionManager -->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>


-----------------------------
Seam's components.xml:


<persistence:managed-hibernate-session name="hibernateSession" auto-create="true" session-factory="#{sessionFactory}"/>
<spring:spring-transaction platform-transaction-manager="#{transactionManager}"/>
<spring:context-loader config-locations="/WEB-INF/application.xml"/>




---------------------------------------------------------------
NOTE: in application.xml use as reference for other beans seamSessionFactory as the only sessionFactory. sessionFactory is defined in Spring only to be wrapped by Seam in components.xml.
---------------------------------------------------------------

Thanks to spring, I didn't change a line of code, and very few of xml.
Thanks to seam, now I can leverage its long running conversations to improve my app.

Thanks to google and all of you who share their good and bad experiences, so I do now.

Seam and asynchronous email send

Over the past 3 months I've ported a JSF 1.1 business application written last year to Seam.
I'll talk of the hurdles I met, expecially porting from myfaces 1.1 to JSF RI 1.2, but now I just want to share with you my few successes.
In seam you can send an email using facelets as template engine. You can do it in same thread that displays you page, but due to high latency of smtp servers and other reasons, it's better to send it asynchronously.
My webapp is a POJO webapp, built upon spring,hibernate and seam.
All you have to do to spawn a new thread is to annotate your method with @Asynchronous, but watch out !
If your code was already working when doing it inside the display thread, now it surely will break.
WHY:
1) when seam spawns a thread, you loose the previous event/page/conversation context, so you have to put the objects you use inside the email template in a new context:

@Asynchronous
public void send(Account account) {
try {
Contexts.getConversationContext().set("account", account);
Renderer.instance().render("/email/activatedaccount.jsf");
} catch (Exception e) {
e.printStackTrace();
}

2) you loose your webapp relative paths too: if inside a display thread seam uses the ServletContext to retrieve the full path to your email template (and the resources it uses). Inside a spawned thread seam replaces the servletContext with a mockContext which resamble a ResourceBundle strategy to find resources in the classpath. So you have to move /email dir in WEB-INF/classes, togheter with the resources it uses (logo images etc..).

3) I happened to use one backing bean to process the page action, and call a send(account) method of the same class. When I marked that method @Asynchronous and debugged inside Eclipse, I saw the thread was the tomcat's one, not a new spawned one. I solved it moving the send method in another class and calling it in a new istance:


public String approve(Account account) {
...
architectMailer.send(account);
...
}

4) There's a bug (fixed in next release, perhaps already in 2.0.1 CR of tonight) about inline images not being displayed in thunderbird, but only attached. Don't go crazy, it's not your fault: wait for next release.

My 2 cents

Hope this helps

giovedì 16 novembre 2006

Let's start !

Hello ! This is my first and only blog.
I'm a java developer since 1999, and a PC enthusiast by the time of Commodore VIC 20.
I managed to see (and use) basic (Vic20, Sinclair QL, early VB), motorola assembler 68000, lisp , Pascal, Turbo C and assembler 386, C++.
Now I'm fond of Java (again and ever more), C++ and Linux, and I'm looking forward to buy a Mac and put inside Linux, VMware and Windows to be really multiplatform (and test).
As a team leader and consultant, I meet many young developers that really don't know why things work the way they do, so they cannot understand what appens when something goes wrong: I'm talking about linkers, mapped I/O, TCP-IP protocol and nowadays the difference between multitasking and multithreading (in a multicore world), and virtual memory and sector and clusters etc...
OK, I feel old and should be if more often than ever I meet colleagues younger than me ...
And it's a good thing young developers want to learn new things like Ruby on Rails etc.. Me too.
But you can't forget the history of IT industry, the good and the bad things done, and learn by studying not only by doing (an excuse of IT manager not to invest and pay for knowledge improvement of his workers, and for developers not to take their job seriously).
My lesson learnt , the one I find leading my actions as a professional is:
know what you're doing, and learn to do it better, the right way (that's why the title for my blog).
I get upset when someone says "it just works, so it is OK".
If I you do something good (or bad) and you don't know why, sooner or later it will explode in your face.
Don't invent the wheel each time, but improve what you previously did.
Reuse your knowledge, and improve it.
Code reuse is less important, but don't re-engineer too often: take a decision and carry on it before changing idea.
You are your best capital.