Chris
Chris

Reputation: 1058

Class constructor-arg causes exception

I'm trying to create a bean that takes a Class as a constructor argument:

public class DummyDao<T> {
    private final Class<T> entityClass;

    public DummyDao(final Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    public void doSomething() {
        System.out.println("My class is " + entityClass);
    }
}

I want to initialize it with the following class:

package com.example.dao;

public class SampleDto {
    private int id;
    private String text;

    public SampleDto() {
    }
    // getters, setters
}

I have this in my Spring configuration:

<bean id="dummyDao" class="com.example.dao.DummyDao">
    <constructor-arg>
        <value type="java.lang.Class" >com.example.dao.SampleDto.class</value>
    </constructor-arg>
</bean>

When I start Tomcat 7 in my Eclipse IDE, I get the following exceptions:

ERROR [localhost-startStop-1] (ContextLoader.java:307) - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dummyDao' defined in file [C:\workspace\scratch\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Loader\WEB-INF\classes\conf\spring\motiva-loader-persistence.xml]: Error converting typed String value for constructor argument; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Class'; nested exception is java.lang.IllegalArgumentException: Cannot find class [com.example.dao.SampleDto.class]
...
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Class'; nested exception is java.lang.IllegalArgumentException: Cannot find class [com.example.dao.SampleDto.class]
...
Caused by: java.lang.IllegalArgumentException: Cannot find class [com.example.dao.SampleDto.class]
...
Caused by: java.lang.ClassNotFoundException: com.example.dao.SampleDto.class
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)

Once the application is running there's no problem finding com.example.dao.SampleDto.class or passing it to the constructor of DummyDao - I can do this in Java code - so I can only conclude that the problem is caused by the class loader that's active during Spring initialisation. It's clear from the stack trace that it's a Tomcat loader.

But if I create a plain old bean that has a DummyDao as a field, there's no problem:

public class Consumer {
    private DummyDao<SampleDto> dummyDao = new DummyDao<SampleDto>(SampleDto.class);

    public Consumer() {
        System.out.println("**Consumer constructor: dummyDao=" + dummyDao);
    }
}

<bean id="consumer" class="com.example.dao.Consumer" />

The message "**Consumer constructor: dummyDao=com.example.dao.DummyDao@23dd246" appears in the log.

Can anybody suggest a fix for this problem?

Upvotes: 1

Views: 1760

Answers (1)

Reimeus
Reimeus

Reputation: 159774

Spring doesnt use the class literal so you could use

<value type="java.lang.Class" >com.example.dao.SampleDto</value>

Upvotes: 2

Related Questions