finos / spring-bot

Spring Boot + Java Integration for Symphony/Teams Chat Platform Bots and Apps
https://springbot.finos.org
Apache License 2.0
60 stars 35 forks source link

Can we add SpringBot dependency on project which has parent dependency Sping-Boot:3x #405

Closed vaibhav-db closed 1 year ago

vaibhav-db commented 1 year ago

Can we add spring-bot dependency on project which has parent dependency Sping-Boot:3x

We have tried to add SpingBot dependency on project has spring-bot:3x dependency.

Error 1: We got error Unsatisfied dependency expressed through field 'teamsResponseHandler':

No qualifying bean of type 'org.finos.springbot.teams.handlers.TeamsResponseHandler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Resolution : adding ComponentScan for "org.finos"

Error 2: java.lang.ClassNotFoundException: org.thymeleaf.spring5.SpringTemplateEngine

Resolution :

org.springframework.boot spring-boot-starter-thymeleaf 2.7.0

After adding thymeleaf older dependency, project started successfully.

Error 3: Azure Identity => ERROR in getToken() call for scopes [[https://graph.microsoft.com/.default]: ]

(https://graph.microsoft.com/.default]:) A request was made to load the default HttpClient provider but one could not be found on the classpath. If you are using a dependency manager, consider including a dependency on azure-core-http-netty or azure-core-http-okhttp. Depending on your existing dependencies, you have the choice of Netty or OkHttp implementations. Additionally, refer to https://aka.ms/azsdk/java/docs/custom-httpclient to learn about writing your own implementation.

Resolution: Class.forName("com.azure.core.implementation.http.HttpClientProviders"); Load HttpClientProviders at start of project

ERROR 4: When it try to send error response to MS Teams: java.lang.NoSuchMethodError: 'void org.springframework.http.ResponseEntity.(org.springframework.http.HttpStatus)'

  | at com.microsoft.bot.integration.spring.BotController.lambda$incoming$0(BotController.java:94) ~[bot-integration-spring-4.14.3.jar!/:4.14.3]   | at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) ~[na:na]   | at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) ~[na:na]

robmoffat commented 1 year ago

Have you tried changing the spring-bot pom.xml file here:

<spring-boot.version>2.7.10</spring-boot.version>

... to a 3.x version? Are these the errors you get when you do that?

vaibhav-db commented 1 year ago

No @robmoffat nothing change in SpingBot..

I am trying to add SpringBot dependency on my new project which has parent spring-boot:3x version

vaibhav-db commented 1 year ago

We can't used the SpringBot dependency if project is build with spring-boot 3x...

As SpringBot and bot-integration-builder is build on spring-boot 2x version.

robmoffat commented 1 year ago

Yep, understood.

This is going to be tricky because of that 4th problem. Can it wait until Wednesday, or do you want some time tomorrow AM?

robmoffat commented 1 year ago

This stems from the bot-integration-spring project, which, given MS are not really into Java support anymore, I doubt will get updated to Spring-Boot 3.

Luckily, there are only 4 classes in this project, so it might be wise to drop this dependency and add these classes to our own codebase.

We can fix so that it works with either Spring-Boot 2 or 3 at the same time.

vaibhav-db commented 1 year ago

It not on high priority, we can connect on Wednesday on our regular time. If you want we can connect tomorrow same time.

I will try to add these class in our project and try to build.

Actually I don't want to change the SpringBot spring-boot version. Any application which are using spring-boot: 3x or Spring-boot: 2x should able to integrate our SpingBot.

Here issue is with Spring-Boot: 2x and Spring-boot: 3x application.

I don't know why they have not kept backwards compatibility.

robmoffat commented 1 year ago

I will try to add these class in our project and try to build.

Yeah give it a go.

vaibhav-db commented 1 year ago

After adding all bot-integration-spring classes and modifying BotController.incoming ERROR 4 is resolved. Now we are getting s.w.r.t.AbstractResourceTemplateProvider : Couldn't find template: custom-help-templatejava.io.FileNotFoundException: class path resource [templates/teams/custom-help-template.html] cannot be opened

vaibhav-db commented 1 year ago

Class loader:

Local eclipse: getClassLoader TomcatEmbeddedWebappClassLoader context: ROOT delegate: true ----------> Parent Classloader: jdk.internal.loader.ClassLoaders$AppClassLoader@1d44bcfa

Local Fat jar: getClassLoader TomcatEmbeddedWebappClassLoader context: ROOT delegate: true ----------> Parent Classloader: org.springframework.boot.loader.LaunchedURLClassLoader@277050dc

Fabric: getClassLoader jdk.internal.loader.ClassLoaders$AppClassLoader@73d16e93


For local fat jar also it is working fine. Only issue on Fabric

vaibhav-db commented 1 year ago

Finally worked, after adding below code in AbstractResourceTemplateProvider:

@Autowired DefaultResourceLoader resourceLoader;

and set class loader in Resource getResource(String name) method resourceLoader.setClassLoader(this.getClass().getClassLoader());

vaibhav-db commented 1 year ago

Tested SpringBot framework on project having Spring-boot:2x and Spring-Bot:3x... all are working file.

@robmoffat please verify the approach.

robmoffat commented 1 year ago

and set class loader in Resource getResource(String name) method resourceLoader.setClassLoader(this.getClass().getClassLoader());

You should only need to do this once, and the resourceLoader should be the same one as being used by Teams, so I don't understand why the @PostConstruct (TeamsWorkflowConfig) isn't doing the job for you.

Is it possible that @PostConstruct doesn't get called in Spring Boot 3?

vaibhav-db commented 1 year ago

let me check that, might be spring-boot 3 has jakarta.annotation.PostConstruct and Spring-boot:2x has javax.annotation.PostConstruct

robmoffat commented 1 year ago

you probably should attach a debugger

vaibhav-db commented 1 year ago

We are only getting this error on Fabric. From local and fat jar it is working properly. Db system does allow to attached a debugger.

vaibhav-db commented 1 year ago

Yes it is issue of @PostConstruct annotation

After setting classloader in my project configuration, project is working.

@Autowired DefaultResourceLoader resourceLoader;

@PostConstruct public void setResourceLoaderClassLoader() { resourceLoader.setClassLoader(this.getClass().getClassLoader()); }

robmoffat commented 1 year ago

So - the @PostConstruct doesn't work in Spring Boot 3? Could we add your other annotation instead?

vaibhav-db commented 1 year ago

Another option will be public class MyComponent implements InitializingBean { @Override public void afterPropertiesSet() { resourceLoader.setClassLoader(this.getClass().getClassLoader()); }

robmoffat commented 1 year ago

what about just bunging both annotations on there?

vaibhav-db commented 1 year ago

Sorry didn't get your question.

1 option: Add classloader in your project like DemoBot project which has spring-boot:3x parent @PostConstruct public void setResourceLoaderClassLoader() { resourceLoader.setClassLoader(this.getClass().getClassLoader()); }

2 option: implements InitializingBean in our TeamsWorkflowConfig class and override afterPropertiesSet method. public class TeamsWorkflowConfig implements InitializingBean {

@Override public void afterPropertiesSet() throws Exception { resourceLoader.setClassLoader(this.getClass().getClassLoader()); }