3

我正在尝试将 GAE-Shiro 和 Resteasy 组合在一起。所以我试着做一个快速端口。但是我收到此错误:

[ERROR] java.lang.RuntimeException: java.lang.InstantiationException: com.cilogi.shiro.guice.ServeModule
[ERROR]     at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.getModules(GuiceResteasyBootstrapServletContextListener.java:83)
[ERROR]     at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.contextInitialized(GuiceResteasyBootstrapServletContextListener.java:27)
[ERROR]     at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[ERROR]     at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[ERROR]     at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[ERROR]     at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[ERROR]     at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[ERROR]     at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[ERROR]     at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[ERROR]     at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[ERROR]     at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[ERROR]     at org.mortbay.jetty.Server.doStart(Server.java:224)
[ERROR]     at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[ERROR]     at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:228)
[ERROR]     at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:255)
[ERROR]     at com.google.appengine.tools.development.AbstractServer.startup(AbstractServer.java:79)
[ERROR]     at com.google.appengine.tools.development.DevAppServerImpl$Servers.startup(DevAppServerImpl.java:451)
[ERROR]     at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:198)
[ERROR]     at com.google.appengine.tools.development.gwt.AppEngineLauncher.start(AppEngineLauncher.java:97)
[ERROR]     at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:509)
[ERROR]     at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1068)
[ERROR]     at com.google.gwt.dev.DevModeBase.run(DevModeBase.java:811)
[ERROR]     at com.google.gwt.dev.DevMode.main(DevMode.java:311)
[ERROR] Caused by: java.lang.InstantiationException: com.cilogi.shiro.guice.ServeModule
[ERROR]     at java.lang.Class.newInstance0(Class.java:359)
[ERROR]     at java.lang.Class.newInstance(Class.java:327)
[ERROR]     at org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener.getModules(GuiceResteasyBootstrapServletContextListener.java:70)
[ERROR]     ... 22 more

这是我当前的 web.xml 配置

    <context-param>
        <param-name>resteasy.guice.modules</param-name>
<!--         <param-value>org.jboss.errai.ui.demo.server.MyServletModule</param-value> -->
        <param-value>com.cilogi.shiro.guice.ServeModule</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener
        </listener-class>
    </listener>

    <context-param>  
        <param-name>resteasy.servlet.mapping.prefix</param-name>  
        <param-value>/</param-value>  
    </context-param>

    <servlet>
        <servlet-name>Resteasy</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Resteasy</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <context-param>
       <param-name>user-base-url</param-name>
       <param-value>/user/admin</param-value>
    </context-param>

    <context-param>
        <param-name>static-base-url</param-name>
        <param-value></param-value>
    </context-param>


    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>com.cilogi.shiro.guice.ServeContextListener</listener-class>
    </listener>


    <mime-mapping>
        <extension>manifest</extension>
        <mime-type>text/cache-manifest</mime-type>
    </mime-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list> 
4

1 回答 1

4

我意识到这个问题已经有将近一年的历史了,但是我最近遇到了 Shiro(注意:不是 GAE-Shiro)和 RESTEasy 的类似问题,我想我会在这里发布我使用的解决方案,这样它可能会让其他任何经历过这个问题的人受益特别的问题。

问题是 RESTEasyGuiceResteasyBootstrapServletContextListener正在尝试创建一个需要将参数传递给它的模块(在我的情况下,它是一个ShiroWebModule需要ServletContext参数......在你的情况下,它看起来com.cilogi.shiro.guice.ServeModule需要传递一个字符串)。但是,当 RESTEasy 尝试创建模块时,它通过调用无参数构造函数来实现,然后由于没有参数而失败。

我决定采用的解决方案是扩展GuiceResteasyBootstrapServletContextListener和覆盖该getModules(ServletContext ctx)方法,以便如果ServletContext存在接受 a 的构造函数,则使用它,否则,使用默认的无参数构造函数。

例如:

公共类 MyBootstrapServletContextListener 扩展 GuiceResteasyBootstrapServletContextListener {

    @覆盖
    protected List getModules(final ServletContext context) {
        最终列表结果 = new ArrayList();
        final String modulesString = context.getInitParameter("resteasy.guice.modules");

        如果(模块字符串!= null){
            final String[] moduleStrings = modulesString.trim().split(",");

            for (final String moduleString : moduleStrings) {
                尝试 {
                    log.info("找到模块:{}", moduleString);
                    最终类 cls = Thread.currentThread().getContextClassLoader().loadClass(moduleString.trim());
                    最终模块模块 = createModule(cls, context);
                    结果.add(模块);
                } 捕捉(ClassNotFoundException e){
                    抛出新的 RuntimeException(e);
                } 捕捉(IllegalAccessException e){
                    抛出新的 RuntimeException(e);
                } 捕捉(实例化异常 e){
                    抛出新的 RuntimeException(e);
                } 捕捉(IllegalArgumentException e){
                    抛出新的 RuntimeException(e);
                } 捕捉(InvocationTargetException e){
                    抛出新的 RuntimeException(e);
                }
            }
        }

        返回结果;
    }

    私有模块 createModule(Class cls, ServletContext context) 抛出 InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        构造函数构造函数 = null;

        尝试 {
            构造函数 = cls.getConstructor(ServletContext.class);
        } 捕捉(NoSuchMethodException e){
            log.info("Class {} 没有只接受 ServletContext 参数的构造函数;默认为无参数构造函数。", cls);
        }

        返回构造函数 == null ?(模块) cls.newInstance() : (模块) 构造函数.newInstance(context);
    }

}

一旦这到位,我改为web.xml使用MyBootstrapServletContextListenerRESTEasy's 而不是GuiceResteasyBootstrapServletContextListenerRESTEasy 不再有问题。您应该能够执行类似的操作以允许 RESTEasy 将所需的 String 传递给com.cilogi.shiro.guice.ServeModule.

同样,我意识到您可能不再需要解决方案,但我在研究 Shiro 的类似问题时遇到了这个问题,并希望帮助其他试图在他们的 Web 应用程序中结合 RESTEasy 和 Shiro 的人。

于 2014-02-17T01:16:01.257 回答