quarkiverse / quarkus-langchain4j

Quarkus Langchain4j extension
https://docs.quarkiverse.io/quarkus-langchain4j/dev/index.html
Apache License 2.0
116 stars 65 forks source link

easy-rag blowing up if not using websockets #642

Closed edeandrea closed 1 month ago

edeandrea commented 1 month ago

If I want to use the easy-rag extension in an app that is not a websocket app (just a simple REST app), the application blows up when the rest endpoint is hit, I think because of https://github.com/quarkiverse/quarkus-langchain4j/blob/main/rag/parsers-base/runtime/src/main/resources/META-INF/services/io.quarkiverse.langchain4j.spi.DefaultMemoryIdProvider

2024-05-30 13:24:31,668 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (quarkus-virtual-thread-1) HTTP Request to /question?question=What%20is%20the%20Quarkus%20equivalent%20of%20Spring%27s%20%40GetMapping%20annotation%3F failed, error id: 4381c064-86f9-43fe-9961-b0f8d1690b76-2: java.lang.NoClassDefFoundError: Could not initialize class io.quarkiverse.langchain4j.runtime.aiservice.AiServiceMethodImplementationSupport
        at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer.methodImplementationSupport(MethodImplementationSupportProducer.java:20)
        at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer_ProducerMethod_methodImplementationSupport_MimluGTOW4J_OymBP0vYo0MFSbY_Bean.doCreate(Unknown Source)
        at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer_ProducerMethod_methodImplementationSupport_MimluGTOW4J_OymBP0vYo0MFSbY_Bean.create(Unknown Source)
        at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer_ProducerMethod_methodImplementationSupport_MimluGTOW4J_OymBP0vYo0MFSbY_Bean.create(Unknown Source)
        at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:119)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:38)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35)
        at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:32)
        at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
        at io.quarkus.arc.impl.ComputingCacheContextInstances.computeIfAbsent(ComputingCacheContextInstances.java:19)
        at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:35)
        at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer_ProducerMethod_methodImplementationSupport_MimluGTOW4J_OymBP0vYo0MFSbY_Bean.get(Unknown Source)
        at io.quarkiverse.langchain4j.runtime.aiservice.MethodImplementationSupportProducer_ProducerMethod_methodImplementationSupport_MimluGTOW4J_OymBP0vYo0MFSbY_Bean.get(Unknown Source)
        at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:559)
        at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:539)
        at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:572)
        at io.quarkus.arc.impl.ArcContainerImpl.instanceHandle(ArcContainerImpl.java:534)
        at io.quarkus.arc.impl.ArcContainerImpl.instance(ArcContainerImpl.java:294)
        at io.erd.qforsqa.BookQueryService$$QuarkusImpl.askQuestionAboutBook(Unknown Source)
        at io.erd.qforsqa.BookQueryService$$QuarkusImpl_ClientProxy.askQuestionAboutBook(Unknown Source)
        at io.erd.qforsqa.BookQueryResource.askQuestion(BookQueryResource.java:24)
        at io.erd.qforsqa.BookQueryResource_Subclass.askQuestion$$superforward(Unknown Source)
        at io.erd.qforsqa.BookQueryResource_Subclass$$function$$1.apply(Unknown Source)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
        at io.quarkus.hibernate.validator.runtime.interceptor.AbstractMethodValidationInterceptor.validateMethodInvocation(AbstractMethodValidationInterceptor.java:71)
        at io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyReactiveEndPointValidationInterceptor.validateMethodInvocation(ResteasyReactiveEndPointValidationInterceptor.java:21)
        at io.quarkus.hibernate.validator.runtime.jaxrs.ResteasyReactiveEndPointValidationInterceptor_Bean.intercept(Unknown Source)
        at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
        at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
        at io.erd.qforsqa.BookQueryResource_Subclass.askQuestion(Unknown Source)
        at io.erd.qforsqa.BookQueryResource$quarkusrestinvoker$askQuestion_bee13abbdbe5ce4203fc78261fef611a41ead77f.invoke(Unknown Source)
        at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
        at io.quarkus.virtual.threads.ContextPreservingExecutorService$ContextPreservingRunnable.run(ContextPreservingExecutorService.java:45)
        at java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
        at java.base/java.lang.VirtualThread.run(VirtualThread.java:309)
Caused by: java.lang.ExceptionInInitializerError: Exception java.util.ServiceConfigurationError: io.quarkiverse.langchain4j.spi.DefaultMemoryIdProvider: Provider io.quarkiverse.langchain4j.websockets.next.runtime.WebSocketConnectionDefaultMemoryIdProvider not found [in thread "ForkJoinPool-1-worker-1"]
        at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:593)
        at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1219)
        at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
        at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
        at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
        at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
        at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
        at dev.langchain4j.spi.ServiceHelper.loadAll(ServiceHelper.java:73)
        at dev.langchain4j.spi.ServiceHelper.loadFactories(ServiceHelper.java:53)
        at dev.langchain4j.spi.ServiceHelper.loadFactories(ServiceHelper.java:26)
        at io.quarkiverse.langchain4j.runtime.aiservice.AiServiceMethodImplementationSupport.<clinit>(AiServiceMethodImplementationSupport.java:65)
        ... 39 more
edeandrea commented 1 month ago

Adding a dependency exclusion seems to solve the problem for my app:

    <dependency>
      <groupId>io.quarkiverse.langchain4j</groupId>
      <artifactId>quarkus-langchain4j-easy-rag</artifactId>
      <exclusions>
        <exclusion>
          <groupId>io.quarkiverse.langchain4j</groupId>
          <artifactId>quarkus-langchain4j-parsers-base</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
geoand commented 1 month ago

Ouch...

https://github.com/quarkiverse/quarkus-langchain4j/pull/645 fixes the problem

geoand commented 1 month ago

This is also a duplicate of #636 and since that one was opened first, I'll close this in favor of that one