jersey-spring3实例化Spring管理的bean空!

如何解决jersey-spring3实例化Spring管理的bean空!

我们有一个自定义的异步ContextLoader,因此临时解决方案需要在Jersey-Spring3源中放置一个完全hack,以在自定义组件提供程序初始化之前等待应用程序初始化。

PS对于任何发现自己必须执行此类操作的可怜人,请确保META-INF / settings包含SpringComponentProvider配置。

请注意,这是一个可怕的骇客,只有在所有其他尝试都失败的情况下,我才尝试尝试最后的手段,例如我的情况。另外,在尝试此类操作之前,我会咨询泽西岛邮寄小组有关你的问题的信息。

就是说…这就是我为解决我的问题所做的:

  • 从字面上将spring-jersey3的源代码复制到我的应用程序/服务器中,并根据许可证使用适当的标签修改每个文件的标题;

  • 创建了以下类

===>

  /**
   * Hack class for RN-8979.
   *
   * @author ryan
   *
   */
  public class ContextLoadWaiter {

    private static final Logger logger = Logger.getLogger(ContextLoadWaiter.class);

    public void doWait() {

      try {
        while (ContextLoaderHttpInterceptor.isNotStarted()) {
          logger.info("Waiting for ContextLoader to start...");
          Thread.sleep(1000);
        }
      } catch (InterruptedException e) {
        logger.error("SpringComponentProvider was interrupted!");
      }
    }
  }

请注意,这特定于 our 代码库,就像ContextLoaderHttpInterceptorhttp servlet一样,如果尚未加载我们的自定义(恰好是异步的),则isNotStarted返回。trueContextLoader

ContextLoader出于某种原因,有人在某个时候将自定义异步程序放置在适当的位置,以使服务器启动时允许UI显示“正在加载”页面。(可能不是添加此UI“功能”的正确方法,但是代码在那里并且UI依赖于它,所以我不得不处理它…)

由于这部分内容并不直接适用于你,因此关键是要调试SpringComponentProvider(从此处开始)并查看的值ClassPathXmlApplicationContext。如果它是null,就像我们的情况一样,那么你需要找出原因,null并ContextLoader在初始化此组件之前等待用于加载的任何内容。

  • 将这条黑线放在SpringComponentProvider

==>

  ...

  private final ContextLoadWaiter waiter = new ContextLoadWaiter();

  ...

  @Override
  public void initialize(ServiceLocator locator) {

    waiter.doWait(); // Wait on our asynchronous context loader.

    this.locator = locator;

    if (LOGGER.isLoggable(Level.FINE)) {
      LOGGER.fine("Context lookup started");
    }

    ...
  • 创建了这个文件:META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider其内容是SpringComponentProvider的完全限定的类路径,例如com.company.server.nbi.rest.internal.jspring.SpringComponentProvider

  • 添加了定制的Jersey-spring3软件包作为要在应用程序中进行扫描的软件包;见下文…

==>

/**
 * Application configuration.
 *
 * @author ryan
 *
 */
public class MyJerseyApplication extends ResourceConfig {

  private static final class Messages {
    static final String INF_STARTING_APPLICATION = "Starting %s!";
  }

  private static final Logger logger = Logger.getLogger(MyJerseyApplication.class);

  public MyJerseyApplication() {

    packages(
    /* Internal providers */
    "com.company.server.nbi.rest.providers",
    /* Internal filters */
    "com.company.server.nbi.rest.filters",
    /* Spring injection support */
    "com.company.server.nbi.rest.internal.jspring", // HERE!!!
    /* Json providers */
    "com.fasterxml.jackson.jaxrs.json",
    /* Jackson exception mappers */
    "com.fasterxml.jackson.jaxrs.base");

    /* Resources */
    register(ResourceA.class);
    register(ResourceB.class);
    register(ResourceC.class);

    /* Miscellaneous features */
    register(MultiPartFeature.class);
    register(LoggingFilter.class);

    logger.info(format(Messages.INF_STARTING_APPLICATION, this.getClass().getName()));
  }
}

而已”。绝对不是值得骄傲的解决方案,但是如果你像我一样处于绝望状态,试一下可能不会有任何伤害。

解决方法

首先,我想指出的是,从时间上来讲,这是我职业生涯中最大的难题。(现在已经连续两天,进度基本上为0。)我尝试的每个“解决方法”或“解决方案”都没有奏效,所以我很受阻,非常渴望获得一些帮助。

简而言之,问题是Jersey / HK2似乎总是在Spring实例化之后立即实例化我的Spring管理的bean,这告诉我jersey-spring3并没有完成工作,或者至少没有使用我当前的设置(或到目前为止我尝试过的约50种设置)。

请注意,当我使用空的构造函数时,这些资源字段在运行时为null。

我不明白为什么当前的设置不起作用,因为我实际上是在复制此在线示例

任何帮助都超过赞赏!

Configuration

-----pom.xml-----

<!-- ... -->

<dependencies>

    <!-- Spring Dependencies -->

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-instrument</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-instrument-tomcat</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-parent</artifactId>
        <version>${spring.version}</version>
        <classifier>tests</classifier>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring.version}</version>
        <classifier>tests</classifier>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-acl</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-support</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-dao</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- / Spring Dependencies -->

    <!-- API dependencies -->

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-processing</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
        <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
        <version>2.4</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-spring3</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>${gson.version}</version>
    </dependency>

    <!-- / API dependencies -->

    <!-- ... -->

</dependencies>

<!-- ... -->

<properties>

    <!-- ... -->

    <spring.version>3.0.5.RELEASE</spring.version>

    <jersey.version>2.4.1</jersey.version>

    <gson.version>2.2.4</gson.version>

    <!-- ... -->

</properties>

<!-- ... -->

-----web.xml-----

<web-app>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/beans.xml</param-value>
    </context-param>

    <!-- ... -->

    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>fubar.rest.FubarJerseyApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

    <!-- ... -->

</web-app>

-----beans.xml(Context Configuration)-----

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<!-- ... -->

<!-- beans-outbound-api has configuration for spring-jersey3 to work properly -->
<import resource="beans-api.xml" />

</beans>

-----beans-api.xml-----

<?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"
       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">

    <!-- Services -->

    <bean id="locationServiceV1" class="fubar.rest.v1.services.location.impl.LocationServiceV1" />
    <bean id="locationServiceV2" class="fubar.rest.v2.services.location.impl.LocationServiceV2" />

    <bean id="viewServiceV1" class="fubar.rest.v1.services.view.impl.ViewServiceV1" />
    <bean id="viewServiceV2" class="fubar.rest.v2.services.view.impl.ViewServiceV2" />

    <!-- Resources -->

    <bean class="fubar.rest.resources.location.impl.LocationResource">
        <constructor-arg index="0" ref="locationServiceV1" />
        <constructor-arg index="1" ref="locationServiceV2" />
    </bean>

    <bean class="fubar.rest.resources.view.impl.ViewResource">
        <constructor-arg index="0" ref="viewServiceV1" />
        <constructor-arg index="1" ref="viewServiceV2" />
    </bean>

</beans>

Code

-----Resource(JAX-RS)-----

@Path(RESTLocationResourceV1.PathFields.PATH_ROOT)
@Produces({V1_JSON,APPLICATION_JSON})
public class LocationResource
extends ResourceBase {

private static final Logger logger = Logger.getLogger(LocationResource.class);

@Inject
public LocationResource(final LocationServiceV1 v1Loc,final LocationServiceV2 v2Loc) {
super(v1Loc,v2Loc);
logger.info(format(Messages.INF_INSTANTIATED,“LocationResource”));
}

@GET
@Path(PathFields.SUBPATH_LIST)
public LocationListV1 listV1(@HeaderParam(HEADER_API_KEY) String apiKey)
throws ApplicationException {
// Implementation
}

@GET
@Path(PathFields.SUBPATH_SEARCH)
public LocationListV1 searchV1(@HeaderParam(HEADER_API_KEY) String apiKey,
@QueryParam(QueryFields.QUERY) String likeText) throws ApplicationException {
// Implementation
}
}

-----Service(Spring Bean)-----

public class LocationServiceV1 extends ServiceBaseV1<LocationBean,LocationV1,LocationListV1>
    implements
      ILocationServiceV1 {

  @Autowired
  private LocationDao daoLoc;

  public LocationServiceV1() {
    super(new LocationBeanToJsonTranslatorV1());
  }

  @Override
  public LocationListV1 listV1() throws ApplicationException {
    // Implementation
  }

  @Override
  public LocationListV1 searchV1(String likeText) throws ApplicationException {
    // Implementation
  }
}

(与版本2基本上相同)

          • Application (Jersey) - - - - -
public class FubarJerseyApplication extends ResourceConfig {

  private static final class Messages {
    static final String INF_STARTING_APPLICATION = "Starting %s!";
  }

  private static final Logger logger = Logger.getLogger(FubarJerseyApplication.class);

  public FubarJerseyApplication() {
    packages("fubar.rest");
    logger.info(format(Messages.INF_STARTING_APPLICATION,this.getClass().getName()));
  }
}

Invocation (Client)

curl http://my-ip-address/fubar/api/location/list

(500内部服务器错误)

Error (Server)

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object
available for injection at Injectee(requiredType=LocationServiceV1,parent=
LocationResource,qualifiers={}),position=0,optional=false,self=false,unqualified=null,344016971)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:208)
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:225)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:329)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:456)
at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:158)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2350)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:612)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:597)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:173)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:103)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:128)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:131)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:131)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:131)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:131)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:110)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:65)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:250)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:361)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at fubar.server.springframework.SessionFilter.doFilter(SessionFilter.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at fubar.server.springframework.loader.ContextLoaderHttpInterceptor$LoaderState.filter(ContextLoaderHttpInterceptor.java:75)
at fubar.server.springframework.loader.ContextLoaderHttpInterceptor$StartedState.filter(ContextLoaderHttpInterceptor.java:120)
at fubar.server.springframework.loader.ContextLoaderHttpInterceptor.doFilter(ContextLoaderHttpInterceptor.java:62)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:311)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:662)

API Log

Dec 10,2013 13:36:28 INFO  [main] fubar.rest.FubarJerseyApplication
     - Starting fubar.rest.FubarJerseyApplication!
Dec 10,2013 13:38:06 INFO  [pool-1-thread-1] resources.location.impl.LocationResource
     - LocationResource has been instantiated
Dec 10,2013 13:38:06 INFO  [pool-1-thread-1] resources.view.impl.ViewResource
     - ViewResource has been instantiated
 -

更新-找到了这个:

Catalina Log

Dec 10,2013 1:36:42 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application,version Jersey: 2.4.1 2013-11-08 12:08:47...
Dec 10,2013 1:36:43 PM org.glassfish.jersey.server.spring.SpringComponentProvider initialize
SEVERE: Spring context lookup failed,skipping spring component provider initialization.
Dec 10,2013 1:38:00 PM com.sun.xml.bind.v2.runtime.reflect.opt.Injector inject

…所以在SpringComponentProvider#initialize中找不到ApplicationContext 。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?