服务器启动期间函数 isAssignableFrom returns false
Function isAssignableFrom returns false during server startup
实施 oauth2
系统,我在使用以下代码时遇到了一些问题:
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.servlet.HandlerMapping;
...
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
确实,由于 class FrameworkEndpointHandlerMapping
正在实现接口 HandlerMapping
,因此该函数应该始终 return true
。当我 运行 对此功能进行单元测试时就是这种情况。但是,在服务器启动期间,此函数 returns false
(已使用调试器检查)。这是一个大问题,因为当实例化 DispatcherServlet
时,它会搜索实现 HandlerMapping
的 class 而我的 FrameworkEndpointHandlerMapping
被丢弃,导致应用程序中出现错误。
我已经搜索过类似这个问题的其他问题,但大多数人回答说 isAssignableFrom
方法使用不正确(class 和函数参数的混合)。这里不是这种情况,因为 JUnit 正在工作。
怀疑导入的 jar
文件有问题,我将它们限制为以下文件:
- spring-beans-4.1.4.RELEASE.jar
- spring-security-oauth2-2.0.6.RELEASE.jar
- spring-webmvc-4.1.4.RELEASE.jar(也试过 4.0.9)
- spring-core-4.1.4.RELEASE.jar
- ...
请问您有什么解决方案可以探索吗?
有关更多信息,来源如下:
我自己的DispatcherServlet
(JUnit测试调用以String
为参数的构造函数,系统启动时调用默认构造函数)
import org.junit.Assert;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
public class MobileDispatcherServlet extends DispatcherServlet
{
private static final long serialVersionUID = 1L;
public MobileDispatcherServlet()
{
super();
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
}
public MobileDispatcherServlet(final WebApplicationContext webApplicationContext)
{
super(webApplicationContext);
final FrameworkEndpointHandlerMapping handlerMapping = webApplicationContext.getBean(FrameworkEndpointHandlerMapping.class);
HandlerMapping.class.isAssignableFrom(handlerMapping.getClass());
}
public MobileDispatcherServlet(final String test)
{
Assert.assertTrue(HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class));
}
}
oauth
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
<!-- Root of the configuration -->
<!-- The FrameworkEndpointHandlerMapping is created here -->
<oauth:authorization-server client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler"
authorization-endpoint-url="/oauth/authorize.action"
token-endpoint-url="/oauth/token.action" >
<oauth:authorization-code authorization-code-services-ref="authorizationCodeServices" disabled="false" />
<oauth:refresh-token />
</oauth:authorization-server>
...
</beans>
web.xml
:
<web-app id="sitestorefront" version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app.xsd"
metadata-complete="true">
...
<context-param>
<description>
The 'contextConfigLocation' param specifies where your configuration files are located.
The 'WEB-INF/config/web-application-config.xml' file includes several other XML config
files to build up the configuration for the application.
</description>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/config/web-application-config.xml</param-value>
</context-param>
<context-param>
<param-name>tagpoolMaxSize</param-name>
<param-value>50</param-value>
</context-param>
<servlet>
<description>
DispatcherServlet
</description>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>be.sbh.site.storefront.oauth2.MobileDispatcherServlet</servlet-class>
<init-param>
<description>
Specifies the location for Spring MVC to load an additional XML configuration file.
Because hybris is already configured with the XML spring configuration files to load
we must set this param value to EMPTY in order to prevent loading of the default
/WEB-INF/applicationContext.xml file.
</description>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!-- Map all requests to the DispatcherServlet -->
<url-pattern>/</url-pattern>
</servlet-mapping>
...
</web-app>
web-application-config.xml
导入所有配置文件(其中,oauth
配置文件)。其中之一有一个 <mvc:annotation-driven />
来启用 mvc 注释。
我试图将我的来源限制在与我相关的来源。如果您需要更多,请随时问我。
感谢您阅读这个问题,
洛朗
这真的很奇怪。面对这样的问题,我首先会怀疑这个bean 没有找到,或者被子应用程序上下文中的同名bean 隐藏了。但是正如您所说,您设法看到 ClassUtils.isAssignableFrom
被调用并返回 False
,我承认找到并测试了正确的 bean。
我能想到的最后一个问题是类路径中的多个 HandlerMapping 实例。正如 JonSkeet 的评论所建议的那样,如果类路径中有多个 spring-webmvc.jar
,FrameworkEndpointHandlerMapping
的类加载器可能会选择一个,而自定义 DispatcherServlet
的类加载器可能会选择另一个。
如果您使用的是 Maven,请控制依赖关系图。无论如何,请控制您应用程序和 servlet 容器的 lib 文件夹中的 jar 列表,以及可通过全局 CLASSPATH 环境变量公开访问的那些
实施 oauth2
系统,我在使用以下代码时遇到了一些问题:
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.servlet.HandlerMapping;
...
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
确实,由于 class FrameworkEndpointHandlerMapping
正在实现接口 HandlerMapping
,因此该函数应该始终 return true
。当我 运行 对此功能进行单元测试时就是这种情况。但是,在服务器启动期间,此函数 returns false
(已使用调试器检查)。这是一个大问题,因为当实例化 DispatcherServlet
时,它会搜索实现 HandlerMapping
的 class 而我的 FrameworkEndpointHandlerMapping
被丢弃,导致应用程序中出现错误。
我已经搜索过类似这个问题的其他问题,但大多数人回答说 isAssignableFrom
方法使用不正确(class 和函数参数的混合)。这里不是这种情况,因为 JUnit 正在工作。
怀疑导入的 jar
文件有问题,我将它们限制为以下文件:
- spring-beans-4.1.4.RELEASE.jar
- spring-security-oauth2-2.0.6.RELEASE.jar
- spring-webmvc-4.1.4.RELEASE.jar(也试过 4.0.9)
- spring-core-4.1.4.RELEASE.jar
- ...
请问您有什么解决方案可以探索吗?
有关更多信息,来源如下:
我自己的DispatcherServlet
(JUnit测试调用以String
为参数的构造函数,系统启动时调用默认构造函数)
import org.junit.Assert;
import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
public class MobileDispatcherServlet extends DispatcherServlet
{
private static final long serialVersionUID = 1L;
public MobileDispatcherServlet()
{
super();
HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class);
}
public MobileDispatcherServlet(final WebApplicationContext webApplicationContext)
{
super(webApplicationContext);
final FrameworkEndpointHandlerMapping handlerMapping = webApplicationContext.getBean(FrameworkEndpointHandlerMapping.class);
HandlerMapping.class.isAssignableFrom(handlerMapping.getClass());
}
public MobileDispatcherServlet(final String test)
{
Assert.assertTrue(HandlerMapping.class.isAssignableFrom(FrameworkEndpointHandlerMapping.class));
}
}
oauth
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
<!-- Root of the configuration -->
<!-- The FrameworkEndpointHandlerMapping is created here -->
<oauth:authorization-server client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler"
authorization-endpoint-url="/oauth/authorize.action"
token-endpoint-url="/oauth/token.action" >
<oauth:authorization-code authorization-code-services-ref="authorizationCodeServices" disabled="false" />
<oauth:refresh-token />
</oauth:authorization-server>
...
</beans>
web.xml
:
<web-app id="sitestorefront" version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app.xsd"
metadata-complete="true">
...
<context-param>
<description>
The 'contextConfigLocation' param specifies where your configuration files are located.
The 'WEB-INF/config/web-application-config.xml' file includes several other XML config
files to build up the configuration for the application.
</description>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/config/web-application-config.xml</param-value>
</context-param>
<context-param>
<param-name>tagpoolMaxSize</param-name>
<param-value>50</param-value>
</context-param>
<servlet>
<description>
DispatcherServlet
</description>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>be.sbh.site.storefront.oauth2.MobileDispatcherServlet</servlet-class>
<init-param>
<description>
Specifies the location for Spring MVC to load an additional XML configuration file.
Because hybris is already configured with the XML spring configuration files to load
we must set this param value to EMPTY in order to prevent loading of the default
/WEB-INF/applicationContext.xml file.
</description>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!-- Map all requests to the DispatcherServlet -->
<url-pattern>/</url-pattern>
</servlet-mapping>
...
</web-app>
web-application-config.xml
导入所有配置文件(其中,oauth
配置文件)。其中之一有一个 <mvc:annotation-driven />
来启用 mvc 注释。
我试图将我的来源限制在与我相关的来源。如果您需要更多,请随时问我。
感谢您阅读这个问题,
洛朗
这真的很奇怪。面对这样的问题,我首先会怀疑这个bean 没有找到,或者被子应用程序上下文中的同名bean 隐藏了。但是正如您所说,您设法看到 ClassUtils.isAssignableFrom
被调用并返回 False
,我承认找到并测试了正确的 bean。
我能想到的最后一个问题是类路径中的多个 HandlerMapping 实例。正如 JonSkeet 的评论所建议的那样,如果类路径中有多个 spring-webmvc.jar
,FrameworkEndpointHandlerMapping
的类加载器可能会选择一个,而自定义 DispatcherServlet
的类加载器可能会选择另一个。
如果您使用的是 Maven,请控制依赖关系图。无论如何,请控制您应用程序和 servlet 容器的 lib 文件夹中的 jar 列表,以及可通过全局 CLASSPATH 环境变量公开访问的那些