Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using hystrix: No bean named 'resourceLoaderDependingInitHook' is defined #75

Closed
jangalinski opened this issue Apr 24, 2016 · 8 comments
Labels
Milestone

Comments

@jangalinski
Copy link
Contributor

I added the following dependencies to a pom.xml using the camunda-springboot-webapp starter.

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-netflix-core</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>

Result:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'resourceLoaderDependingInitHook' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.camunda.bpm.spring.boot.starter.webapp.filter.LazyFilterRuntimeListener.finished(LazyFilterRuntimeListener.java:38) ~[camunda-bpm-spring-boot-starter-webapp-1.2.0-SNAPSHOT.jar:1.2.0-SNAPSHOT]
    at org.springframework.boot.SpringApplicationRunListeners.callFinishedListener(SpringApplicationRunListeners.java:79) ~[spring-boot-1.3.3.RELEASE.jar:1.3.3.RELEASE]
@g00glen00b
Copy link
Contributor

g00glen00b commented Apr 26, 2016

Same issue here, though I'm not using Hystrix but I am using Eureka (from Spring cloud/Netflix as well). I think the compatibility of Spring cloud with Camunda isn't perfect yet.

@jangalinski
Copy link
Contributor Author

What is perfect in this world?
We were aiming for "camunda can run with spring boot" ...now the next goal is "run as/in a cloud". Camunda itself does not support all possible usecases, especially when working with distributed, heterogenous engines not synched by a common datasource.

But maybe you are able to help us out? Could you analyse the resourceLoader Problem? to me it seems that the whole concept of static references in spring lifecycle methods is not the optimal choice, but I do not really get it ...

@g00glen00b
Copy link
Contributor

g00glen00b commented Apr 27, 2016

Nothing is perfect. It looks that for some reason any SpringApplicationRunListener is executed twice when using Spring cloud. This is clearly something related to Spring itself, because if you add Spring cloud, you can also see it mentions the "Started Application in 0.999 seconds (JVM running for 0.4999)" line twice in the logs.

I also added a log to the finish statement of the runner:

b.c.test.LazyFilterRuntimeListener       : It's finished
be.company.test.TestCamundaApplication   : Started TestCamundaApplication in 0.499 seconds (JVM running for 0.86)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.7.RELEASE)


...

s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
b.c.test.LazyFilterRuntimeListener       : It's finished
be.company.test.TestCamundaApplication   : Started TestCamundaApplication in 2.423 seconds (JVM running for 2.721)

I have no idea why it does that, so I asked on StackOverflow. Perhaps there's an obvious reason that I'm missing.

@g00glen00b
Copy link
Contributor

But knowing that it executes twice, you could check first if the context contains a bean with the given context:

@Override
public void finished(ConfigurableApplicationContext context, Throwable exception) {
  if (context.containsBean("resourceLoaderDependingInitHook")) {
    @SuppressWarnings("unchecked")
    InitHook<ResourceLoaderDependingFilter> initHook = context.getBean("resourceLoaderDependingInitHook", InitHook.class);
    init(LazySecurityFilter.INSTANCE, initHook);
    init(LazyProcessEnginesFilter.INSTANCE, initHook);
  } else {
    logger.warn("Finished lazy runtime listener without access to resourceLoaderDependingInitHook");
  }
}

This does the trick, however, a bit later I got another exception that the CamundaBpmProperties was available twice on the application context, so I also changed the autowire in CamundaBpmWebappAutoConfiguration to this:

@Autowired
@Qualifier("camundaBpmProperties")
private CamundaBpmProperties properties;

That did the trick and the admin application is working now. If you would like me to create a pull request I'll do that (have to verify if I have to change any tests though).

@jangalinski
Copy link
Contributor Author

Thanks for your input, Dimitri.
Great analysis of some probably hard to discover runtime dependencies.

Spontanuous idea: If the RunListener is really the problem here, we could try another approach: we can use camunda hooks (@postdeploy or ProcessEnginePlugin.postEngineBuild()) to execute stuff that is supposed to happen after the application started without relying on the spring application lifecycle. That's something I already had in mind anyway (there even is an issue for that somewhere).

But for now: if you could create a PR, I would accept the quick-fix, but you'd have to live with a removal somewhere in the near future when the lifecycle is siwtched to camunda. Deal?

@g00glen00b
Copy link
Contributor

For me personally it doesn't matter, I'm just testing the capabilities of Camunda. I created a pull request already #79.

jangalinski pushed a commit that referenced this issue Apr 27, 2016
* Implemented more safe way to check if the inithook bean was already created (#75)

* Fixed referencing CamundaBpmProperties by qualifier in case multiple instances are found on the application context
@jangalinski jangalinski added this to the 1.2 milestone Apr 27, 2016
jangalinski added a commit that referenced this issue Apr 27, 2016
* Implemented more safe way to check if the inithook bean was already created (#75)

* Fixed referencing CamundaBpmProperties by qualifier in case multiple instances are found on the application context

* add documentation for SpringBootProcessApplication

* add hystrix to test
@jangalinski jangalinski reopened this Apr 27, 2016
@jangalinski
Copy link
Contributor Author

With PR #79 the CamundaBpmWebappConfigurationIT test fails because it cannot find CamundaBpmProperties bean. Ideas?

@jangalinski
Copy link
Contributor Author

fixed by switching to EnableConfigurationProperties

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants