Wednesday, November 21, 2012

JCS and Spring: Unable to validate using XSD...

Working on a servlet project that uses spring and I wanted to add caching using Apache JCS, but as soon as I added the maven dependency I started getting this exception:
12/11/22 09:20:44 INFO support.FileSystemXmlApplicationContext: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@15136019: startup date [Thu Nov 22 09:20:44 EST 2012]; root of context hierarchy
12/11/22 09:20:44 INFO xml.XmlBeanDefinitionReader: Loading XML bean definitions from file [bean.xml]
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Parser configuration exception parsing XML from file [bean.xml]; nested exception is javax.xml.parsers.ParserConfigurationException: Unable to validate using XSD: Your JAXP provider [org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@419829a9] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? Upgrade to Apache Xerces (or Java 1.5) for full XSD support.
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:404)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
 at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
 at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
 at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
 at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
 at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:522)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)
 at org.springframework.context.support.FileSystemXmlApplicationContext.(FileSystemXmlApplicationContext.java:140)
 at org.springframework.context.support.FileSystemXmlApplicationContext.(FileSystemXmlApplicationContext.java:84)
 at Tester.main(HBaseXmlStreamTester.java:87)
Caused by: javax.xml.parsers.ParserConfigurationException: Unable to validate using XSD: Your JAXP provider [org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@419829a9] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? Upgrade to Apache Xerces (or Java 1.5) for full XSD support.
 at org.springframework.beans.factory.xml.DefaultDocumentLoader.createDocumentBuilderFactory(DefaultDocumentLoader.java:102)
 at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:70)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
 ... 19 more
Caused by: java.lang.IllegalArgumentException: No attributes are implemented
 at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(DocumentBuilderFactoryImpl.java:98)
 at org.springframework.beans.factory.xml.DefaultDocumentLoader.createDocumentBuilderFactory(DefaultDocumentLoader.java:99)
 ... 21 more

The pom.xml dependencies:

        .
        .
        .
 
  
      jcs
      jcs
      1.3
  
  
      org.springframework
      spring-core
      3.1.1.RELEASE
  
  
      org.springframework
      spring-web
      ${spring.version}
  
  
      org.springframework
      spring-beans
      ${spring.version}
  
  
      org.springframework
      spring-context
      ${spring.version}
  
  
      org.springframework
      spring-aop
      ${spring.version}
  
  
      org.springframework
      spring-context-support
      ${spring.version}
  
  
      org.springframework
      spring-tx
      ${spring.version}
  
  
      org.springframework
      spring-orm
      ${spring.version}
  
  
      org.springframework
      spring-jdbc
      ${spring.version}
  
  
      org.springframework
      spring-test
      ${spring.version}
  
  
      org.springframework
      spring-webmvc
      ${spring.version}
  
  
      org.springframework
      spring-oxm
      ${spring.version}
  
  
      org.springframework
      spring-instrument
      ${spring.version}
  
 
        .
        .
        .
In the source for javax.xml.parsers.DocumentBuilderFactory.newInstance() it lets you specify the DocumentBuilderFactory implementation with a VM define, like this (using the implementation from the source):
        #> java -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl Tester
Now this work fine, but I don't want to have to set up a define in the servlet container so I kept looking. I replaced the JCS dependency:
        
            jcs
            jcs
            1.3
        
with:
        
            jcs
            jcs
            1.3
            
                
                    xerces
                    xerces
                
                
                    xml-apis
                    xml-apis
                
            
        
 
        
            xerces
            xercesImpl
            2.10.0
        
        
            xml-apis
            xml-apis
            1.4.01
        
And it now works without having to set a VM define.

Wednesday, April 4, 2012

Gentoo, Grub, and UUID

A guide I wrote so I can remember how to set up UUID booting on my Gentoo system running Grub. It is a simplified version of the Gentoo Initramfs guide. The following assumptions apply:

  • That initramfs is enabled in the kernel.
  • That all modules required to boot the system are compiled into the kernel.

Emerge a statically linked Busybox

$ echo sys-apps/busybox mdev static >> /etc/portage/package.use
$ emerge -a busybox

Create the ramfs image

$ echo sys-apps/busybox ipv6 pam mdev static >> /etc/portage/package.use
$ mkdir /usr/src/initramfs
$ cd /usr/src/initramfs
$ mkdir bin sbin proc sys mnt mnt/root
$ cp /bin/busybox bin/
fail_safe() {
        echo "Entering Shell"
        exec /bin/sh
}

find_and_mount_root() {
    for cmd in $(cat /proc/cmdline) ; do
        case $cmd in
        root=*)
            type=$(echo $cmd | cut -d= -f2)
            if [ $type == "LABEL" ] || [ $type == "UUID" ] ; then
                uuid=$(echo $cmd | cut -d= -f3)
                mount -o ro $(findfs "$type"="$uuid") /mnt/root
            else
                mount -o ro $(echo $cmd | cut -d= -f2) /mnt/root
            fi
            ;;
        esac
    done
}
#!/bin/busybox sh

. /bin/funcs

/bin/busybox --install -s

mount -t proc none /proc
mount -t sysfs none /sys

echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

find_and_mount_root || fail_safe

umount /proc
umount /sys


exec switch_root /mnt/root /sbin/init
#!/bin/bash

BOOT=/boot/
MY_NAME=`basename $0`

make_it() {

        find .  \( ! -iname $MY_NAME \) -print0 | cpio --null -ov --format=newc | gzip -9 > $BOOT/initramfs.cpio.gz
}


mount $BOOT
cd $(cd  $(dirname $0) ; pwd -P) && make_it
$ chmod +x init
$ chmod +x make_initramfs
$ ./make_initramfs

Grub

If you are using /dev/sda1 as your root file system, you can find its UUID
ls /dev/disk/by-uuid/ -la
total 0
drwxr-xr-x 2 root root 240 Apr  3 19:32 .
drwxr-xr-x 6 root root 120 Apr  2 04:00 ..
lrwxrwxrwx 1 root root  10 Apr  2 04:00 550e8400-e29b-41d4-a716-446655440000 -> ../../sda1
# This is a sample grub.conf for use with Genkernel, per the Gentoo handbook
# http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=1&chap=10#doc_chap2
# If you are not using Genkernel and you need help creating this file, you
# should consult the handbook. Alternatively, consult the grub.conf.sample that
# is included with the Grub documentation.

default 0
timeout 30
splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title Gentoo Linux kernel-3.2.1-gentoo-r2
root (hd0,0)
kernel /boot/kernel-3.2.1-gentoo-r2 root=UUID=550e8400-e29b-41d4-a716-446655440000
initrd /boot/initramfs.cpio.gz

Ok. All done. Reboot and enjoy!