arquillian / arquillian-extension-persistence

Arquillian Database / Persistence Extension

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ClassNotFoundException with Postgresql UUID datatype

wyaeld opened this issue · comments

Issue Overview

Running a Wildfly Swarm project to build a JaxRS API using Arquillian for automated testing.
Data layer is JPA entities.
Database is Postgresql
Making use of @UsingDataSet annotation with YAML files.

Expected Behaviour

When a datatype has an ID of type UUID, the following seed snippet will work.

some_entity:
  - id: "uuid'2aad615a-d8e1-11e2-b8ed-50e549c9b654'"
    other_attrs...
Current Behaviour

Exception thrown when it tries to seed.

Caused by: org.dbunit.dataset.datatype.TypeCastException: Unable to typecast value <uuid'2aad615a-d8e1-11e2-b8ed-50e549c9b654'> of type <java.lang.String> to uuid
	at org.dbunit.ext.postgresql.UuidType.getUUID(UuidType.java:88)
	at org.dbunit.ext.postgresql.UuidType.setSqlValue(UuidType.java:63)
	at org.dbunit.database.statement.SimplePreparedStatement.addValue(SimplePreparedStatement.java:73)
	at org.dbunit.database.statement.AutomaticPreparedBatchStatement.addValue(AutomaticPreparedBatchStatement.java:63)
	at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:211)
	... 200 more
Caused by: java.lang.ClassNotFoundException: org.postgresql.util.PGobject from [Module "org.jboss.ironjacamar.jdbcadapters:main" from BootModuleLoader@7de62196 for finders [BootstrapClasspathModuleFinder, BootstrapModuleFinder(org.wildfly.swarm.bootstrap:main), ClasspathModuleFinder, ContainerModuleFinder(swarm.container:main), ApplicationModuleFinder(swarm.application:main), org.wildfly.swarm.bootstrap.modules.DynamicModuleFinder@163370c2]]
	at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198)
	at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
	at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
	at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
	at org.dbunit.dataset.datatype.AbstractDataType.loadClass(AbstractDataType.java:224)
	at org.dbunit.dataset.datatype.AbstractDataType.loadClass(AbstractDataType.java:213)
	at org.dbunit.ext.postgresql.UuidType.getUUID(UuidType.java:77)
	... 204 more
Steps to reproduce

Wildfly swarm project with usual datasource fractions and postgres

JPA entity using UUID datatype like:

    @Id
    @GeneratedValue
    @Column( columnDefinition = "uuid", updatable = false )
    private UUID id;

yaml seed file that specifies the ID
arquillian test that loads the seed using APE annotation

Additional Information

Have tried upgrading to the APE 2.x line, no change.
Have rules out Deployment and Shrinkwrap issues. Outputting the libs shows the Postgres classes are all there, and running a test which doesn't seed, but checks for the libs, works. See below.

The classpath issue only occurs during the APE seed stage. Is there a way to configure it to find the postgres lib?

 @Test
    public void testLibs() {
        try {
            Class.forName("org.postgresql.Driver");
            Class.forName("org.postgresql.util.PGobject");
        } catch (ClassNotFoundException e) {
            System.err.println("Where is your PostgreSQL JDBC Driver? "
                    + "Include in your library path!");
            e.printStackTrace();
        }
    }

I'm confused. I've been using these tests for weeks now without issue, and the problem has only arisen with the introduction of entities that use a UUID datatype, which requires a conversion to a native Postgres datatype.

I've spent a full day digging into the issue, trying different things, but currently have no reason to believe that the APE classpath issue is not the only thing preventing the functionality from working. Why would running as a Client solve the classpath loading the postgres jar?

My understanding is that running as Client treats the system as a black box, so I also don't understand how it could manage the transaction rollbacks.

Just an update on this, haven't fixed the problem, but tried going around it by just provisioning the test-data directory with junit. That approach however also fails, because I run into transaction boundary problems with RestAssured, which is being used to integration test the API.

It seems I need some of the glue in APE in order for Arquillian, JPA and RestAssured to play nicely together, but without this classloader bug being fixed, I can't use PG datatypes.

I'm happy to work with you guys to try and reproduce the issue, will work on seeing if I can create a failing test simply within APE.

@bartoszmajsak any thoughts?

@wyaeld did you had any luck with this?

Also having the same problem. Would very much appreciate it if anyone has any ideas on solving this.

I know this is old, but i have had issues with jboss/wildfly/swarm and now Thorntail. Lucky for me when it came to Thorntail i knew from jboss/wildfly how i could fix it. This is what i was able to do to get postgresql uuid to work. There may be a better way.

Steps
Create new directory structure under src/main/resources/
as
modules/org/jboss/ironjacamar/jdbcadapters/main.
Create newt module.xml in the main directory with this content.

<?xml version="1.0" encoding="UTF-8"?>
<module name="org.jboss.ironjacamar.jdbcadapters" xmlns="urn:jboss:module:1.5">
   <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <resources>
        <resource-root path="ironjacamar-jdbc-1.4.9.Final.jar"/>
        <artifact name="org.jboss.ironjacamar:ironjacamar-jdbc:1.4.6.Final" />
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.resource.api"/>
        <module name="javax.transaction.api"/>
        <module name="javax.validation.api"/>
        <module name="org.hibernate.validator"/>
        <module name="org.jboss.as.naming"/>
        <module name="org.jboss.as.transactions"/>
        <module name="org.jboss.jboss-transaction-spi"/>
        <module name="org.jboss.ironjacamar.api"/>
        <module name="org.jboss.ironjacamar.impl"/>
        <module name="org.jboss.logging"/>
        <module name="org.jboss.threads"/>
        <module name="javax.xml.stream.api"/>
        <module name="org.postgresql" />
</dependencies>
</module>

Notice the last modules is org.postgresql.

For the version of thorntail i am running "2.0.0.Final" this is the version of ironjacamar-jdbc it uses.
Now you should be able to run with no errors. I hope this helps someone.

commented

I know this is old, but i have had issues with jboss/wildfly/swarm and now Thorntail. Lucky for me when it came to Thorntail i knew from jboss/wildfly how i could fix it. This is what i was able to do to get postgresql uuid to work. There may be a better way.

Steps
Create new directory structure under src/main/resources/
as
modules/org/jboss/ironjacamar/jdbcadapters/main.
Create newt module.xml in the main directory with this content.

<?xml version="1.0" encoding="UTF-8"?>
<module name="org.jboss.ironjacamar.jdbcadapters" xmlns="urn:jboss:module:1.5">
   <properties>
        <property name="jboss.api" value="private"/>
    </properties>

    <resources>
        <resource-root path="ironjacamar-jdbc-1.4.9.Final.jar"/>
        <artifact name="org.jboss.ironjacamar:ironjacamar-jdbc:1.4.6.Final" />
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.resource.api"/>
        <module name="javax.transaction.api"/>
        <module name="javax.validation.api"/>
        <module name="org.hibernate.validator"/>
        <module name="org.jboss.as.naming"/>
        <module name="org.jboss.as.transactions"/>
        <module name="org.jboss.jboss-transaction-spi"/>
        <module name="org.jboss.ironjacamar.api"/>
        <module name="org.jboss.ironjacamar.impl"/>
        <module name="org.jboss.logging"/>
        <module name="org.jboss.threads"/>
        <module name="javax.xml.stream.api"/>
        <module name="org.postgresql" />
</dependencies>
</module>

Notice the last modules is org.postgresql.

For the version of thorntail i am running "2.0.0.Final" this is the version of ironjacamar-jdbc it uses.
Now you should be able to run with no errors. I hope this helps someone.

Thanks, mann-ed.

I met similar issue when testing with inet type as below. And it is fixed via adding module postgresql-jdbc jar to module.xml of org.jboss.ironjacamar.jdbcadapters.

org.jboss.arquillian.persistence.dbunit.exception.DBUnitDataSetHandlingException: Failed while seeding database.
Caused by: org.dbunit.dataset.datatype.TypeCastException: Unable to typecast value <192.168.1.0> of type <java.lang.String> to inet
Caused by: java.lang.ClassNotFoundException: org.postgresql.util.PGobject from [Module "org.jboss.ironjacamar.jdbcadapters:main" from local module loader @15d9bc04 (finder: local module finder @473b46c3 (roots: .....)