Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    OpenAPI support error

    Hi, I was testing the OpenAPI support for the RESTHandler, and I noticed that if a DataSource has two operationBindings for the same operationType, and only one of them has an operationId (so the other is the default):

    Code:
        <operationBindings>
            <operationBinding operationType="fetch"/>
            <operationBinding operationType="fetch" operationId="bar"/>
        </operationBindings>
    invoking the URL:
    isomorphic/RESTHandler/myDS.yaml
    results in the following error:

    Code:
    nov 13, 2025 6:03:53 PM org.apache.catalina.core.StandardWrapperValve invoke
    INFORMAZIONI: 2025-11-13T18:03:53,629 [ ] DEBUG ProcessedFileCache STALE object for file '/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/ds/AUTH_USERS.ds.xml', reloading (file timestamp 1763053102529, cache timestamp 1763053088427)
    2025-11-13T18:03:53,701 [ ] DEBUG cache TemplateLoader.findTemplateSource("AUTH_USERS_it_IT.ftl"): Not found
    2025-11-13T18:03:53,702 [ ] DEBUG cache TemplateLoader.findTemplateSource("AUTH_USERS_it.ftl"): Not found
    2025-11-13T18:03:53,702 [ ] DEBUG cache TemplateLoader.findTemplateSource("AUTH_USERS.ftl"): Not found
    2025-11-13T18:03:53,702 [ ] DEBUG cache "AUTH_USERS.ftl"("it_IT", UTF-8, parsed) no source found.
    2025-11-13T18:03:53,704 [ ] DEBUG cache TemplateLoader.findTemplateSource("datasource_it_IT.ftl"): Not found
    2025-11-13T18:03:53,704 [ ] DEBUG cache TemplateLoader.findTemplateSource("datasource_it.ftl"): Not found
    2025-11-13T18:03:53,705 [ ] DEBUG cache TemplateLoader.findTemplateSource("datasource.ftl"): Found
    2025-11-13T18:03:53,706 [ ] DEBUG cache "datasource.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/datasource.ftl hasn't changed.
    2025-11-13T18:03:53,709 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/parameters_it_IT.ftl"): Not found
    2025-11-13T18:03:53,710 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/parameters_it.ftl"): Not found
    2025-11-13T18:03:53,710 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/parameters.ftl"): Found
    2025-11-13T18:03:53,710 [ ] DEBUG cache "lib/parameters.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/lib/parameters.ftl hasn't changed.
    2025-11-13T18:03:53,712 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/responses_it_IT.ftl"): Not found
    2025-11-13T18:03:53,713 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/responses_it.ftl"): Not found
    2025-11-13T18:03:53,713 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/responses.ftl"): Found
    2025-11-13T18:03:53,713 [ ] DEBUG cache "lib/responses.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/lib/responses.ftl hasn't changed.
    2025-11-13T18:03:53,715 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/datasource-utils_it_IT.ftl"): Not found
    2025-11-13T18:03:53,715 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/datasource-utils_it.ftl"): Not found
    2025-11-13T18:03:53,716 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/datasource-utils.ftl"): Found
    2025-11-13T18:03:53,716 [ ] DEBUG cache "lib/datasource-utils.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/lib/datasource-utils.ftl hasn't changed.
    2025-11-13T18:03:53,717 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/schemas_it_IT.ftl"): Not found
    2025-11-13T18:03:53,718 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/schemas_it.ftl"): Not found
    2025-11-13T18:03:53,718 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/schemas.ftl"): Found
    2025-11-13T18:03:53,718 [ ] DEBUG cache "lib/schemas.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/lib/schemas.ftl hasn't changed.
    2025-11-13T18:03:53,719 [ ] DEBUG cache "lib/datasource-utils.ftl"("it_IT", UTF-8, parsed) cached copy not yet stale; using cached.
    2025-11-13T18:03:53,720 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/simplified-rest_it_IT.ftl"): Not found
    2025-11-13T18:03:53,720 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/simplified-rest_it.ftl"): Not found
    2025-11-13T18:03:53,721 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/simplified-rest.ftl"): Found
    2025-11-13T18:03:53,721 [ ] DEBUG cache "lib/simplified-rest.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/lib/simplified-rest.ftl hasn't changed.
    2025-11-13T18:03:53,721 [ ] DEBUG cache "lib/parameters.ftl"("it_IT", UTF-8, parsed) cached copy not yet stale; using cached.
    2025-11-13T18:03:53,721 [ ] DEBUG cache "lib/datasource-utils.ftl"("it_IT", UTF-8, parsed) cached copy not yet stale; using cached.
    2025-11-13T18:03:53,722 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/simplified-post_it_IT.ftl"): Not found
    2025-11-13T18:03:53,723 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/simplified-post_it.ftl"): Not found
    2025-11-13T18:03:53,723 [ ] DEBUG cache TemplateLoader.findTemplateSource("lib/simplified-post.ftl"): Found
    2025-11-13T18:03:53,723 [ ] DEBUG cache "lib/simplified-post.ftl"("it_IT", UTF-8, parsed): using cached since jar:file:/Users/bosticco/iscSDK/tools/visualBuilder/wsmvn/JcaAuth/target/JcaAuth/WEB-INF/lib/isomorphic-core-rpc-13.1-p20251105.jar!/com/isomorphic/openapi/lib/simplified-post.ftl hasn't changed.
    2025-11-13T18:03:53,724 [ ] DEBUG cache "lib/datasource-utils.ftl"("it_IT", UTF-8, parsed) cached copy not yet stale; using cached.
    2025-11-13T18:03:53,724 [ ] DEBUG cache "lib/parameters.ftl"("it_IT", UTF-8, parsed) cached copy not yet stale; using cached.
    2025-11-13T18:03:53,735 [ ] ERROR RESTHandler Document generation failed. Refer to server logs for detail
    freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
    ==> named.operationId [in template "datasource.ftl" at line 111, column 53]
    
    ----
    Tip: It's the step after the last dot that caused this error, not those before it.
    ----
    Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
    ----
    
    ----
    FTL stack trace ("~" means nesting-related):
        - Failed at: ${named.operationId} [in template "datasource.ftl" at line 111, column 51]
    ----
        at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:481) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:401) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:370) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:100) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.DollarVariable.accept(DollarVariable.java:63) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.Environment.visit(Environment.java:370) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.Environment.visitIteratorBlock(Environment.java:644) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.Environment.visit(Environment.java:334) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.Environment.visit(Environment.java:340) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.core.Environment.process(Environment.java:313) ~[freemarker-2.3.30.jar:2.3.30]
        at freemarker.template.Template.process(Template.java:383) ~[freemarker-2.3.30.jar:2.3.30]
        at com.isomorphic.servlet.RESTHandler.processDocumentationRequest(RESTHandler.java:742) [isomorphic-core-rpc-13.1-p20251105.jar:?]
        at com.isomorphic.servlet.RESTHandler.doGet(RESTHandler.java:494) [isomorphic-core-rpc-13.1-p20251105.jar:?]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [servlet-api.jar:?]
        at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:178) [isomorphic-core-rpc-13.1-p20251105.jar:?]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [servlet-api.jar:?]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.23]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.23]
        at com.juve.utils.Log4j2SessionFilter.doFilter(Log4j2SessionFilter.java:72) [classes/:build 20251110155723]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.23]
        at com.isomorphic.servlet.CompressionFilter._doFilter(CompressionFilter.java:263) [isomorphic-core-rpc-13.1-p20251105.jar:?]
        at com.isomorphic.servlet.BaseFilter.doFilter(BaseFilter.java:91) [isomorphic-core-rpc-13.1-p20251105.jar:?]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.23]
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:209) [spring-security-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.23]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar:5.1.6.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.23]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.23]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:185) [catalina.jar:8.5.23]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:8.5.23]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [catalina.jar:8.5.23]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [catalina.jar:8.5.23]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [catalina.jar:8.5.23]
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) [catalina.jar:8.5.23]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [catalina.jar:8.5.23]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [catalina.jar:8.5.23]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-coyote.jar:8.5.23]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:8.5.23]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-coyote.jar:8.5.23]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-coyote.jar:8.5.23]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:8.5.23]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.5.23]
        at java.lang.Thread.run(Thread.java:829) [?:?]
    Additionally, I noticed that the URL mentioned in the documentation:
    https://www-demos.smartclient.com/sm...s/openapi.html

    returns a blank page.

    #2
    Thanks for the error report. We have now fixed this; the fix will be in all builds from 13.0 onwards, as of tomorrow, November 25th.

    Comment


      #3
      SmartClient Version: v13.1p_2025-12-23/AllModules Development Only (built 2025-12-23)

      Hi, I see that the issue is fixed - thank you very much (but https://www-demos.smartclient.com/sm...s/openapi.html still returns a blank page).

      I also noticed that, with a pair of operationBindings like the following:

      Code:
      <operationBindings>
           <operationBinding operationType="fetch" description="foo"/>
           <operationBinding operationType="fetch" operationId="bar"/>
      </operationBindings>
      both of them appear in the documented POST API calls, plus a third one:

      .../RESTDataSource/myDs/fetch/(unnamed default operation)
      Additionally, I see the calls for the SimplifiedREST protocol listed after those for the AdvancedREST protocol. Is it possible to disable the SimplifiedREST ones?

      Finally, I don’t see the description for the fetch operation reflected in the SimplifiedREST call.

      Comment


        #4
        www-demos is actually meant for private demos, although for some reason, people keep linking it...

        It seems likely you want these docs:

        https://smartclient.com/smartclient-...openapiSupport

        Let us know if that wasn't the thing you wanted.

        We'll get rid of the "foo" / "bar" stuff which was clearly debug code that leaked.

        As far as wanting to disable the SimplifiedREST version, can we ask, why would you care about that? Are you trying to ensure that anyone calling your APIs has a certain level of sophistication? Or perhaps it's a DDOS defence thing?

        Comment


          #5
          Originally posted by Isomorphic View Post
          www-demos is actually meant for private demos, although for some reason, people keep linking it...

          It seems likely you want these docs:

          https://smartclient.com/smartclient-...openapiSupport

          Let us know if that wasn't the thing you wanted.
          Thanks for the heads up - I’ve updated my bookmark accordingly.
          However, the following link, which is mentioned at the bottom of the OpenAPI documentation, still returns a blank page:
          https://smartclient.com/smartclient-...s/openapi.html

          Originally posted by Isomorphic View Post

          We'll get rid of the "foo" / "bar" stuff which was clearly debug code that leaked.

          As far as wanting to disable the SimplifiedREST version, can we ask, why would you care about that? Are you trying to ensure that anyone calling your APIs has a certain level of sophistication? Or perhaps it's a DDOS defence thing?
          Regarding the SimplifiedREST APIs: yes, my thinking was that in some scenarios I might want to require callers to use only the AdvancedREST protocol.

          I’m also not sure I explained the other issue clearly. With a test case like the one from my first post - which previously triggered the error:
          Code:
          <operationBindings>
               <operationBinding operationType="fetch" description="foo"/>
               <operationBinding operationType="fetch" operationId="bar"/>
          </operationBindings>
          I now see the two expected calls correctly documented, plus a third one with “(unnamed default operation)” appended to the URL:
          [cut]/RESTDataSource/myDs/fetch/(unnamed default operation)
          Additionally, I don’t see the "foo" description (which I added to the default fetch operation) reflected in the SimplifiedREST section of the generated documentation.



          Comment

          Working...
          X