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!

Wednesday, October 5, 2011

There's no ObjectFactory with an @XmlElementDecl

So I was trying to use the OGC Schemas compiled with JAXB. I compiled them all and decided to test them with this class:
import net.opengis.sos.v_1_0_0.InsertObservation;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class JAXBTest {
    public static void main(String[] args) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(InsertObservation.class);
        InsertObservation insert = new InsertObservation();
        Marshaller mar = context.createMarshaller();
        mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        mar.marshal(insert, System.out);

    }
}

However it throws this unenlightening (for me at least) error:


There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/sensorML/1.0.1}_Process.
 this problem is related to the following location:
  at protected java.util.List net.opengis.om.v_1_0_0.ProcessPropertyType.content
  at net.opengis.om.v_1_0_0.ProcessPropertyType
  at public net.opengis.om.v_1_0_0.ProcessPropertyType net.opengis.om.v_1_0_0.ObjectFactory.createProcessPropertyType()
  at net.opengis.om.v_1_0_0.ObjectFactory
  at protected java.lang.Object net.opengis.om.v_1_0_0.AnyOrReferenceType.any
  at net.opengis.om.v_1_0_0.AnyOrReferenceType
  at protected net.opengis.om.v_1_0_0.AnyOrReferenceType net.opengis.om.v_1_0_0.ObservationType.metadata
  at net.opengis.om.v_1_0_0.ObservationType
  at protected net.opengis.om.v_1_0_0.ObservationType net.opengis.sos.v_1_0_0.InsertObservation.observation
  at net.opengis.sos.v_1_0_0.InsertObservation
There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/ogc}temporalOps.
 this problem is related to the following location:
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetResult$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetResult$EventTime
  at protected java.util.List net.opengis.sos.v_1_0_0.GetResult.eventTime
  at net.opengis.sos.v_1_0_0.GetResult
  at @javax.xml.bind.annotation.XmlSeeAlso(value=[class net.opengis.sos.v_1_0_0.DescribeFeatureType, class net.opengis.sos.v_1_0_0.DescribeResultModel, class net.opengis.sos.v_1_0_0.InsertObservation, class net.opengis.sos.v_1_0_0.DescribeSensor, class net.opengis.sos.v_1_0_0.GetObservationById, class net.opengis.sos.v_1_0_0.GetFeatureOfInterestTime, class net.opengis.sos.v_1_0_0.GetResult, class net.opengis.sos.v_1_0_0.RegisterSensor, class net.opengis.sos.v_1_0_0.GetObservation, class net.opengis.sos.v_1_0_0.DescribeObservationType, class net.opengis.sos.v_1_0_0.GetFeatureOfInterest])
  at net.opengis.sos.v_1_0_0.InsertObservation
There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/ogc}spatialOps.
 this problem is related to the following location:
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetObservation$FeatureOfInterest.spatialOps
  at net.opengis.sos.v_1_0_0.GetObservation$FeatureOfInterest
  at public net.opengis.sos.v_1_0_0.GetObservation$FeatureOfInterest net.opengis.sos.v_1_0_0.ObjectFactory.createGetObservationFeatureOfInterest()
  at net.opengis.sos.v_1_0_0.ObjectFactory
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetResult$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetResult$EventTime
  at protected java.util.List net.opengis.sos.v_1_0_0.GetResult.eventTime
  at net.opengis.sos.v_1_0_0.GetResult
  at @javax.xml.bind.annotation.XmlSeeAlso(value=[class net.opengis.sos.v_1_0_0.DescribeFeatureType, class net.opengis.sos.v_1_0_0.DescribeResultModel, class net.opengis.sos.v_1_0_0.InsertObservation, class net.opengis.sos.v_1_0_0.DescribeSensor, class net.opengis.sos.v_1_0_0.GetObservationById, class net.opengis.sos.v_1_0_0.GetFeatureOfInterestTime, class net.opengis.sos.v_1_0_0.GetResult, class net.opengis.sos.v_1_0_0.RegisterSensor, class net.opengis.sos.v_1_0_0.GetObservation, class net.opengis.sos.v_1_0_0.DescribeObservationType, class net.opengis.sos.v_1_0_0.GetFeatureOfInterest])
  at net.opengis.sos.v_1_0_0.InsertObservation
There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/ogc}temporalOps.
 this problem is related to the following location:
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetFeatureOfInterest$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetFeatureOfInterest$EventTime
  at public net.opengis.sos.v_1_0_0.GetFeatureOfInterest$EventTime net.opengis.sos.v_1_0_0.ObjectFactory.createGetFeatureOfInterestEventTime()
  at net.opengis.sos.v_1_0_0.ObjectFactory
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetResult$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetResult$EventTime
  at protected java.util.List net.opengis.sos.v_1_0_0.GetResult.eventTime
  at net.opengis.sos.v_1_0_0.GetResult
  at @javax.xml.bind.annotation.XmlSeeAlso(value=[class net.opengis.sos.v_1_0_0.DescribeFeatureType, class net.opengis.sos.v_1_0_0.DescribeResultModel, class net.opengis.sos.v_1_0_0.InsertObservation, class net.opengis.sos.v_1_0_0.DescribeSensor, class net.opengis.sos.v_1_0_0.GetObservationById, class net.opengis.sos.v_1_0_0.GetFeatureOfInterestTime, class net.opengis.sos.v_1_0_0.GetResult, class net.opengis.sos.v_1_0_0.RegisterSensor, class net.opengis.sos.v_1_0_0.GetObservation, class net.opengis.sos.v_1_0_0.DescribeObservationType, class net.opengis.sos.v_1_0_0.GetFeatureOfInterest])
  at net.opengis.sos.v_1_0_0.InsertObservation
There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/ogc}temporalOps.
 this problem is related to the following location:
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetObservation$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetObservation$EventTime
  at public net.opengis.sos.v_1_0_0.GetObservation$EventTime net.opengis.sos.v_1_0_0.ObjectFactory.createGetObservationEventTime()
  at net.opengis.sos.v_1_0_0.ObjectFactory
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetResult$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetResult$EventTime
  at protected java.util.List net.opengis.sos.v_1_0_0.GetResult.eventTime
  at net.opengis.sos.v_1_0_0.GetResult
  at @javax.xml.bind.annotation.XmlSeeAlso(value=[class net.opengis.sos.v_1_0_0.DescribeFeatureType, class net.opengis.sos.v_1_0_0.DescribeResultModel, class net.opengis.sos.v_1_0_0.InsertObservation, class net.opengis.sos.v_1_0_0.DescribeSensor, class net.opengis.sos.v_1_0_0.GetObservationById, class net.opengis.sos.v_1_0_0.GetFeatureOfInterestTime, class net.opengis.sos.v_1_0_0.GetResult, class net.opengis.sos.v_1_0_0.RegisterSensor, class net.opengis.sos.v_1_0_0.GetObservation, class net.opengis.sos.v_1_0_0.DescribeObservationType, class net.opengis.sos.v_1_0_0.GetFeatureOfInterest])
  at net.opengis.sos.v_1_0_0.InsertObservation
There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/ogc}comparisonOps.
 this problem is related to the following location:
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetObservation$Result.comparisonOps
  at net.opengis.sos.v_1_0_0.GetObservation$Result
  at public net.opengis.sos.v_1_0_0.GetObservation$Result net.opengis.sos.v_1_0_0.ObjectFactory.createGetObservationResult()
  at net.opengis.sos.v_1_0_0.ObjectFactory
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetResult$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetResult$EventTime
  at protected java.util.List net.opengis.sos.v_1_0_0.GetResult.eventTime
  at net.opengis.sos.v_1_0_0.GetResult
  at @javax.xml.bind.annotation.XmlSeeAlso(value=[class net.opengis.sos.v_1_0_0.DescribeFeatureType, class net.opengis.sos.v_1_0_0.DescribeResultModel, class net.opengis.sos.v_1_0_0.InsertObservation, class net.opengis.sos.v_1_0_0.DescribeSensor, class net.opengis.sos.v_1_0_0.GetObservationById, class net.opengis.sos.v_1_0_0.GetFeatureOfInterestTime, class net.opengis.sos.v_1_0_0.GetResult, class net.opengis.sos.v_1_0_0.RegisterSensor, class net.opengis.sos.v_1_0_0.GetObservation, class net.opengis.sos.v_1_0_0.DescribeObservationType, class net.opengis.sos.v_1_0_0.GetFeatureOfInterest])
  at net.opengis.sos.v_1_0_0.InsertObservation
There's no ObjectFactory with an @XmlElementDecl for the element {http://www.opengis.net/ogc}spatialOps.
 this problem is related to the following location:
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetFeatureOfInterest$Location.spatialOps
  at net.opengis.sos.v_1_0_0.GetFeatureOfInterest$Location
  at protected net.opengis.sos.v_1_0_0.GetFeatureOfInterest$Location net.opengis.sos.v_1_0_0.GetFeatureOfInterest.location
  at net.opengis.sos.v_1_0_0.GetFeatureOfInterest
  at public net.opengis.sos.v_1_0_0.GetFeatureOfInterest net.opengis.sos.v_1_0_0.ObjectFactory.createGetFeatureOfInterest()
  at net.opengis.sos.v_1_0_0.ObjectFactory
  at protected javax.xml.bind.JAXBElement net.opengis.sos.v_1_0_0.GetResult$EventTime.temporalOps
  at net.opengis.sos.v_1_0_0.GetResult$EventTime
  at protected java.util.List net.opengis.sos.v_1_0_0.GetResult.eventTime
  at net.opengis.sos.v_1_0_0.GetResult
  at @javax.xml.bind.annotation.XmlSeeAlso(value=[class net.opengis.sos.v_1_0_0.DescribeFeatureType, class net.opengis.sos.v_1_0_0.DescribeResultModel, class net.opengis.sos.v_1_0_0.InsertObservation, class net.opengis.sos.v_1_0_0.DescribeSensor, class net.opengis.sos.v_1_0_0.GetObservationById, class net.opengis.sos.v_1_0_0.GetFeatureOfInterestTime, class net.opengis.sos.v_1_0_0.GetResult, class net.opengis.sos.v_1_0_0.RegisterSensor, class net.opengis.sos.v_1_0_0.GetObservation, class net.opengis.sos.v_1_0_0.DescribeObservationType, class net.opengis.sos.v_1_0_0.GetFeatureOfInterest])
  at net.opengis.sos.v_1_0_0.InsertObservation

After googling for a while I found this post on a mailing list. Now I am not a fan of editing auto-generated code, so I went looking for a better solution and read up on the documentation for the XmlSeeAlso annotation, specifically:

The user would be required to create JAXBContext as JAXBContext.newInstance(Dog.class,Cat.class)


Hmm... So after reading this I gave this a quick whirl:

import net.opengis.sensorml.v_1_0_1.ProcessChainType;
import net.opengis.sos.v_1_0_0.InsertObservation;
import net.opengis.sos.v_1_0_0.filter.v_1_1_0.BinaryTemporalOpType;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class JAXBTest {
    public static void main(String[] args) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(InsertObservation.class, BinaryTemporalOpType.class, ProcessChainType.class);
        InsertObservation insert = new InsertObservation();
        Marshaller mar = context.createMarshaller();
        mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        mar.marshal(insert, System.out);

    }
}

Yeah! Success:





The thing to note is that these two extra classes are not in the same package or jar file so cannot be found by the context loader, hence having to specifically add them.

Tuesday, June 22, 2010

Visual Basic UTF8

After much googling and messing about I have some UTF8 conversion functions for Visual Basic (vb).

Option Compare Database
Public Const UTF8 = 65001
Public Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long
Public Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cbMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long

'
'Converts Unicode to UTF8. It wraps the system call WideCharToMultiByte.
'
Public Function UTF8_Encode_System(ByVal sStr As String) As String
    Dim buffer As String
    Dim length As Long
    
    'Get the length of the converted data.
    length = WideCharToMultiByte(UTF8, 0, StrPtr(sStr), Len(sStr), 0, 0, 0, 0)
    
    'Ensure the buffer is the correct size.
    buffer = String$(length, 0)
    
    'Convert the string into the buffer.
    length = WideCharToMultiByte(UTF8, 0, StrPtr(sStr), Len(sStr), StrPtr(buffer), Len(buffer), 0, 0)
    
    'Access needs it in unicode?
    buffer = StrConv(buffer, vbUnicode)
    
    'Chop of any crap.
    buffer = Left$(buffer, length)
    
    'Return baby.
    UTF8_Encode_System = buffer
End Function

'
'Converts UTF8 data into unicode. It wrapps the system call MultiByteToWideChar.
'
Public Function UTF8_Decode_System(ByVal sStr As String) As String
    Dim buffer As String
    Dim length As Long
    
    'Get the length of the converted data.
    length = MultiByteToWideChar(UTF8, 0, StrPtr(StrConv(sStr, vbFromUnicode)), Len(sStr), 0, 0)
    
    'Ensure the buffer is the correct size.
    buffer = String$(length, 0)
    
    'Convert the data into the buffer.
    length = MultiByteToWideChar(UTF8, 0, StrPtr(StrConv(sStr, vbFromUnicode)), Len(sStr), StrPtr(buffer), Len(buffer))
    
    'Chop off any crap.
    buffer = Left$(buffer, length)
    
    'Return baby.
    UTF8_Decode_System = buffer
End Function