【问题标题】:Making GAE Shiro and Resteasy work together让 GAE Shiro 和 Resteasy 一起工作
【发布时间】:2013-04-05 00:08:01
【问题描述】:

我正在尝试让 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> 

【问题讨论】:

    标签: java google-app-engine jax-rs resteasy shiro


    【解决方案1】:

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

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

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

    例如:

    公共类 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 更改为使用MyBootstrapServletContextListener,而不是RESTEasy 的GuiceResteasyBootstrapServletContextListener,RESTEasy 不再有问题。您应该能够执行类似的操作以允许 RESTEasy 将所需的字符串传递给 com.cilogi.shiro.guice.ServeModule

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

    【讨论】:

    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多