domenica, dicembre 28, 2008

BLOB type in MySQL

I had this exception when I was trying to insert a big image in a BLOB column using MySQL.

java.sql.BatchUpdateException: Data truncation: Data too long for column 'picture' at row 1


The problem didn't happen with small images, i.e. with the size of 2,3Kb. After spent some time to investigate about the problem, I understood that the reason is due to the BLOB type in MySQL whose maximum size is 64k. Therefore if you want to store big binary data in a MySQL database you need to use another blob type as MEDIUMBLOB or LONGBLOB.
If you are using JPA annotations to define your tables you need to specify the length of your BLOB attribute using the @Column annotation.
Here is what I have defined for the picture attribute used in jugevents application.

@Lob
@Basic(fetch = FetchType.LAZY)
@Column(length=1048576)
public byte[] getPicture() {
return picture;
}

In this way the type of the column corresponding to the picture attribute will be MEDIUMBLOB instead of BLOB and you won't get that exception

venerdì, dicembre 05, 2008

Auto injected spring beans

A colleague of mine asked me to solve a problem about using beans, configured using the spring container, in legacy code.
Basically he couldn't change the way those beans are created but he wanted to be able to inject their properties using a spring configuration file.
This is the way he wants to create an instance of the class BeanAutoInjecting.

BeanAutoInjecting bai = new BeanAutoInjecting();

The class BeanAutoInjecting has its attributes injected by spring container but we don't want to have any trace of Spring in the code that use this class.
A friend of mine, Lucio, proposed me to use the class AutowiredAnnotationBeanPostProcessor to sort out this problem.
Therefore we have to modify the constructor of the class BeanAutoInjecting in this way:

public BeanAutoInjecting()
{
ApplicationContext ctx = SpringLoader.getApplicationContext();
AutowiredAnnotationBeanPostProcessor aabpp = (AutowiredAnnotationBeanPostProcessor)ctx.getBean(
"org.springframework.context.annotation.
internalAutowiredAnnotationProcessor");
aabpp.processInjection(this);
}

The trick is to define a dummy constructor and to instruct the spring container to use it. Here the dummy constructor

public BeanAutoInjecting(int a)
{
System.out.println("I am the dummy constructor!");
}

Here the definition of the bean and the auto-wiring directive in the spring configuration file.

<!-- auto wiring directive -->
<context:component-scan base-package="spikes.springexamples"/>
---------------------------
<!-- bean definition with dummy constructor ->
<bean name="beanAutoInjecting" class="spikes.springexamples.BeanAutoInjecting">
<constructor-arg>15</constructor-arg>
</bean>

That's cool I would say, I am able to use a spring managed bean in my legacy code creating it out of the spring container!!!

sabato, novembre 08, 2008

I love jugevents

Just to say that I am really lucky to be one of the developers of jugevents, according to me the best ever web application I have worked on. I mean, nothing special over there but all is rational, logic, simple.
Just an example, in development I need to test the functionality add new jugger but I don't want to send emails every time I test it, because I have previously test that service. Well, I only need to mock the dependency to the mail sender bean in this way

<bean id="mailSender" class="it.jugpadova.mock.ParancoeMockMailSender"/>

And it's done. Honestly think for a while about one of the crap application you are working on in your job. Could you easily mock the dependencies as easily as we do in jugevents? Well I think the answer is no.
I should dedicate more time in development jugevents as it's good for my education and even for my mood.

domenica, ottobre 19, 2008

Flights web site

Finally I have found a nice web site to find international cheap flights, very easy to use and with really complete search results. Have a try at http://www.tickets-to-europe.com/

lunedì, ottobre 13, 2008

Ubuntu Window Grouping

The default window grouping setting in ubuntu results in opening a separate tab, in the bottom bar, for every application running.
i.e. if you are using skype and you are talking with 3 different users you will see three different tabs in the bar.
In order to change the window grouping settings follow this steps:

  1. Right click on the bottom bar, on the left (in the visible space);
  2. Preferences
  3. Check Always group windows

...Ah I was forgetting, thanks again to Lucio

venerdì, ottobre 10, 2008

Refreshing cache DNS in Windows

In Windows there is cache for DNS. In order to refresh the cache from command line and refer to the correct IP you need to execute this command:

$ ipconfig /flushdns

After that verify the correct IP of the website you want to connect using:

$ tracert <myWebSite>

Thanks to my colleague Roman.

lunedì, ottobre 06, 2008

Chain commands with maven

If you need to run two (or more) maven command in cascade you can chain these two commands in the following way:

$ mvn commandA commandB

Example:

$ mvn clean install

instead of:

$ mvn clean
$ mvn install

Thanks again to Lucio.

martedì, luglio 29, 2008

org.eclipse.core.runtime.AssertionFailedException in Eclipse RCP

If you are working on development (or bug fixing) of a eclipse-plugin application and you get this error:

org.eclipse.core.runtime.AssertionFailedException: assertion failed:

or any eclipse specific error, in order to find out the real exception thrown by your code proceed in this way:

  1. Right click on the error message;
  2. Open log

Thanks to Roman ;)

sabato, maggio 31, 2008

MySQL case sensitive in linux


MySQL table names are case-sensitive depending on the filesystem of the server. e.g. insensitive on Windows & Mac HFS+, Case sensitive on Unix.

It means that if you have stored the table PIPPO (upper case) in your database, the select query:
select * from pippo
doesn't work and it returns a message like ..."table pippo doesn't exist".
In order to prevent this problem you have to set set lower_case_table_names=1 in your /etc/mysql/my.cnf file. In this way the mysql server will store the table in the file system using lower case.
Here the steps I have followed:

  1. Chek the status of lower_case_table_names typing: $ mysqladmin -uroot -p variables
  2. $ sudo gedit /etc/mysql/my.cnf
  3. edit the file adding the entry lower_case_table_names=1 just under the group definition: [mysqld]

    [mysqld]
    #
    # * Basic Settings
    #

    #
    # * IMPORTANT
    # If you make changes to these settings and your system uses apparmor, you may
    # also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
    #

    lower_case_table_names=1

    user = mysql
    pid-file = /var/run/mysqld/mysqld.pid
    socket = /var/run/mysqld/mysqld.sock
    port = 3306
    basedir = /usr
    datadir = /var/lib/mysql
    tmpdir = /tmp
    language = /usr/share/mysql/english
    skip-external-locking

  4. shutdown the mysqlserver: $ mysqladmin -uroot -p shutdown
  5. start the mysqlserver: $ sudo mysqld &
  6. Chek the new status of lower_case_table_names typing: $ mysqladmin -uroot -p variables
  7. Remember that you have to re store the tables in the database, the best way to do that is dropping your database and running the SQL script.
  8. Test if works running a query like $ select * from pippo supposing you have stored PIPPO upper case

I ran this configuration with ubuntu 8.0.4, dell XPS1530, mysql 5-0
Enjoy with MySQL on linux.

dell XPS 1530 + ubuntu = fast

Here the log after executed mvn install on parancoe (trunk). Before I ran the command mvn clean, so the total time includes the compile step.
21 seconds not bad at all.

[INFO]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Parancoe .............................................. SUCCESS [2.784s]
[INFO] Parancoe Yaml ......................................... SUCCESS [5.407s]
[INFO] Parancoe Core ......................................... SUCCESS [9.599s]
[INFO] Parancoe Web .......................................... SUCCESS [2.964s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 21 seconds
[INFO] Finished at: Sat May 31 02:15:55 IST 2008
[INFO] Final Memory: 37M/132M
[INFO] ------------------------------------------------------------------------

install activation with maven

Problem

[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) javax.activation:activation:jar:1.1.1

Try downloading the file manually from the project website.



Link
activation


Command
mvn install:install-file -DgroupId=javax.activation -DartifactId=activation -Dversion=1.1.1 -Dpackaging=jar -Dfile=activation.jar

giovedì, maggio 29, 2008

Executing main class with maven

If you want to run the main class of your application, let say mypackage.Pluto from maven, just run this command:


$ mvn exec:java -Dexec.mainClass=mypackage.Pluto


That's great, easy, simple...that's the maven way. Thanks to Lucio.

giovedì, aprile 03, 2008

Installing cruisecontrol as service on windows XP


Here the steps I have followed in order to install and run cruisecontrol as a windows service.

  1. Download cruisecontrol. I used the version 2.6.2 windows installer.
  2. Run the installer and check the windows service box.
  3. Remove the service using the command: $ sc delete CruiseControl
  4. Go to <CRUISE_HOME> folder and edit the wrapper.conf file and be sure it contains the following entry:

    # Application parameters.
    # Add parameters as needed starting from 1
    wrapper.app.parameter.1=CruiseControlWithJetty
    wrapper.app.parameter.2=-jmxport
    wrapper.app.parameter.3=8000
    wrapper.app.parameter.4=-configfile
    wrapper.app.parameter.5=config.xml
    wrapper.app.parameter.6=-rmiport
    wrapper.app.parameter.7=1099
    wrapper.app.parameter.8=-webport
    wrapper.app.parameter.9=8180

  5. I set the listening port of cruisecontrol to 8180, you can change the value as you like.
  6. Open a dos windows corresponding to <CRUISE_HOME> folder and type: $ wrapper -i wrapper.conf
  7. You should read the message: "wrapper | CruiseControl Service installed."
  8. Try to open a browser at the url: http://localhost:8180
  9. If you see the normal screen of cruisecontrol you have been lucky (not like me) and you are done!.
  10. ...Otherwise...If you see an error like 500 code open the wrapper.log under the log folder. Check for a message like:
    Unable to find a javac compiler;
    com.sun.tools.javac.Main is not on the classpath.
    Perhaps JAVA_HOME does not point to the JDK.

    proceed with the following item.
  11. Copy the file tools.jar to <JAVA_HOME>\jre\lib\ext folder. I found this solution here.
  12. Restart the service, it should be works.
  13. If still doesn't work... copy the tools.jar also under the folder /lib/ext

Maybe there is a faster and easier process to have cruisecontrol running as service. Anyway if you follow this guide you will successfully configure cruise as service.

venerdì, marzo 28, 2008

Do not make complex simple things

I can't say much more, just I was wondering why do people tend to complicate all the things that could be easily developed, why do I need a bus to go to work if I am alone in the bus, why do I need an expansive computer if I have only to use excel, and why do I need to define another language if I can use well known languages to do the same. So why I have to spend 1000 eur for a watch when I could spend 50 to achieve the same result, that is checking the time. Keep things easy and you would be loved, common patterns, common words. Ask yourself what are you going to produce, what the costumer wants and try to realize it as simple as you can, there is no way to invent things if they are already available, and most of them for free. Look at jugevents, it's one of the best web application in the world, and it works, it's easy to understand, and it uses common frameworks. I like working on it, just would like having more time to dedicate on it.

lunedì, febbraio 25, 2008

The king and the poisoned wine

There is a king, 8 bottles of wine, one of them contains poison. Who drinks the wine with poison dies after 24 hours. The king wants to figure out what is the bottle with poison in only 24 hours. Some prisoners of the kingdom are available as test drunker. You should save as much life (of the prisoners) as you can. How many tester you have to use in order to figure out what is the bottle containing wine, in 24 hours?
I had this question during the interview for a role as software engineer. You can find the solution reading the comments of this post.

martedì, febbraio 19, 2008

spring mail configuration using gmail as smtp server

If you are going to use gmail as smtp server in your spring configuration file remember to add the property mail.smtp.starttls.enable and set it to true.
Here the configuration of mailSender used in jugevents .

<!-- start mail section -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- here your smtp server -->
<property name="host"><value>smtp.gmail.com</value></property>
<!-- Parameters for SMTP AUTH -->
<property name="username"><value>yourUsername</value></property>
<property name="password"><value>yourPassword</value></property>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<!-- used by gmail smtp server -->
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>

Fail doing it you will face into the following exception

org.springframework.mail.MailSendException; nested exception details (1) are: Failed message 1: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first z37sm13522675ikz.1 at

Thanks to Lucio for the help.

mercoledì, gennaio 09, 2008

migration maven based project to using spring 2.5

As the new version of spring labelled 2.5 has been released, I wanted update all the dependencies in the parancoe project to the new version of spring.
I didn't find the 2.5 version for the following spring modules:

  • spring-dao
  • spring-hibernate3

At the first I used the old version, 2.0.7, for these two modules but I had many test failures. I have found the explanation of the reason of these missing files here.
These two modules have been renominated in the following way:

  • spring-dao to spring-tx
  • spring-hibernate3 to spring-orm

Here the section in your pom.xml maven file with the updated version of these two modules:


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>2.5</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>2.5</version>
</dependency>

giovedì, gennaio 03, 2008

Deploy webapp on tomcat 6

Here, the steeps I have followed in order to deploy and starting my web application on tomcat 6.
I wanted deploy my webapp (hereafter I'll call it pippo), without moving the pippo.war on <tomcat-home>/webapps
Environment: Windows XP, JDK 1.6, tomcat 6.0

  • Create the folder <tomcat-home>/conf/Catalina/localhost (Note the capital letter C in Catalina)
  • Rename the contex.xml of your webapp as pippo.xml e copy it under the localhost folder just created.
  • Copy all the jdbc drivers that your webapp needs under the folder <tomcat-home>/lib
  • Exec $ catalina start from <tomcat-home>/bin
  • Open the browser and type http://localhost:8080/pippo

Here the context.xml of pippo webapp, renamed pippo.xml


<Context path="/pippo" reloadable="true"
docBase="C:/temp/pippo">
<Resource auth="Container"
driverClassName="org.hsqldb.jdbcDriver"
maxActive="5"
name="jdbc/pippoDS"
password=""
type="javax.sql.DataSource"
url="jdbc:hsqldb:hsql://localhost/pippo"
username="sa"/>
</Context>


Remember also to modify the tomcat-users.xml file in the <tomcat-home>/conf/ folder.
Here the file I use.

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager"/>
<role rolename="tomcat"/>
<role rolename="admin"/>
<user username="tomcat" password="tomcat" roles="manager,tomcat,admin"/>
</tomcat-users>


Deployment descriptor for the basicwebappevolution




<Context path="/basicWebAppEvolution" reloadable="true"
docBase="/dev/parancoe/parancoe/examples/basicWebAppEvolution/target/basicWebAppEvolution">
<Resource auth="Container"
driverClassName="org.postgresql.Driver"
maxActive="5"
name="jdbc/dataSource"
password="mypassword"
type="javax.sql.DataSource"
url="jdbc:postgresql://localhost:5432/basicwebappevolution"
username="postgres"/>
</Context>