Total Pageviews

Monday, December 09, 2013

Useful Subversion pre-commit hook script for Linux servers

Looking for useful subversion pre-commit hooks? Maybe this script is for you. It's a Linux bash shell script and makes also use of python.
The script does the following:

  1. Checks whether the commit message is not empty
  2. Checks whether the commit message consists of at least 5 characters
  3. Checks if the committed files are UTF-8 compliant
  4. Checks whether the svn:eol-style property is set to LF on newly added files
  5. Checks if the committed files have no TAB characters

The UTF-8 and TAB checks are performed on the following file suffixes
  • *.java
  • *.js
  • *.xhtml
  • *.css
  • *.xml
  • *.properties (only check for TABs here, no check for UTF-8 compliance)
It should be easy to adjust those settings to your needs.

 #!/bin/bash  
   
 REPOS="$1"  
 TXN="$2"  
   
   
 # Make sure that the log message contains some text.  
 SVNLOOK=/usr/bin/svnlook  
 ICONV=/usr/bin/iconv  
   
 SVNLOOKOK=1  
 $SVNLOOK log -t "$TXN" "$REPOS" | \  
 grep "[a-zA-Z0-9]" > /dev/null || SVNLOOKOK=0  
 if [ $SVNLOOKOK = 0 ]; then  
  echo "Empty log messages are not allowed. Please provide a proper log message." >&2  
  exit 1  
 fi  
   
 # Comments should have more than 5 characters  
 LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS" | grep [a-zA-Z0-9] | wc -c)  
   
 if [ "$LOGMSG" -lt 6 ]; then  
  echo -e "Please provide a meaningful comment when committing changes." 1>&2  
  exit 1  
 fi  
   
 # Make sure that all files to be committed are encoded in UTF-8.  
 while read changeline;   
 do  
   
   # Get just the file (not the add / update / etc. status).  
   file=${changeline:4}  
   
   # Only check source files.  
   if [[ $file == *.java || $file == *.xhtml || $file == *.css || $file == *.xml || $file == *.js ]] ; then  
     $SVNLOOK cat -t "$TXN" "$REPOS" "$file" | $ICONV -f UTF-8 -t UTF-8 -o /dev/null  
     if [ "${PIPESTATUS[1]}" != 0 ] ; then  
       echo "Only UTF-8 files can be committed ("$file")" 1>&2  
       exit 1  
     fi  
   fi  
 done < <($SVNLOOK changed -t "$TXN" "$REPOS")  
   
 # Check files for svn:eol-style property  
 # Exit on all errors.  
 set -e  
 EOL_STYLE="LF"  
 echo "`$SVNLOOK changed -t "$TXN" "$REPOS"`" | while read REPOS_PATH  
 do  
  if [[ $REPOS_PATH =~ A[[:blank:]]{3}(.*)\.(java|css|properties|xhtml|xml|js) ]]  
  then  
   if [ ${#BASH_REMATCH[*]} -ge 2 ]  
     then  
   FILENAME=${BASH_REMATCH[1]}.${BASH_REMATCH[2]};  
   
   # Make sure every file has the right svn:eol-style property set  
    if [ $EOL_STYLE != "`$SVNLOOK propget -t \"$TXN\" \"$REPOS\" svn:eol-style \"$FILENAME\" 2> /dev/null`" ]  
     then  
     ERROR=1;  
       echo "svn ps svn:eol-style $EOL_STYLE \"$FILENAME\"" >&2  
    fi  
   fi  
  fi  
  test -z $ERROR || (echo "Please execute above commands to correct svn property settings. EOL Style LF must be used!" >& 2; exit 1)  
 done  
   
   
   
 # Block commits with tabs  
 # This is coded in python  
 # Exit on all errors  
 set -e  
   
 $SVNLOOK diff -t "$TXN" "$REPOS" | python /dev/fd/3 3<<'EOF'  
 import sys  
 ignore = True  
 SUFFIXES = [ ".java", ".css", ".xhtml", ".js", ".xml", ".properties" ]  
 filename = None  
   
 for ln in sys.stdin:  
   
     if ignore and ln.startswith("+++ "):  
         filename = ln[4:ln.find("\t")].strip()  
         ignore = not reduce(lambda x, y: x or y, map(lambda x: filename.endswith(x), SUFFIXES))  
   
     elif not ignore:  
         if ln.startswith("+"):  
           
            if ln.count("\t") > 0:  
               sys.stderr.write("\n*** Transaction blocked, %s contains tab character:\n\n%s" % (filename, ln))  
               sys.exit(1)  
   
         if not (ln.startswith("@") or \  
            ln.startswith("-") or \  
            ln.startswith("+") or \  
            ln.startswith(" ")):  
   
            ignore = True  
   
 sys.exit(0)  
 EOF  
   
 # All checks passed, so allow the commit.  
 exit 0  
   

Friday, November 08, 2013

Hit Ctrl+F9 in Intellij IDEA when JRebel does not work as expected

Often the solution for a problem is so damn easy when you know the cause of the problem ...
Intellij IDEA doesn't have an autocompile feature similar to Eclipse. So if you want your new code to be generated as a class file you have to hit Ctrl+F9 manually.
Well, the same is true when using JRebel. This great piece of software can only detect a change in a class file if the changed class file is generated by a compiler first.
So in case you are using IDEA in conjunction with JRebel and you wonder, why the heck this new code isn't replaced by JRebel on the fly you must hit Ctrl+F9 to generate a new class version and to trigger JRebel afterwards.

One other thing to keep in mind when working with WAR or EAR artifacts in IDEA is to deploy those artifacts as exploded ones!


Monday, October 07, 2013

Installing Android 4.3 OTA Update on rooted Nexus 7

Ok, the 4.3 OTA update is out now for a few months, but I didn't find the time to do the update on my rooted Nexus 7 device.
Another reason for the delay was the fact, that the Nexus 7 Toolkit wasn't released until a few weeks ago. My Nexus 7 already showed me the information that a new update was downloaded and ready to install.
Well, finally I decided to do the install (making a full Nandroid backup prior to the update), but when hitting the button "Reboot and Install" nothing happened.
Usually after waiting 10 seconds the device should reboot and install the update, but the reboot did not occur. My battery wasn't the problem, because it was almost fully charged.
First thing coming to my mind was to flash back the stock recovery. Unfortunately that didn't solve the problem.
The next thing I did was do hit the button "Delete data" of the app "Google Service Framework". This usually forces the system to reset the update state and check for newly available system updates.
And this did the trick. Clicking on "System Updates" the device told me that it was uptodate with a last check date of January 1st, 1970. So I manually hit the button to check for new updates and my device started to download a fresh copy of the 4.3 stock rom.
Now hitting the button "Reboot and Install" rebooted the device and installed the Android 4.3 update.

Wednesday, September 11, 2013

Pitfalls installing wordpress on a Linux box using Multisite with sub directories

This post is not about installing wordpress on a Linux box. It just covers two problems I have faced when installing wordpress 3.6 on my Ubuntu 12.04 box at home.
I did install wordpress using the distributed zip archive following the detailed instructions on the wordpress site. Setting up the database and editing the PHP config files was no problem.
The installation went smooth and everything was working as expected.

Problem 1: Configuring Multisite

Multisite is a great feature of wordpress. It gives you the ability to create more than one site (or blog) within your wordpress installation.
I did the setup using this step-by-step guide. So far so good. With my new multisite feature enabled I wanted to create a new site and filled in the necessary informations for it. The creation succeeded without an error and when I clicked on the dashboard of the newly created site I got a "Page Not Found" error.
Hm ... googling around I didn't really find a good answer.
I decided to check the network administration guide of the wordpress documentation and found a really helpful paragraph about using mod_rewrite (multisite feature needs mod_rewrite) and Apache Virtual Hosts.
My Apache installation is using virtual hosts so what finally did the trick was to add these lines to my VirtualHost section:


 <VirtualHost *:80>    
  <Directory /var/www/vhosts/wordpress>  
   AllowOverride Fileinfo Options  
  </Directory>  

Problem 2: Changing the domain name (or change the URL)

I am using DynDNS and I (and my users) want to access the wordpress installation from the internet. During the installation I did not realize that this was so important, because I thought I can change it easily afterwards. Well, changing it in a Non-Multisite environment is easy, but it turns out that a change of the domain name in a multisite installation is a little bit harder.
What helped me a lot was this documentation on the wordpress site.
Because my installation was totally fresh I skipped the step to make a backup of my database. I walked through all tables of the database and replaced every occurrence of my old domain name with the new DynDNS domain name.
Finally I changed the DOMAIN_CURRENT_SITE attribute in the wp-config.php file to point to the DynDNS name as well and after that my multisite wordpress installation was accessible via the DynDNS url.

I can't say whether it would have been easier to change the domain name before I activated the multisite feature, but it would make sense to me.

Anyway, it works now.

Thursday, July 04, 2013

Referencing a Derby database column with a reserved name using DBUnit

DBUnit is a pretty good tool to achieve reproducible results when unit testing your code. It puts your database in a known state before each test run.
In my case I use JPA with Hibernate as implementation to create the DB schema before each test run. Furthermore I use an embedded in-memory Derby database.

I ran into problems when inserting dbunit datasets into the created schema. A column was named interval which is a reserved word in Derby.

No problem I thought, when escaping the column name (using ' or " ticks) the problem would be solved. Well it turns out to be not that simple :-(

The solution is to set a DBUnit related property/feature to tell DBUnit how to config and use the underlying database. Here is the relevant code snippet

   IDatabaseConnection memDbConnection = new DatabaseDataSourceConnection(  
       (InitialContext) context, DEFAULT_DATASOURCE);  
   DatabaseConfig dbConfig = memDbConnection.getConfig();  
   dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new DefaultDataTypeFactory());  
   dbConfig.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, "\"?\"");  


The line
dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new DefaultDataTypeFactory());

tells DBUnit to use the default data type factory which works well with Derby. You don't have to set this property explicitly when using Derby.

The second line
dbConfig.setProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN, "\"?\"");  

solved my issue. You have to explicitly declare an escape pattern. In my case this was "\"?"".
With default settings DBUnit uses no escape pattern.

Using this solution, a clean insert into the database with a column that uses a reserved name works as expected.

Wednesday, June 26, 2013

Howto create a DB field with a reserved name using Hibernate and JPA

I stumbled upon this problem when I switched from a SQLServer 2008 database to a MySQL database 5.5 using Hibernate in Version 3.6.6 with JPA implementation 2.0.

The goal

Generating a MySQL database schema or updating a database schema automatically using Hibernate's hbm2ddl.auto feature.

The problem

Using SQLServer for a long time everything worked fine. When switching to MySQL the schema generation failed. In particular, one single table was not created and I couldn't find a hint in Hibernate's log statements.

The solution

My persistence.xml file uses the auto update of a database schema using this property

      <property name="hibernate.hbm2ddl.auto" value="update" />

So far so good. Nothing special here.
I changed the Hibernate dialect to use the MySQL dialect (org.hibernate.dialect.MySQLDialect) and when deploying the application it generates the database schema and it should populate the database with default values. When populating starts it immediately fails with the following Hibernate error message:

"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'interval) values (0, '10', 9, 4, 7, 1)' at line 1"

After a few minutes it came to my mind that the column name "interval" might be a keyword in MySQL. So googling around I found out that I was right. "interval" is a keyword in MySQL (but not in SQLServer).

Ok, reason found. But what is the best way to fix this issue?
Stackoverflow is your friend :-)
Just read this answer from Stackoverflow and you are done.

To summarize shortly:
With Hibernate as JPA 1.0 provider you have to annotate the entity field with enclosing backticks like this:

@Column(name="`interval`")
 
and when using JPA 2.0 the syntax was standardized you have to escape the column name like this

@Column(name="\"interval\"")

This is mentioned in chapter 2.13 (Naming of database objects) of the JPA 2.0 specification:

"It is possible to specify on a per-name basis that a name for a database object is to be inter-
preted as a delimited identifier as follows:
• Using annotations, a name is specified as a delimited identifier by enclosing the name
within double quotes, whereby the inner quotes are escaped, e.g.,
@Table(name="\"customer\"").
• When using XML, a name is specified as a delimited identifier by use of double
quotes, e.g.,
<table name="&quot;customer&quot;"/>"


Using the first (but deprecated) solution you can force Hibernate to quote an identifier in the generated SQL by enclosing the table or column name in backticks in the mapping document. Hibernate will use the correct quotation style for the SQL Dialect. This is usually double quotes, but the SQL Server uses brackets and MySQL uses backticks.

The second solution is the modern and standardized way of forcing your JPA 2.0 and above provider to quote the identifier.

Sunday, June 23, 2013

Lösung für "mit Windows Update kann derzeit nicht nach Updates gesucht werden"

Wer unter einem Windows 7 (64 Bit) die Funktion "Nach Updates suchen" ausführt und obige Fehlermeldung bekommt fängt erstmal an zu googeln.
Das Problem sollte eigentlich relativ einfach zu beheben sein - dachte ich.
Nun, es gibt diverse Antworten zu dem Problem:
Der letzte Eintrag erwähnt auch das Werkzeug winUpdRestore!v28.exe, welches allerdings mit einem Link in SkyDrive ins Leere läuft.
Die FixIt Lösung von Microsoft hat bei mir nicht funktioniert. Viele Blogeinträge erwähnten jedoch die erfolgreiche Behebung des Problems beim Einsatz des Tools winUpdRestore!v28.exe.

Leider ist dieses Tool so gut wie gar nicht im Web aufzutreiben. Ich habe es dann doch auf dieser Webseite gefunden.

Da ich hoffe, dass dieser Blogartikel auch schnell im Google Index auftaucht, gebe ich hier zwei funktionierende Links für diese Datei an:

  1. https://www.dropbox.com/s/n40u1jzphk3bsgs/winUpdRestore!v28.zip
  2. https://dl.dropboxusercontent.com/u/27481342/winUpdRestore!v28.zip
Das Tool ist kein offizielles Microsoft Produkt und Microsoft wird seine Gründe haben, warum das Werkzeug nicht mehr zu bekommen ist. Bei mir hat das Tool aber das Problem behoben.

Wednesday, May 22, 2013

Essential resources when building Android Apps using Maven (and Eclipse)

If you plan to build your Android application on a build server like Jenkins, Hudson, etc ... you should switch from building your project with your IDE (in my case Eclipse) to a build system like Maven or Gradle.

I tried Gradle (using the new Gradle Build export in Eclipse ADT plugin) because the new Android Studio preview release by Google supports Gradle builds, but was totally disappointed by the poor performance of Gradle on my Jenkins CI build server. So I decided to use maven instead and found out about these resources which you have to read and understand:

  1. Maven Android Plugin:
    You need the plugin to build android projects using maven. With Android API 17 the latest stable release 3.5.3 doesn't work. You have to pull the plugin's source from GitHub and build version 3.5.4-SNAPSHOT by yourself.
  2. Android SDK Deployer:
    "Typically artifacts are available in Maven Central, however only the platform versions available in the Android Open Source Project are published to Maven Central. Newer versions of the platform as well as the compatibility package and proprietary extensions like the Google Maps support are not available there and need to be published to your Maven repository, if you want to use them in your Android project.
    The artifacts published to Maven central are available as dependencies under the groupId com.google.android with the artifactId android and android-test.
    The Maven Android SDK Deployer has been created to publish artifacts from the Android SDK into your local repository or repository server when using components that are not available in Central."


    I have taken this from the online book Maven - The Complete Reference by Sonatype.
    With Android API 17 you might run into the same bug like described above. So before building this project you must build version 3.5.4-SNAPSHOT of the Maven Android Plugin
  3. m2e-android:
    In case you use Eclipse, you can use this m2e plugin to add maven support to your Eclipse Android project.

Monday, May 20, 2013

Install Android Tools on Ubuntu 12.04.

Check this blog when you have to install Android SDK on Ubuntu 12.04. It simply works!

Thursday, April 18, 2013

VirtualBox - Let Host-Only mode access the internet

In an earlier post I described networking modes in VirtualBox. Combining those modes you'll get some kind of swiss knife in realizing somehow exotic networking modes in your VMs.
What if you want your VM that is configured for Host-Only mode access the internet?
Port forwarding using NAT is an option. But for me that sounded to complicated. I had the following requirements:
  1. The host should be able to access services like Apache or GlassFish on the guests (the virtual machine)
  2. The guests should be able to access the outside world (intranet/internet)
  3. The guests should be able to talk to each other using fixed IP adresses
  4. The host should be able to talk to the guests using fixed IP adresses
A working solution for these requirements is described in this blog article.