带有JdbcRealm和JndiObjectFactory的Apache Shiro会抛出IllegalArgumentException

时间:2012-08-06 10:59:27

标签: java-ee-6 shiro

我正在尝试在GlassFish v3.1.2应用服务器上的JavaEE6 Web应用程序中使用Apache Shiro(v1.2)。

在GlassFish中,我已经设置了一个数据源(jdbc/myds),我已通过JPA2测试了该数据源。

我想使用相同的数据源来验证使用Shiro JDBC领域的用户。

我在shiro.ini中有以下内容:

# DataSource config
ds                = org.apache.shiro.jndi.JndiObjectFactory 
ds.requiredType   = javax.sql.DataSource
ds.resourceName   = jdbc/myds

# JDBC realm config
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = false
jdbcRealm.authenticationQuery = SELECT password FROM user_account WHERE email = ?
jdbcRealm.userRolesQuery = SELECT role_name FROM user_group_membership WHERE email = ?
jdbcRealm.dataSource = $ds

当我部署应用程序时,我得到以下异常(摘要):

FINE: Encountered object reference '$ds'.  Looking up object with id 'ds'
FINEST: Applying property [dataSource] value [org.apache.shiro.jndi.JndiObjectFactory@2ca061] on object of type [org.apache.shiro.realm.jdbc.JdbcRealm]
SEVERE: Unable to start Filter: [Unable to set property 'dataSource' with value [$ds] on object of type org.apache.shiro.realm.jdbc.JdbcRealm.  If '$ds' is a reference to another (previously defined) object, prefix it with '$' to indicate that the referenced object should be used as the actual value.  For example, $$ds].
org.apache.shiro.config.ConfigurationException: Unable to set property 'dataSource' with value [$ds] on object of type org.apache.shiro.realm.jdbc.JdbcRealm.  If '$ds' is a reference to another (previously defined) object, prefix it with '$' to indicate that the referenced object should be used as the actual value.  For example, $$ds
at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:373)
at org.apache.shiro.config.ReflectionBuilder.applySingleProperty(ReflectionBuilder.java:198)
at org.apache.shiro.config.ReflectionBuilder.applyProperty(ReflectionBuilder.java:159)
at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:119)
...
...
Caused by: java.lang.IllegalArgumentException: Cannot invokeorg.apache.shiro.realm.jdbc.JdbcRealm.setDataSource on bean class 'class org.apache.shiro.realm.jdbc.JdbcRealm' - argument type mismatch - had objects of type "org.apache.shiro.jndi.JndiObjectFactory" but expected signature "javax.sql.DataSource"
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2235)
at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2151)
at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1957)
...

如果我定义一个实际的MySQL数据源,它可以正常工作,例如

ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource 
ds.serverName = localhost
ds.user = root
ds.password = root
ds.databaseName = mydb

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

这看起来很可能是类路径问题。堆栈跟踪引用了在shiro 1.1.0中有意义的ReflectionBuilder的行号。然而,它们在shiro 1.2.0中没有意义。但是,由于JndiObjectFactory在shiro 1.2.0中是新的,并且两个类都在shiro-core中,所以你可能在类路径上都有两个jar。

您应首先查看您的war文件,确保两个罐子都不在那里。如果是,您可以通过删除1.1.0版本来修复war文件。如果没有,我会开始寻找你是否通过玻璃鱼基础设施以某种方式继承旧版本的shiro。