Announcement

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

    [bug] RESTHandler delivers dates as local time instead of UTC

    SmartClient Version: v9.1p_2014-06-25/PowerEdition Deployment (built 2014-06-25)
    and
    SmartClient Version: v9.1p_2014-07-15/PowerEdition Deployment (built 2014-07-15)

    delivers "2015-05-24T15:00:00.000" which is 'local' time

    instead this 9.0 build was working correctly:
    SmartClient Version: v9.0p_2014-05-20/PowerEdition Deployment (built 2014-05-20)
    and delivers "2015-05-24T13:00:00" (we are GMT+02:00)

    #2
    We're not seeing this and we have automated tests verifying the output is as expected. Most likely what's happening for you is that the data is actually delivered to the SmartClient server framework with the wrong value, has the wrong value in the DB, or field declarations are wrong (eg wrong type).

    If you think there's a bug here, you should put together a minimal, standalone test case that we can run to see the problem.

    Comment


      #3
      ok, I'll double check this, but I've done my test using the same database (and data) and the same application, I've only swapped the SmartClient version.

      Actually, I've re-deployed the application in production with SmartClient 9.0 instead of 9.1 and the problem is fixed.
      Last edited by claudiobosticco; 30 Jul 2014, 12:07.

      Comment


        #4
        And yet still, we see expected behavior in our tests (across both versions).

        It may be that you've got some weird usage that happened to be OK in 9.0 and isn't in 9.1, or the application code is wrong but is offset by an undiscovered framework bug in 9.0.. in any case, we need a test case to look further.

        Comment


          #5
          Edit: please, before this long post, read my last post, where I wrote that the bug shows only for defaultDataFormat=json

          -------------------------------------------------------------

          Hello, the test case is really minimal.

          Our database (installed on Windows 2008 server) is:
          Code:
          Database: Oracle/Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
          Driver name: Oracle JDBC driver
          Driver version: 11.2.0.3.0
          JDBC version: 11.2
          Case sensitivity: UPPER (quoted: EXACT)
          I've done this test using SmartClient Version: v9.1p_2014-07-30/PowerEdition Deployment (built 2014-07-30)
          with tomcat 7.0.32 and jdk1.7.0_60.jdk on MAC OSX.

          create this table:
          Code:
          CREATE TABLE DATE_REST_TEST
          (
              ID_REC INTEGER PRIMARY KEY NOT NULL,
              DATA_INIZIO DATE NOT NULL
          );
          insert one record:
          Code:
          SET SQLBLANKLINES ON;
          SET DEFINE OFF;
          ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/SYYYY HH24:MI:SS';
          ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'MM/DD/SYYYY HH24:MI:SS.FF TZH:TZM';
          ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'MM/DD/SYYYY HH24:MI:SS.FF';
          ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,';
          ALTER SESSION SET NLS_NCHAR_CONV_EXCP = FALSE;
          ALTER SESSION SET TIME_ZONE = '+02:00';
          
          INSERT INTO DBSALES.DATE_REST_TEST(ID_REC, DATA_INIZIO) VALUES (725762, '01/23/2015 15:00:00');
          
          COMMIT;
          the DATE_REST_TEST.ds.xml:
          Code:
          <DataSource xmlns="http://www.smartclient.com/schema"
                      ID="DATE_REST_TEST"
                      tableName="DATE_REST_TEST"
                      schema="DBSALES"
                      dbName="dbJpcEP"
                      serverType="sql"
                      requiresAuthentication="false"
                  >
              <fields>
                  <field sqlType="decimal" primaryKey="true" name="ID_REC" type="sequence" hidden="true" sequenceName="SEQUENCE_ID_REC"/>
                  <field name="DATA_INIZIO" type="datetime"/>
              </fields>
          </DataSource>
          the RESTHandler configuration in web.xml:
          Code:
              <servlet>
                  <init-param>
                      <param-name>wrapJSONResponses</param-name>
                      <param-value>true</param-value>
                  </init-param>
                  <init-param>
                      <param-name>defaultDataFormat</param-name>
                      <param-value>json</param-value>
                  </init-param>
                <servlet-name>RESTHandler</servlet-name>
                <servlet-class>com.isomorphic.servlet.RESTHandler</servlet-class>
              </servlet>
              <servlet-mapping>
                  <servlet-name>RESTHandler</servlet-name>
                  <url-pattern>/isomorphic/RESTHandler/*</url-pattern>
            </servlet-mapping>
          complete web.xml:
          Code:
          <?xml version="1.0" encoding="UTF-8"?>
          <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
                   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
                   id="IMA" version="3.0">
              <display-name>IMA</display-name>
              <context-param>
                  <param-name>log4jConfigLocation</param-name>
                  <param-value>/WEB-INF/classes/log4j.isc.config.xml</param-value>
              </context-param>
              <context-param>
                  <param-name>log4jExposeWebAppRoot</param-name>
                  <param-value>false</param-value>
              </context-param>
              <context-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>
                      /WEB-INF/applicationContext.xml
                      /WEB-INF/Ldap.xml
                      classpath:com/juve/i18n/i18nContext.xml
                      classpath:com/juve/admin/adminContext.xml
                      classpath:com/juve/ima/dmi/ima_spring.xml
              </param-value>
            </context-param>
            <filter>
              <filter-name>CAS_SingleSignOutFilter</filter-name>
              <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
              <init-param>
                <param-name>artifactParameterName</param-name>
                <param-value>SAMLart</param-value>
              </init-param>
            </filter>
              <filter>
                  <filter-name>charsetFilter</filter-name>
                  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
                  <init-param>
                      <param-name>encoding</param-name>
                      <param-value>UTF-8</param-value>
                  </init-param>
              </filter>
              <filter>
              <filter-name>JSSyntaxScannerFilter</filter-name>
              <filter-class>com.isomorphic.js.JSSyntaxScannerFilter</filter-class>
            </filter>
            <filter>
              <filter-name>CompressionFilter</filter-name>
              <filter-class>com.isomorphic.servlet.CompressionFilter</filter-class>
            </filter>
            <filter>
              <filter-name>springSecurityFilterChain</filter-name>
              <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            </filter>
              <filter>
                  <filter-name>log4jSessionFilter</filter-name>
                  <filter-class>com.juve.utils.Log4jSessionFilter</filter-class>
              </filter>
              <filter-mapping>
                  <filter-name>charsetFilter</filter-name>
                  <url-pattern>/*</url-pattern>
              </filter-mapping>
              <filter-mapping>
              <filter-name>CAS_SingleSignOutFilter</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
            <filter-mapping>
              <filter-name>JSSyntaxScannerFilter</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
            <filter-mapping>
              <filter-name>CompressionFilter</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
            <filter-mapping>
              <filter-name>springSecurityFilterChain</filter-name>
              <url-pattern>/*</url-pattern>
            </filter-mapping>
              <filter-mapping>
                  <filter-name>log4jSessionFilter</filter-name>
                  <url-pattern>/*</url-pattern>
              </filter-mapping>
            <listener>
                       <listener-class>com.isomorphic.base.InitListener</listener-class>
                   </listener>
            <listener>
              <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
            </listener>
            <listener>
              <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
            </listener>
            <listener>
              <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
            </listener>
            <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>
            <listener>
              <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
            </listener>
              <servlet>
                    <display-name>RestRequest</display-name>
                    <servlet-name>RestRequest</servlet-name>
                    <servlet-class>com.juve.ima.rest.RestRequest</servlet-class>
                </servlet>
                <servlet-mapping>
                    <servlet-name>RestRequest</servlet-name>
                    <url-pattern>/isomorphic/RestRequest/*</url-pattern>
                </servlet-mapping>
            <servlet>
              <servlet-name>IDACall</servlet-name>
              <servlet-class>com.isomorphic.servlet.IDACall</servlet-class>
            </servlet>
              <servlet>
                  <init-param>
                      <param-name>wrapJSONResponses</param-name>
                      <param-value>true</param-value>
                  </init-param>
                  <init-param>
                      <param-name>defaultDataFormat</param-name>
                      <param-value>json</param-value>
                  </init-param>
                <servlet-name>RESTHandler</servlet-name>
                <servlet-class>com.isomorphic.servlet.RESTHandler</servlet-class>
              </servlet>
              <servlet>
              <servlet-name>FileDownload</servlet-name>
              <servlet-class>com.isomorphic.servlet.FileDownload</servlet-class>
              <init-param>
                <param-name>expires</param-name>
                      <param-value>
                          text/javascript:31104000,image/gif:31104000,image/png:31104000,image/jpeg:31104000,image/x-icon:31104000,text/css:31104000
                      </param-value>
              </init-param>
            </servlet>
            <servlet>
              <servlet-name>FileAssemblyJuveModule</servlet-name>
              <servlet-class>com.isomorphic.servlet.FileAssembly</servlet-class>
              <init-param>
                    <param-name>configFile</param-name>
                    <param-value>
                        /WEB-INF/classes/assembly.juveModule.xml
                    </param-value>
                  </init-param>
            </servlet>
              <servlet>
              <servlet-name>FileAssembly</servlet-name>
              <servlet-class>com.isomorphic.servlet.FileAssembly</servlet-class>
              <init-param>
                    <param-name>configFile</param-name>
                    <param-value>
                        /WEB-INF/classes/assembly.xml
                    </param-value>
                  </init-param>
            </servlet>
              <servlet>
                  <servlet-name>RealPath</servlet-name>
                  <servlet-class>com.juve.utils.RealPath</servlet-class>
                  <load-on-startup>2</load-on-startup>
              </servlet>
              <servlet>
              <servlet-name>HttpProxy</servlet-name>
              <servlet-class>com.isomorphic.servlet.HttpProxyServlet</servlet-class>
            </servlet>
              <servlet>
                  <display-name>Apache-Axis Servlet</display-name>
                  <servlet-name>AxisServlet</servlet-name>
                  <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
              </servlet>
              <servlet>
                  <display-name>Axis Admin Servlet</display-name>
                  <servlet-name>AdminServlet</servlet-name>
                  <servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
                  <load-on-startup>100</load-on-startup>
              </servlet>
              <!-- //>RealtimeMessaging -->
              <!-- The MessagingServlet is used by realtime messaging -->
              <servlet>
                  <servlet-name>MessagingServlet</servlet-name>
                  <servlet-class>com.isomorphic.messaging.MessagingServlet</servlet-class>
              </servlet>
              <!-- //<RealtimeMessaging -->
              <servlet-mapping>
                  <servlet-name>AxisServlet</servlet-name>
                  <url-pattern>/servlet/AxisServlet</url-pattern>
              </servlet-mapping>
              <servlet-mapping>
                  <servlet-name>AxisServlet</servlet-name>
                  <url-pattern>*.jws</url-pattern>
              </servlet-mapping>
              <servlet-mapping>
                  <servlet-name>AxisServlet</servlet-name>
                  <url-pattern>/services/*</url-pattern>
              </servlet-mapping>
              <servlet-mapping>
                  <servlet-name>AdminServlet</servlet-name>
                  <url-pattern>/servlet/AdminServlet</url-pattern>
              </servlet-mapping>
              <servlet-mapping>
              <servlet-name>FileAssemblyJuveModule</servlet-name>
              <url-pattern>/init.js</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileAssemblyJuveModule</servlet-name>
              <url-pattern>/roleAdmin.js</url-pattern>
            </servlet-mapping>
              <servlet-mapping>
              <servlet-name>FileAssembly</servlet-name>
              <url-pattern>/everyRole.js</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>IDACall</servlet-name>
              <url-pattern>/isomorphic/IDACall/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>IDACall</servlet-name>
              <url-pattern>/isomorphic/IDACall.aspx/*</url-pattern>
            </servlet-mapping>
              <servlet-mapping>
                  <servlet-name>RESTHandler</servlet-name>
                  <url-pattern>/isomorphic/RESTHandler/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>HttpProxy</servlet-name>
              <url-pattern>/isomorphic/HttpProxy/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileDownload</servlet-name>
              <url-pattern>/isomorphic/skins/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileDownload</servlet-name>
              <url-pattern>/isomorphic/locales/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileDownload</servlet-name>
              <url-pattern>/isomorphic/system/modules/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileDownload</servlet-name>
              <url-pattern>/isomorphic/system/development/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileDownload</servlet-name>
              <url-pattern>/shared/ui/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
              <servlet-name>FileDownload</servlet-name>
              <url-pattern>/images/*</url-pattern>
            </servlet-mapping>
            <session-config>
              <session-timeout>300</session-timeout>
            </session-config>
            <jsp-config>
              <taglib>
                <taglib-uri>isomorphic</taglib-uri>
                <taglib-location>/WEB-INF/iscTaglib.xml</taglib-location>
              </taglib>
              <taglib>
                <taglib-uri>fmt</taglib-uri>
                <taglib-location>/WEB-INF/fmt.tld</taglib-location>
              </taglib>
                  <jsp-property-group>
                      <url-pattern>*.isc</url-pattern>
                      <include-prelude>/shared/jsp/iscHeader.jsp</include-prelude>
                      <include-coda>/shared/jsp/iscFooter.jsp</include-coda>
                  </jsp-property-group>
                  <jsp-property-group>
                      <url-pattern>*.rpc</url-pattern>
                      <include-prelude>/shared/jsp/rpcHeader.jsp</include-prelude>
                      <include-coda>/shared/jsp/rpcFooter.jsp</include-coda>
                  </jsp-property-group>
              <jsp-property-group>
                  <url-pattern>*.xml</url-pattern>
                  <page-encoding>UTF-8</page-encoding>
              </jsp-property-group>
            </jsp-config>
            <mime-mapping>
              <extension>manifest</extension>
              <mime-type>text/cache-manifest</mime-type>
              </mime-mapping>
              <mime-mapping>
                  <extension>wsdl</extension>
                  <mime-type>text/xml</mime-type>
            </mime-mapping>
            <welcome-file-list>
              <welcome-file>index.jsp</welcome-file>
            </welcome-file-list>
          </web-app>
          then I'm invoking it with this URL in the browser (chrome):
          http://localhost:8082/IMA/isomorphic...DATE_REST_TEST

          and this is the response
          Code:
          <SCRIPT>//'"]]>>isc_JSONResponseStart>>{"response":{"affectedRows":0,"data":[{"ID_REC":725762,"DATA_INIZIO":"2015-01-23T15:00:00.000"}],"endRow":1,"invalidateCache":false,"isDSResponse":true,"operationType":"fetch","queueStatus":0,"startRow":0,"status":0,"totalRows":1}}//isc_JSONResponseEnd
          which is wrong because at that date we'll be GMT+01
          NOTE: it also contains the millisecond part (.000)

          server logs:
          Code:
          2014-07-31 11:34:25,291 DEBUG RESTHandler Wrapping json responses:true 
          2014-07-31 11:34:25,293 DEBUG RESTHandler json prefix:null 
          2014-07-31 11:34:25,293 DEBUG RESTHandler json suffix:null 
          2014-07-31 11:34:25,293 DEBUG RESTHandler Default response data format:json 
          2014-07-31 11:34:25,316 INFO  DataTools setProperties: couldn't set:
          {
              defaultDataFormat:"No such property",
              wrapJSONResponses:"No such property"
          } 
          2014-07-31 11:34:25,344 INFO  RequestContext URL: '/IMA/isomorphic/RESTHandler', User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36': Safari with Accept-Encoding header 
          2014-07-31 11:34:25,355 DEBUG FilterChainProxy Converted URL to lowercase, from: '/isomorphic/resthandler'; to: '/isomorphic/resthandler' 
          2014-07-31 11:34:25,356 DEBUG FilterChainProxy Candidate is: '/isomorphic/resthandler'; pattern is /images/*; matched=false 
          2014-07-31 11:34:25,356 DEBUG FilterChainProxy Converted URL to lowercase, from: '/isomorphic/resthandler'; to: '/isomorphic/resthandler' 
          2014-07-31 11:34:25,356 DEBUG FilterChainProxy Candidate is: '/isomorphic/resthandler'; pattern is /isomorphic/resthandler*; matched=true 
          2014-07-31 11:34:25,356 DEBUG FilterChainProxy /isomorphic/RESTHandler?_operationType=fetch&_dataSource=DATE_REST_TEST has an empty filter list 
          2014-07-31 11:34:25,405 DEBUG RestRequestParser Parameter:'_operationType'. Value:'fetch'. 
          2014-07-31 11:34:25,406 DEBUG RestRequestParser Parameter:'_dataSource'. Value:'DATE_REST_TEST'. 
          2014-07-31 11:34:25,533 INFO  PoolManager SmartClient pooling started for 'simpleTypes' objects 
          2014-07-31 11:34:25,864 INFO  RESTHandler Performing 1 operation(s) 
          2014-07-31 11:34:25,897 INFO  SQLWhereClause [builtinApplication.DATE_REST_TEST_fetch] empty condition 
          2014-07-31 11:34:26,078 INFO  PoolManager [builtinApplication.DATE_REST_TEST_fetch] SmartClient pooling disabled for 'dbJpcEP' objects 
          2014-07-31 11:34:26,496 INFO  SQLDriver [builtinApplication.DATE_REST_TEST_fetch] Executing SQL query on 'dbJpcEP': SELECT DATE_REST_TEST.ID_REC, DATE_REST_TEST.DATA_INIZIO FROM DBSALES.DATE_REST_TEST WHERE ('1'='1') 
          2014-07-31 11:34:26,504 INFO  DSResponse [builtinApplication.DATE_REST_TEST_fetch] DSResponse: List with 1 items 
          2014-07-31 11:34:26,505 DEBUG RPCManager Content type for RPC transaction: text/html; charset=UTF-8 
          2014-07-31 11:34:26,506 DEBUG RPCManager non-DMI response, dropExtraFields: false 
          2014-07-31 11:34:26,520 INFO  Compression /IMA/isomorphic/RESTHandler: 291 -> 234 bytes
          simply switching to SmartClient Version: v9.0p_2014-05-20/PowerEdition Deployment (built 2014-05-20)
          or SmartClient Version: v9.0p_2014-07-27/PowerEdition Deployment (built 2014-07-27)
          fixes the problem.

          Please let me know if you need more details.
          Last edited by claudiobosticco; 31 Jul 2014, 07:48.

          Comment


            #6
            I just discovered that the bug shows only for defaultDataFormat=json

            with defaultDataFormat=xml it works

            I need absolutely to use json, could you please fix it?
            Any workarounds available?

            ps: I've also noticed that the 'datetime' fields, in the response returned by handleDSRequest of RESTHandler, are of type java.sql.Timestamp. Is this correct?
            Last edited by claudiobosticco; 31 Jul 2014, 06:56.

            Comment


              #7
              OK, we see this problem and have corrected it. Please try your use case with tomorrow's 9.1p or 10.0d build

              Comment


                #8
                SmartClient Version: v9.1p_2014-08-24/PowerEdition Deployment (built 2014-08-24)

                verified, thank you very much

                Comment

                Working...
                X