Circular dependency while fetching history in java sdk

i want to send temporal history as response of an api call. But im getting the below error

WorkflowExecution workflowExecution = WorkflowExecution.newBuilder()
.setWorkflowId(workflowId)
.setRunId(runId)
.build();

        GetWorkflowExecutionHistoryRequest request =
                GetWorkflowExecutionHistoryRequest.newBuilder()
                        .setNamespace(namespace)
                        .setExecution(WorkflowExecution.newBuilder()
                                .setWorkflowId(workflowId)
                                .build())
                        .build();

        WorkflowExecutionHistory workflowExecutionHistory = new WorkflowExecutionHistory(
                service.blockingStub().getWorkflowExecutionHistory(request).getHistory());

through reference chain: com.bre.commons.dto.CommonResponseDto["response"]->io.temporal.internal.common.WorkflowExecutionHistory["history"]->io.temporal.api.history.v1.History["unknownFields"]->com.google.protobuf.UnknownFieldSet["defaultInstanceForType"] : This part of the error message shows the path of the cyclic dependency in the object’s structure.

as defaultInstanceForType field of History is of type History im not able to send the response
please help

Hello,

@Tallam_Hemanth

I guess this has to do with a dependency you have in your project, can you share a small repro?

Also, is that the full error message?

Antonio

Hi @antonio.perez

below is the error

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: io.temporal.api.workflow.v1.WorkflowExecutionInfo[“unknownFields”]->com.google.protobuf.UnknownFieldSet[“defaultInstanceForType”]->com.google.protobuf.UnknownFieldSet[“defaultInstanceForType”])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference(BeanPropertyWriter.java:944)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:722)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4568)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3821)
at com.bre.orchestrator.service.impl.BreWorkflowHouseKeepingServiceImpl.getWorkflowDetails(BreWorkflowHouseKeepingServiceImpl.java:103)
at com.bre.orchestrator.controller.BreWorkflowHouseKeepingController.getWorkflowDetails(BreWorkflowHouseKeepingController.java:38)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:497)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:584)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.servlet.OpenTelemetryHandlerMappingFilter.doFilter(OpenTelemetryHandlerMappingFilter.java:81)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:79)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:79)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2019)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1558)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1449)
at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
at java.base/java.lang.Thread.run(Thread.java:829)

Hi @antonio.perez
these are the dependencies

temporal java-sdk → 1.17.0

io.temporal
temporal-sdk
1.17.0

This is working for me with temporal 1.17.0

WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();

        String namespace = "default";
        String workflowId = "childWorkflow";
        GetWorkflowExecutionHistoryRequest request =
                GetWorkflowExecutionHistoryRequest.newBuilder()
                        .setNamespace(namespace)
                        .setExecution(WorkflowExecution.newBuilder().setWorkflowId(workflowId).build())
                        .build();

        WorkflowExecutionHistory workflowExecutionHistory =
                new WorkflowExecutionHistory(
                        service.blockingStub().getWorkflowExecutionHistory(request).getHistory());

        System.out.println(
                "Number of events: " + workflowExecutionHistory.getHistory().getEventsCount());

I think we need something more to reproduce the issue,

I guess that has to do with some conflict with a transitive dependency you are using in your project.

Hi @antonio.perez
Im able to get the response and log it there is no issue with that. But when Im trying to send as api response WorkflowExecutionHistory, im facing Serialisation error. [WorkflowExecutionHistory] has a field [History] which has → public History getDefaultInstanceForType() {return DEFAULT_INSTANCE;}. Which had a method that returns of type [History]. As there is a circular dependency. It is not able to serialize and throwing an error

@Tallam_Hemanth

If you are trying to serialize the object to a Json, can’t you use the methods WorkflowExecutionHistory. fromJson / toJson ?

Antonio

hi @antonio.perez
then im getting input like below . with encoding and encoded data
eg-

{"eventId":"1","eventTime":"2023-05-31T11:35:27.096097508Z","eventType":"WorkflowExecutionStarted","taskId":"65012204","workflowExecutionStartedEventAttributes":{"workflowType":{"name":"LfaApplicationWorkflow"},"taskQueue":{"name":"applicationTaskQueue","kind":"Normal"},"input":{"payloads":[{"metadata":{"encoding":"anNvbi9wbGFpbg=="},"data":"eyJyZXF1ZXN0SWQiOiJzdHJpbmdhamtidmZiamYiLCJsb2FuQXBwbGljYXRpb25JZCI6IkdDUy1MT0FOLUFQUC1mNzRjOTJiNC02MDRmLTRhZWItYmY4Yy05NWM3ODgwNTgwNjIiLCJ1c2VyQWNjb3VudElkIjoiR0NTMzEzMTgyMTEwMDAwIiwibWVyY2hhbnRDb2RlIjoiR1JPV1ciLCJzY2hlbWVDb2RlIjoiUlBMIiwib2ZmZXJJZCI6IkdDUy1PRkZFUi0wMTAwMDAyNjIwNTA2NDMiLCJsb2FuQW1vdW50IjoxMDAwMDAsInRvdGFsTGluZUxpbWl0Ijo3MDAwMDAsImludGVyZXN0UmF0ZSI6MTUuMjUsInRlbnVyZSI6MTAsImVtaUFtb3VudCI6NTAwMDAsInByb2Nlc3NpbmdGZWUiOjMuMCwidXNlckxvY2F0aW9uIjp7ImxhdGl0dWRlIjoiMTIuOTIwMDg4NyIsImxvbmdpdHVkZSI6Ijc3LjY3MTc3MTQiLCJpc1VzZXJJbkluZGlhIjp0cnVlfSwiY29uc2VudHNMaXN0IjpbeyJpcEFkZHJlc3MiOiIxMC4wLjAuMSIsInRpbWVTdGFtcCI6IjIwMjMtMDMtMjRUMDY6Mzc6MzUuMDxMiIsImFjY291bnRIb2xkZXJOYW1lIjoiU2FoYWphIEtvdnVyaSIsImFjY291bnRUeXBlIjpudWxsLCJtaWNyTnVtYmVyIjpudWxsLCJiYW5rSWQiOm51bGx9LCJtYW5kYXRlQWNjb3VudERldGFpbHMiOnsidW1ybiI6InN0cmluZyJ9fQ=="}]},"workflowExecutionTimeout":"0s","workflowRunTimeout":"0s","workflowTaskTimeout":"10s","originalExecutionRunId":"7fea8f91-b69e-4ba5-87e8-7fbf7330ddd5","identity":"8@orion-orchestrator-deployment-568d86d957-d29pg","firstExecutionRunId":"7fea8f91-b69e-4ba5-87e8-7fbf7330ddd5","attempt":1,"firstWorkflowTaskBackoff":"0s","header":{}}}