Maven Jetty Plugin and double slashes in the url

English The maven jetty plugin is a handy plug-in that allows to run a maven based project that has a web-app inside simply by doing a “mvn jetty:run”, without the hassle of creating a WAR and deploy it to somewhere else.

It happens that the jetty web server, by default, does not handle URLs that contains double slashes “//”, that is, calling http://host/mycontext/media//img/a.gif is not the same as calling http://host/mycontext/media/img/a.gif, and brings a 404 error (as described in http://jira.codehaus.org/browse/JETTY-386)

To enable url compactation in the jetty through maven plug-in, and thus enabling the same behaviour as tomcat:

<plugins>
           ...
           <plugin>
                      <groupId>org.mortbay.jetty</groupId>
                      <artifactId>maven-jetty-plugin</artifactId>
                      <configuration>
                                <scanIntervalSeconds>10</scanIntervalSeconds>
                                <connectors>
                                       <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                                               <port>8080</port>
                                               <maxIdleTime>60000</maxIdleTime>
                                       </connector>
                                </connectors>
                                <webAppConfig>
                                       <contextPath>/mycontext</contextPath>
                                       <compactPath>true</compactPath>
                                </webAppConfig>
                    </configuration>
           </plugin>
           ...
</plugins>
Advertisements

Casifying Luntbuild

England I’ve been working a lot lately in devware which is a vmware virtual machine containing a lot of development tools already installed and integrated. The challenge now is to support Single Sign On, so that only one login is necessary to access all the tools and softwares inside (at least the ones that has a web interface).

It happens that devware is composed of heterogeneous 3rd party tools, and obviously each one uses a different kind of authentication and security schema.

That’s where comes to scene CAS (Central Authentication Service) a very neat solution for single sign on for the web.

Luntbuild, which is a great and full featured build automation server is the first software that was “Casified”. Luntbuild, fortunately, was created using Spring and Acegi, which in turn supports CAS integration. So, this is how I Casified luntbuild:

1. Install and make sure that CAS is working

Install CAS is as hard as drop a WAR inside your favourite web container. The not-so-obvious part are the SSL issues: you and everyone must access cas using a name, and not and IP, and SSL is obligatory. And you must have a certificate (can be self signed) that reflects this name. After that, make sure that you can login in CAS accessing https://<server>/cas/login.

2. Make sure luntbuild is installed and running

The version of luntbuild that I casified was 1.5.5. This process will not work on previous versions, such as 1.3.x ones. Make sure that luntbuild is installed and that it’s possible to do a login using it’s own security scheme.

3. Changing luntbuild’s web.xml

No change is needed! 🙂 luntbuild’s web.xml declares a filterToBean proxy that allows to make all filtering stuff inside spring’s application context.

4. Changing applicationContext.xml

This is where luntbuild’s spring appcontext lies.

Locate the bean “authenticationManager” and add to the list (as the first one) the CAS authentication provider:

<bean id="authenticationManager" class="com.luntsys.luntbuild.security.AuthenticationProviderManager">
                <property name="providers">
                        <list>
                                <ref local="casAuthenticationProvider" />

                                <!-- authentication provider which uses declarative security -->
                                <ref local="inMemoryAuthenticationProvider" />

                                <!-- authentication provider for remember me -->
                                <ref local="rememberMeAuthenticationProvider" />

                                <!-- authentication provider which validates users again internal db -->
                                <ref local="luntbuildAuthenticationProvider" />

                                <!-- authentication provider which validates users again Ldap -->
                                <ref local="ldapAuthenticationProvider" />
                        </list>
                </property>
        </bean>

Search and coment the bean id “exceptionTranslationFilter”:

<!--<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
             <property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
</bean> -->

Locate the bean “filterChainProxy” and change the URL matching rules to:

<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
     <property name="filterInvocationDefinitionSource">
        <value>
            PATTERN_TYPE_APACHE_ANT
            /*.do=httpSessionContextIntegrationFilter,casProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            /j_acegi_cas_security_check=httpSessionContextIntegrationFilter,casProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            /casProxy/receptor=httpSessionContextIntegrationFilter,casProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
       </value>
    </property>
</bean>

And then add the beans of the CASAuthenticationProvider:

<bean id="casAuthenticationProvider" class="org.acegisecurity.providers.cas.CasAuthenticationProvider">
               <property name="casAuthoritiesPopulator">
                        <ref bean="casAuthoritiesPopulator" />
                </property>
                <property name="casProxyDecider">
                        <ref bean="casProxyDecider" />
                </property>
                <property name="ticketValidator">
                        <ref bean="casProxyTicketValidator" />
                </property>
                <property name="statelessTicketCache">
                        <ref bean="statelessTicketCache" />
                </property>
                <property name="key">
                        <value>my_password_for_this_auth_provider_only</value>
                </property>
</bean>

<bean id="casProxyDecider" class="org.acegisecurity.providers.cas.proxy.RejectProxyTickets" />

<bean id="statelessTicketCache" class="org.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">
                <property name="cache">
                        <ref local="ticketCacheBackend" />
                </property>
</bean>

<bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
                <property name="cacheManager">
                        <ref local="cacheManager" />
                </property>
                <property name="cacheName">
                        <value>ticketCache</value>
                </property>
</bean>
   <bean id="casProxyTicketValidator" class="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator">
                <property name="casValidate">
                        <value>https://devware/cas/proxyValidate</value>
                </property>
                <property name="proxyCallbackUrl">
                        <value>https://devware/luntbuild/casProxy/receptor</value>
                </property>
                <property name="serviceProperties">
                        <ref bean="serviceProperties" />
                </property>
</bean>

<bean id="casAuthoritiesPopulator" class="com.luntsys.luntbuild.security.LuntbuildCasAuthoritiesPopulator">
                <property name="authenticationDao">
                        <ref bean="luntbuildAuthenticationDAO" />
                </property>
</bean>

<bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties">
                <property name="service">
                        <value>https://devware/luntbuild/j_acegi_cas_security_check</value>
                </property>
                <property name="sendRenew">
                        <value>false</value>
                </property>
</bean>

<bean id="casProcessingFilter" class="org.acegisecurity.ui.cas.CasProcessingFilter">
                <property name="authenticationManager">
                        <ref bean="authenticationManager" />
                </property>
                <property name="authenticationFailureUrl">
                        <value>/casfailed.jsp</value>
                </property>
                <property name="defaultTargetUrl">
                        <value>/</value>
                </property>
                <property name="filterProcessesUrl">
                        <value>/j_acegi_cas_security_check</value>
                </property>
</bean>

<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
                <property name="authenticationEntryPoint">
                        <ref local="casProcessingFilterEntryPoint" />
                </property>
</bean>

<bean id="casProcessingFilterEntryPoint" class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
                <property name="loginUrl">
                        <value>https://devware/cas/login</value>
                </property>
                <property name="serviceProperties">
                        <ref bean="serviceProperties" />
                </property>
</bean>

Replace “https://devware&#8221; with your cas host.

The final piece of the puzzle is the casAuthoritiesPopulator declared above. This is necessary to populate the luntbuild user’s credentials accordingly after the user has logged on, and to create the user in the luntbuild database it does not exist already, similar to what happens when integration luntbuild with LDAP. I’ve submitted a patch to luntbuild’s tracker with this class

5. Final remarks

After this procedure, if one logins into cas, and after that enters luntbuild, a second login will not be necessary. If someone tries to enter luntbuild directly, it’ll redirect to CAS login page. And the same happens with every other applications that is “Casified”. Without changing the source code of luntbuild at all (just changing XML and adding one more class), it was possible to change a major application behavior, and that’s the beauty of spring based projects. They are so decoupled that nearly every aspect of an application instantly becomes an extension point!

And the use of CAS allows to have SSO and not depend on things like proprietary realms, intrusive server configurations, and obscure plugins that are target to a certain version of a certain application server maker. CAS is very portable, the only requisite is an application container that support servlets.


Gentoo Linux: how to backup to ipod and restore to vmware

England In this post I’ll show how to backup bit-by-bit an existing gentoo linux installation to an iPod classic via USB, and how to restore the image to a vmware virtual machine. Why all that? Because iPod classic can be used as a portable hard disk with 160 Gb… And what better way there is to test a backup than actually run it as if it were the real machine ? 😉

What you’ll need:

  • an Ipod classic 160 Gb, with enough free space
  • a burned ISO of Ghost for Linux (g4l)
  • a burned ISO of Gentoo Live CD
  • a running vmware server on another machine.

Prepare the kernel for vmware

Since the existing physical gentoo installation will run on vmware after the backup, it doesn’t hurt to enable in the kernel support for the “hardware” it’ll encounter. These are the features that must be enabled on the kernel to support vmware server 1.0.x:

Support for vmware NIC:

Device Drivers --->

     [*] Network device support  --->
        [*]  Ethernet (10 or 100Mbit)  --->
                 [*]   EISA, VLB, PCI and on board controllers
                 <*>     AMD PCnet32 PCI support

Support for vmware SCSI:

Device Drivers --->
         SCSI device support  --->
               <*> SCSI disk support
                [*] SCSI low-level drivers  --->
                      <*>   BusLogic SCSI support

Doing the backup

1. Connect the ipod via USB and boot the gentoo machine with the g4l CD. In the kernel list, choose the latest RELEASED one.

2. After booting, the ipod should be detected as a general USB storage device. In my machine it is seen as /dev/sdb1. To be sure, a simple mount will suffice to discover:

mount /dev/sdb1  /mnt/local

3. Type ‘g4l’ to enter the ‘graphical interface’. In the main menu, choose “RAW Mode”

4. Then choose “Local use”

5. In the local use screen, configure the following values:
A: Pick the drive: choose the ipod device, or (X) sdb1
B: Config filename: I’ve chosen vaio_bkp.img
C: Toogle split: (X) On. This is very important. Ipod is formatted as FAT32 under windows, and does not support files larger than 4Gb
D: Toogle compression: I’ve chosen (X) None, since I have plenty of free space in my ipod and thus the process can be faster and less cpu intensive
E: Backup: choose the partition on the machine to be backed up, (X) sda4, for example.

After that, G4l will show all the choices made before starting the process:

g4l2.jpg

6. Several 1Gb files will be created in the ipod root folder. The backup speed was about 18 Mb/s in my environment, so, to backup 80Gb it took aprox. 70 min.

Creating the vm

1. In another machine that has vmware server instaled, create a new virtual machine (File -> New -> Virtual Machine), choose “custom” -> “Linux” -> “Other Linux 2.6.x kernel”, and when prompted for “I/O Adpater type” choose “BusLogic”. When prompted for “Disk type”, choose “SCSI”. In the “Disk capacity” choose the same size of the partition in the original machine. Keep “allocate disk now” unchecked, to save space. In the vmware server console, add to the virtual machine a USB Controller (menu VM -> Settings) and then “Add -> USB Controller”
2. Boot the virtual machine with g4l live CD, with the ipod plugged in. Run “fdisk” and make sure that the partition layout is the same of the original gentoo, that is, if the partition was called /dev/sda4 in the source machine, create in the virtual machine the same partition name. Don’t forget to toggle the bootable flag in this partition.
3. The vm should see the ipod in the USB. If not go to menu VM -> Removable Devices -> USB Devices and mark “Apple Computer USB Device”.

Restoring the backup

1. In ghost for linux, go to the menus:
RAW Mode -> Local Use
2. Choose the options:
A: sdb1 (or where the ipod was mounted)
B: the same name used to backup
C: Toogle split (On)
D: Toogle compression (None) if compression was not used
F: Restore: choose the partition created in vmware, matching the original partition name. G4l will show a resume before restoring:

restore.jpg

The restore will take longer than the backup, since vmware server 1.0.x still does not support high speed USB (the support is coming in vmware server 2, still in beta stage). In my environment, I could get a 2.4 Mb/s speed.

Fixing the bootloader

Now that you have a clone of the physical machine under vmware, chances are that it still not bootable. This may occurs if the partition backed-up was not where the bootloader was installed. In my case, the backup was made from /dev/sda4, and the bootloader was installed in /dev/sda alongside with windows, to enable dual boot. To fix this, boot the virtual machine with gentoo install CD, and install grub again:

# mount the partition
mount /dev/sda4 /mnt/gentoo
# Remount /dev/ inside the partition
mount -o bind /dev/ /mnt/gentoo/dev

# Chroot into the partition
chroot /mnt/gentoo /bin/bash

# mount proc
mount -t proc proc /proc

# Populate /etc/mtab, so that grub-install does not get angry
cat /proc/mount >> /etc/mtab

# Install grub on the disk
grub-install /dev/sda

Now the virtual machine is bootable!

Fixing X and network

After booting, eth0 is not available, thanks to udev. As the MAC Address of the NIC changed, udev allocates eth1 and wipes eth0. To fix this, simply:

rm  /etc/udev/rules.d/70-persistent.net.rules

and reboot the system.

To fix the X server, run the command ‘xorgconfig’. Choose the following options:

Mouse Protocol:  1
Emulate3Buttons: Y
Mouse device: /dev/input/mouse0
card  database:  choose 30 (vmware)

And that’s all! Now we have a perfect running clone of the physical machine, with network and X support, in a relative easy manner.

vmware

Gentoo and Sony Vaio VGN-FZ180E – part 5: Storage

England In this post I’ll deal with this vaio’s hard disk, dvd-rom, 5-in-1 Card reader. The kernel is 2.6.24-r3 (latest official stable)

Hard Disk

lspci show the SATA controller that this model uses:

00:1f.2 SATA controller: Intel Corporation Mobile SATA AHCI Controller (rev 03)

To enable in the kernel:

Device Drivers --->
  <*> Serial ATA (prod) and Parallel ATA (experimental) drivers  --->
     <*>   AHCI SATA support

CD/DVD-ROM Drive

Device Drivers --->
   <*> ATA/ATAPI/MFM/RLL support  --->
           <*>   Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
           <*>     Include IDE/ATAPI CDROM support
            [*]     IDE ACPI support
           <*>     generic/default IDE chipset support
           <*>     Generic PCI IDE Chipset Support

After booting, look in dmesg:

Probing IDE interface ide0...
hda: MATSHITABD-MLT UJ-220V, ATAPI CD/DVD-ROM drive
Probing IDE interface ide1...
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
hda: ATAPI 47X DVD-ROM DVD-R-RAM CD-R/RW drive, 8192kB Cache

Multimedia Card Reader (MMC)

lspci shows:

09:03.2 Mass storage controller: Texas Instruments 5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD)

kernel flags:

Device Drivers
     --- MMC/SD card support
      <*>   MMC block device driver
       [*]     Use bounce buffer for simple hosts
      <*>   SDIO UART/GPS class support
        <*>   Secure Digital Host Controller Interface support  (EXPERIMENTAL)
        <*>     Ricoh MMC Controller Disabler  (EXPERIMENTAL)
        <*>   Winbond W83L51xD SD/MMC Card Interface support
        <*>   TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)

See how maven works inside – remote debugging plugins

England Who uses maven as I do for a long time, knows that sometimes things does not go as expected. So it’s necessary to look at the ultimate documentation: the source code! In this post I’ll show how to debug a maven plugin using Eclipse’s remote debugger. I’ve chosen for this example the maven-clean-plugin.

Ok, let’s start. First create a simple sample project:

    mvn archetype:create -DgroupId=com.wordpress -DartifactId=maven-debug

In the folder maven-debug, edit the pom.xml and add the dependency of the plugin. This will serve as an “anchor” to bring all the sources needed to debug.

<dependency> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-clean-plugin</artifactId> 
       <version>2.1.1</version> 
       <scope>provided</scope> 
</dependency>

Note the scope “provided”, meaning that the dependency will be given to the project by someone and it should not make to the final package. It shouldn’t matter, anyway, since this is a dependency that will be removed later, it’s just for debug purposes.

It’s important to know what version of the plugin your project is using. When in doubt, run “mvn -X clean” and note lines like:

  [DEBUG] Retrieving parent-POM: org.apache.maven.plugins:maven-plugins::3 for project: 
           null:maven-clean-plugin:maven-plugin:2.1.1 from the repository.

Now generate the project in eclipse:

   mvn -Declipse.downloadSources=true eclipse:eclipse

Open eclipse, go to File -> Import -> Existing Projects into Workspace and select the root directory of the project. After that go to menu
“Run –> Open debug dialog” and under “Remote java application” create a new profile to debug our project:
debug.jpg

Using the eclipse search facilities, search for a class which name ends with “Mojo” (Maven Old Java Object) and place a breakpoint in the “execute” method. In the case of the clean plugin, this class is called CleanMojo

To debug, first enable debug on maven in the command line (linux shown here)

MAVEN_OPTS="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"; 
export MAVEN_OPTS

and then do a “mvn clean”; the process will halt. Start the debugger in eclipse, it will hit the breakpoint.

breakpoint.jpg

Congratulations! Now you can know exactly what’s going on!

Watching live soccer in Gentoo – part 1 – SopCast

England The portal myp2p.eu is a very interesting site where you can choose among several live sports and watching ’em live, with very good quality. The matches can be seen with a myriad of softwares, among them: windows media, real audio, sopcast, tvants. In this post I’ll focus on SopCast.

Gentoo portage does not have an ebuild for sopcast (yet), but meanwhile there is a sopcast ebuild on gentoo bugzilla. To install it, download the file http://bugs.gentoo.org/attachment.cgi?id=137461 and save it to /usr/portage/media-tv/sopcast-1.1.1.ebuild.

Edit sopcast-1.1.1.ebuild and change the URL from

   SRC_URI="http://download.sopcast.com/download/${MY_P}.tgz"

to

   SRC_URI="http://download.sopcast.cn/download/${MY_P}.tgz"

As the packages are masked, first we have unmask them:

    echo "=media-tv/sopcast-1.1.1" >> /etc/portage/package.keywords

Before emerging, go to the ebuild dir and generate the manifest:

    ebuild  sopcast-1.1.1.ebuild digest

and finally

    emerge sopcast

Now the fun bergins!

Under myp2p.eu/competition.php?competitionid=∂=sports&discipline=football choose the match you want to see, copy the adress (that beggins with the “protocol” sop://) and run the command:

   sp-sc sop://broker1.sopcast.com:3912/6001 1234 5678

that opens the stream from local port “1234” to player port “5678”. Player port is where you will watch the video. So, to watch with Xine (my favorite), run:

   xine http://localhost:5678

and that’s it! Nice game! 🙂

SoapCast

Gentoo and Sony Vaio VGN-FZ180E – part 4: Wireless

England The latest kernel 2.6.24-r3 support the Intel Pro Wireless 4965, so it’s not needed to manually built 3rd part modules. Mark the following kernel opts:

Networking --->  Wireless --->
 -*- Improved wireless configuration API
[*]   nl80211 new netlink interface support
-*- Wireless extensions
<*> Generic IEEE 802.11 Networking Stack (mac80211)
[ ]   Enable debugging output
< > Generic IEEE 802.11 Networking Stack

and

Device Drivers ---> [*] Network device support ---> Wireless LAN ---> [*] Wireless LAN (IEEE 802.11)
[*]   Intel Wireless WiFi Link Drivers
[*]     Enable full debugging output in iwlwifi drivers
[*]     Enable Sensitivity Calibration in iwlwifi drivers
[*]     Enable Spectrum Measurement in iwlwifi drivers
[*]     Enable Wireless QoS in iwlwifi drivers
<M>     Intel Wireless WiFi 4965AGN

After reboot, “modprobe iwl4965” and “modules-update”Emerge the packages “wpa_supplicant” and “wireless-tools”.
The wireless network can be discovery by using the command “iwlist wlan0 scan”. To connect to a network, declare it inside/etc/wpa_supplicant/wpa_supplicant.conf. Examples of networks declaration, with and without WEP:

network={
        ssid="home_network"
        key_mgmt=NONE
        wep_key0=fffffffffffffffffffff01111
        wep_tx_keyidx=0
} network={
        ssid="Delle_Province Hotel"
        key_mgmt=NONE
}

To activate wpa_supplicant as the “wireless connections manager”, the file /etc/conf.d/net must contain:

# Use dhcp for the wireless interface
config_wlan0=("dhcp")

# Declare wpa_supplicant module
modules=( "wpa_supplicant" )

# Wpa supplicant command line.
# wext referes to the wireless interface
# -dd enables verbose logging
# -c points to the configuration file
wpa_supplicant_wlan0="-Dwext -iwlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -dd"

Ok, now we have support in the kernel, support in the net scripts. To start/stop wireless network, it’s enough to do a

/etc/init.d/net.wlan0 start

which is a symbolic link to net.lo.