代码之家  ›  专栏  ›  技术社区  ›  quarks

让GAE Shiro和Resteasy合作

  •  3
  • quarks  · 技术社区  · 12 年前

    我正在努力让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> 
    
    1 回复  |  直到 12 年前
        1
  •  4
  •   syllk    11 年前

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

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

    我决定采用的解决方案是 GuideResteasyBootstrap Servlet上下文侦听器 并覆盖 getModules(ServletContext ctx) 方法,以便如果构造函数 Servlet上下文 存在,然后使用它,否则,使用默认的无参数构造函数。

    例如:

    public class MyBootstrapServletContextListener extends GuiceResteasyBootstrapServletContextListener {
    
        @Override
        protected List getModules(final ServletContext context) {
            final List result = new ArrayList();
            final String modulesString = context.getInitParameter("resteasy.guice.modules");
    
            if (modulesString != null) {
                final String[] moduleStrings = modulesString.trim().split(",");
    
                for (final String moduleString : moduleStrings) {
                    try {
                        log.info("Found module: {}", moduleString);
                        final Class cls = Thread.currentThread().getContextClassLoader().loadClass(moduleString.trim());
                        final Module module = createModule(cls, context);
                        result.add(module);
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    } catch (InstantiationException e) {
                        throw new RuntimeException(e);
                    } catch (IllegalArgumentException e) {
                        throw new RuntimeException(e);
                    } catch (InvocationTargetException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    
            return result;
        }
    
        private Module createModule(Class cls, ServletContext context) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            Constructor constructor = null;
    
            try {
                constructor = cls.getConstructor(ServletContext.class);
            } catch (NoSuchMethodException e) {
                log.info("Class {} has no constructor that takes just a ServletContext parameter; defaulting to no-args constructor.", cls);
            }
    
            return constructor == null ? (Module) cls.newInstance() : (Module) constructor.newInstance(context);
        }
    
    }
    

    一旦这一点到位,我就改变了 web.xml 使用 MyBootstrapServletContextListener 而不是RESTEasy的 GuideResteasyBootstrap Servlet上下文侦听器 ,RESTEasy不再有问题。您应该能够执行类似的操作,允许RESTEasy将所需的String传递给 com.cilogi.shiro.gui服务模块 .

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