Announcement

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

    Relogin timeout

    Hi,

    I am using your relogin guide here: https://isomorphic.atlassian.net/wik...mcat+JDBCRealm and it basically works.
    But I am getting some strange timeouts on the loginSuccessMarker.html request.

    I see the following:
    Code:
    Request URL:
    http://localhost:8080/kids-dev/loginSuccessMarker.html?isc_rpc=1&isc_v=v11.1p_2017-12-27&isc_xhr=1
    Request Method:
    POST
    Status Code:
    200 OK
    Remote Address:
    [::1]:8080
    Referrer Policy:
    no-referrer-when-downgrade
    so you see it has status 200. Successful. I also see the loginSuccessMarker HTML in the response. So it seems to arrive correctly.

    Nevertheless, in the SmartGWT console I see the RPC request to loginSuccessMarker waiting.
    The request:
    Code:
    {
        "actionURL":"loginSuccessMarker.html", 
        "showPrompt":false, 
        "transport":"xmlHttpRequest", 
        "promptStyle":"cursor"
    }
    This request has status "N/A" at first. After some time, it gets the status "SERVER_TIMEOUT" and I get an error in the UI. Here a screenshot of the status. It still has status 200, but SERVER_TIMEOUT. Why is this happening ?
    Using smartgwt 6.1p 20180203 power.
    Click image for larger version

Name:	Bildschirmfoto 2018-02-04 um 00.31.49.png
Views:	508
Size:	64.7 KB
ID:	251568

    #2
    There are multiple ways to configure relogin, which have you done? The stock reloginFlow.js file we provide sends credentials to the loginSuccessMarker.html file as a means of logging back in. Perhaps you changed the approach but you still have this request happening unnecessarily.

    Note: it definitely doesn't make sense that you end up with a request which appears to have received a 200 response but still times out, but we can't see how that could happen and we're not reproducing that in the standard flow.

    Comment


      #3
      Hi edulid,

      I have been thinking of a German SmartGWT / SmartClient users group (most likely online-only for now) for a long time.
      From your screenshots in the forums I get you are from the DACH region.
      Would you mind connecting me on LinkedIn/Xing?

      Best regards
      Salek Talangi

      Comment


        #4
        Hi,

        I isolated this issue for a testcase. Now I am only using standard smartgwt components in a minimal example and the issue is still there.
        My relogin is based on this relogin: https://isomorphic.atlassian.net/wik...mcat+JDBCRealm

        TestingModule.java
        Code:
        package org.infofabrik.kids.client.test;
        
        import java.util.HashMap;
        
        import java.util.Map;
        
        import org.infofabrik.kids.client.KidsIcons;
        
        
        
        
        import com.google.gwt.core.client.EntryPoint;
        
        import com.smartgwt.client.rpc.LoginRequiredCallback;
        
        import com.smartgwt.client.rpc.RPCCallback;
        
        import com.smartgwt.client.rpc.RPCManager;
        
        import com.smartgwt.client.rpc.RPCRequest;
        
        import com.smartgwt.client.rpc.RPCResponse;
        
        import com.smartgwt.client.types.Alignment;
        
        import com.smartgwt.client.util.SC;
        
        import com.smartgwt.client.widgets.IButton;
        
        import com.smartgwt.client.widgets.Label;
        
        import com.smartgwt.client.widgets.Window;
        
        import com.smartgwt.client.widgets.events.ClickEvent;
        
        import com.smartgwt.client.widgets.events.ClickHandler;
        
        import com.smartgwt.client.widgets.form.DynamicForm;
        
        import com.smartgwt.client.widgets.form.fields.PasswordItem;
        
        import com.smartgwt.client.widgets.form.fields.TextItem;
        
        import com.smartgwt.client.widgets.grid.ListGrid;
        
        import com.smartgwt.client.widgets.grid.ListGridField;
        
        import com.smartgwt.client.widgets.layout.HLayout;
        
        import com.smartgwt.client.widgets.layout.VLayout;
        
        
        
        
        public class TestingModule implements EntryPoint {
        
        
        
        
        private Window windowRelogin = new Window();
        
        private DynamicForm formLogin;
        
        private TextItem login;
        
        
        
        
        @Override
        
        public void onModuleLoad() {
        
        
        
        
        setupRelogin();
        
        
        
        
        final VLayout vlayout = new VLayout(10);
        
        vlayout.setWidth(300);
        
        
        
        
        Label loggedInLabel = new Label("Logged in");
        
        
        
        
        vlayout.addMember(loggedInLabel);
        
        
        
        loggedInLabel.setHeight(20);
        
        
        
        
        final ListGrid lg = new ListGrid();
        
        ListGridField nameField = new ListGridField("f_name");
        
        lg.setAutoFetchData(false);
        
        lg.setDataSource("simpleTable");
        
        lg.setFields(nameField);
        
        lg.setHeight(400);
        
        
        
        
        vlayout.addMember(lg);
        
        
        
        vlayout.draw();
        
        
        
        lg.fetchData();
        
        }
        
        
        
        
        private void setupRelogin() {
        
        windowRelogin = new Window();
        
        windowRelogin.setAutoCenter(true);
        
        windowRelogin.setTitle("relogin");
        
        windowRelogin.setShowCloseButton(false);
        
        windowRelogin.setShowMinimizeButton(false);
        
        windowRelogin.setShowMaximizeButton(false);
        
        windowRelogin.setWidth(370);
        
        windowRelogin.setIsModal(true);
        
        windowRelogin.setShowModalMask(true);
        
        windowRelogin.setHeight(190);
        
        
        
        
        VLayout vlayout = new VLayout(10);
        
        Label lMsg = new Label("login time out");
        
        lMsg.setWidth100();
        
        lMsg.setHeight(20);
        
        
        
        
        vlayout.setPadding(10);
        
        
        
        
        formLogin = new DynamicForm();
        
        formLogin.setAlign(Alignment.CENTER);
        
        formLogin.setIsGroup(false);
        
        
        
        
        login = new TextItem();
        
        login.setTitle("username");
        
        login.setName("j_username");
        
        
        
        
        PasswordItem password = new PasswordItem();
        
        password.setTitle("password");
        
        password.setName("j_password");
        
        password.setRequired(true);
        
        IButton loginButton = new IButton();
        
        loginButton.setTitle("login");
        
        loginButton.setIcon(KidsIcons.OK.getFilename());
        
        loginButton.setWidth(100);
        
        loginButton.addClickHandler(new ClickHandler() {
        
        
        
        
        @Override
        
        public void onClick(ClickEvent event) {
        
        if (!formLogin.validate())
        
        return;
        
        
        
        
        RPCRequest request = new RPCRequest();
        
        request.setActionURL("loginSuccessMarker.html");
        
        RPCManager.sendRequest(request);
        
        
        
        
        validateRelogin(formLogin.getValueAsString("j_username"), formLogin.getValueAsString("j_password"));
        
        }
        
        });
        
        
        
        
        HLayout buttonsLayout = new HLayout(5);
        
        buttonsLayout.addMember(loginButton);
        
        
        
        
        formLogin.setFields(login, password);
        
        vlayout.addMember(lMsg);
        
        vlayout.addMember(formLogin);
        
        vlayout.addMember(buttonsLayout);
        
        
        
        
        windowRelogin.addItem(vlayout);
        
        
        
        
        // setup Relogin
        
        RPCManager.setLoginRequiredCallback(new LoginRequiredCallback() {
        
        
        
        
        @Override
        
        public void loginRequired(int transactionNum, RPCRequest request, RPCResponse response) {
        
        if ((!windowRelogin.isDrawn()) || (!windowRelogin.isVisible())) {
        
        formLogin.clearValues();
        
        windowRelogin.redraw();
        
        windowRelogin.show();
        
        formLogin.focusInItem("j_username");
        
        }
        
        }
        
        });
        
        }
        
        
        
        
        public void validateRelogin(String j_username, String j_password) {
        
        RPCRequest request = new RPCRequest();
        
        request.setContainsCredentials(true);
        
        request.setActionURL("j_security_check");
        
        request.setUseSimpleHttp(true);
        
        request.setShowPrompt(false);
        
        Map<String, String>params = new HashMap<String, String>();
        
        params.put("j_username", j_username);
        
        params.put("j_password", j_password);
        
        request.setParams(params);
        
        RPCManager.sendRequest(request, new RPCCallback() {
        
        @Override
        
        public void execute(RPCResponse response, Object rawData, RPCRequest request) {
        
        windowRelogin.hide();
        
        String data = String.valueOf(rawData);
        
        if (data.contains("error")) {
        
        formLogin.clearValues();
        
        windowRelogin.redraw();
        
        windowRelogin.show();
        
        formLogin.focusInItem("j_username");
        
        SC.say("Your login information was not correct, try again");
        
        } else {
        
        RPCManager.resendTransaction();
        
        }
        
        }
        
        });
        
        }
        
        
        
        
        }
        myapp.gwt.xml
        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        
        <module rename-to='myapp'>
        
        
        
        
        <inherits name="com.smartgwtee.SmartGwtEENoScript" />
        
        <inherits
        
        name="com.smartclient.theme.enterpriseblue.EnterpriseBlueResources" />
        
        <inherits name="com.smartgwt.RealtimeMessagingNoScript"/>
        
        
        
        <!-- Other module inherits -->
        
        <inherits name="com.google.gwt.resources.Resources" />
        
        
        
        
        <entry-point class='org.infofabrik.kids.client.test.TestingModule'
        
        />
        
        
        
        
        <!-- Specify the paths for translatable code -->
        
        <source path='client' />
        
        <source path='shared' />
        
        
        
        
        <!-- Set user agents -->
        
        <set-property name="user.agent" value="gecko1_8,safari,ie9" />
        
        
        
        
        <!-- Locale. -->
        
        <extend-property name="locale" values="de" />
        
        <extend-property name="locale" values="en" />
        
        
        
        
        <set-property-fallback name="locale" value="de" />
        
        <set-configuration-property name="locale.cookie"
        
        value="GWT_LOCALE" />
        
        
        
        
        <!-- SuperDev Mode -->
        
        <add-linker name="xsiframe" />
        
        <set-configuration-property name="devModeRedirectEnabled"
        
        value="true" />
        
        <!-- enable source maps -->
        
        <set-property name="compiler.useSourceMaps" value="true" />
        
        
        
        
        </module>
        web.xml
        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        
        <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        
        version="3.0">
        
        
        
        
        
        
        
        <welcome-file-list>
        
        <welcome-file>myapp.html</welcome-file>
        
        </welcome-file-list>
        
        
        
        <!-- ISC init: initializes ISC framework -->
        
            <servlet>
        
                <servlet-name>Init</servlet-name>
        
                <servlet-class>com.isomorphic.base.Init</servlet-class>
        
                <load-on-startup>1</load-on-startup>
        
            </servlet>
        
        
        
        <servlet>
        
                <servlet-name>DataSourceLoader</servlet-name>
        
                <servlet-class>com.isomorphic.servlet.DataSourceLoader</servlet-class>
        
            </servlet>  
        
        
        
            <servlet-mapping>
        
                <servlet-name>DataSourceLoader</servlet-name>
        
                <url-pattern>/myapp/sc/DataSourceLoader</url-pattern>
        
            </servlet-mapping>
        
        
        
             <!-- The IDACall servlet handles all Built-in DataSource operations -->
        
            <servlet>
        
                <servlet-name>IDACall</servlet-name>
        
                <servlet-class>com.isomorphic.servlet.IDACall</servlet-class>
        
            </servlet>
        
        
        
             <!-- RPCManager uses this URL by default for Built-in DataSource operations -->
        
            <servlet-mapping>
        
                <servlet-name>IDACall</servlet-name>
        
                <url-pattern>/myapp/sc/IDACall/*</url-pattern>
        
            </servlet-mapping>
        
        
        
            <!-- The FileDownload servlet downloads static files, like a webserver -->
        
            <servlet>
        
                <servlet-name>FileDownload</servlet-name>
        
                <servlet-class>com.isomorphic.servlet.FileDownload</servlet-class>
        
            </servlet>
        
        
        
        
            <servlet>
        
                <servlet-name>HttpProxy</servlet-name>
        
                <servlet-class>com.isomorphic.servlet.HttpProxyServlet</servlet-class>
        
            </servlet>
        
        
        
            <servlet-mapping>
        
                <servlet-name>HttpProxy</servlet-name>
        
                <url-pattern>/myapp/sc/HttpProxy/*</url-pattern>
        
            </servlet-mapping>
        
        
        
            <!-- Use FileDownload servlet to download all static content that's part of the skin, such as
        
                 image files, so we can set Expires headers and other cache control directives.  In a
        
                 production deployment, you'd want to use a webserver such as Apache to do this.  
        
            -->
        
            <servlet-mapping>
        
                <servlet-name>FileDownload</servlet-name>
        
                <url-pattern>/myapp/sc/skins/*</url-pattern>
        
            </servlet-mapping>
        
        
        
        
            <!-- serve ISC modules compressed, with expires headers -->
        
            <servlet-mapping>
        
                <servlet-name>FileDownload</servlet-name>
        
                <url-pattern>/myapp/sc/system/modules/*</url-pattern>
        
            </servlet-mapping>
        
        
        
        
            <!-- serve ISC development modules compressed, with expires headers -->
        
            <servlet-mapping>
        
                <servlet-name>FileDownload</servlet-name>
        
                <url-pattern>/myapp/sc/system/development/*</url-pattern>
        
            </servlet-mapping>
        
        
        
        
            <!-- server skin assets with expires headers -->
        
            <servlet-mapping>
        
                <servlet-name>FileDownload</servlet-name>
        
                <url-pattern>/myapp/sc/system/reference/skin/*</url-pattern>
        
            </servlet-mapping>
        
        
        
        
        <!-- The PreCache servlet initializes when the servlet engine starts up
        
        and pre-loads data need for all client requests. This is optional, and improves
        
        performance of the first few page requests. PreCache cannot be invoked by
        
        a browser, because there is no "servlet-mapping" defined for it. -->
        
        <servlet>
        
        <servlet-name>PreCache</servlet-name>
        
        <servlet-class>com.isomorphic.servlet.PreCache</servlet-class>
        
        <load-on-startup>2</load-on-startup>
        
        </servlet>
        
        
        
        
        <!-- General config -->
        
        <session-config>
        
        <session-timeout>1</session-timeout>
        
        </session-config>
        
        
        
        
        <jsp-config>
        
        <!-- Isomorphic JSP tags -->
        
        <taglib>
        
        <taglib-uri>isomorphic</taglib-uri>
        
        <taglib-location>/WEB-INF/classes/iscTaglib.xml</taglib-location>
        
        </taglib>
        
        </jsp-config>
        
        
        
        
        <mime-mapping>
        
        <extension>manifest</extension>
        
        <mime-type>text/cache-manifest</mime-type>
        
        </mime-mapping>
        
        
        
        <security-constraint>
        
            <web-resource-collection>
        
                <web-resource-name>no-auth</web-resource-name>
        
                <url-pattern>/myapp/sc/system/helpers/Log.html</url-pattern>
        
            </web-resource-collection>
        
            <!-- OMIT auth-constraint -->
        
        </security-constraint>
        
        
        
        
        <security-constraint>
        
        <web-resource-collection>
        
        <web-resource-name>my web resource</web-resource-name>
        
        <url-pattern>/myapp/sc/IDACall/*</url-pattern>
        
        <url-pattern>/myapp.html</url-pattern>
        
        <http-method>GET</http-method>
        
        <http-method>POST</http-method>
        
        </web-resource-collection>
        
        <auth-constraint>
        
        <role-name>MYROLE</role-name>
        
        </auth-constraint>
        
        
        
        
        </security-constraint>
        
        
        
        
        <login-config>
        
        <auth-method>FORM</auth-method>
        
        <realm-name>User Auth</realm-name>
        
        
        
        
        <form-login-config>
        
        <form-login-page>/login.html</form-login-page>
        
        <form-error-page>/autherr.html</form-error-page>
        
        </form-login-config>
        
        
        
        
        </login-config>
        
        
        
        
        <security-role>
        
        <role-name>MYROLE</role-name>
        
        </security-role>
        
        
        
        
        </web-app>
        myapp.html
        Code:
        <!DOCTYPE html>
        
        <html>
        
          <head>
        
        
        
            <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        
        
        
        
            <title>my app</title>
        
        
        
            <script>isc_css3Mode = "on";</script>
        
        
        
        <!-- You must set the variable isomorphicDir to [MODULE_NAME]/sc/ -->
        
        <!-- so that the SmartGWT resources are correctly resolved        -->
        
        <script> var isomorphicDir = "myapp/sc/"; </script>
        
        
        
            <script type="text/javascript" language="javascript"
        
                src="myapp/myapp.nocache.js"></script>
        
        
        
        <script type="text/javascript" language="javascript" src="myapp/sc/initsc.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_Core.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_Foundation.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_Containers.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_Grids.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_Forms.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_RichTextEditor.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_Calendar.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/modules/ISC_DataBinding.js"></script>
        
        <script type="text/javascript" language="javascript" src="myapp/sc/skins/EnterpriseBlue/load_skin.js"></script>
        
        
        
          </head>
        
          <body>
        
          <script src="myapp/sc/DataSourceLoader?dataSource=simpleTable"></script>
        
            <!-- OPTIONAL: include this if you want history support -->
        
            <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
        
                style="position:absolute;width:0;height:0;border:0"></iframe>
        
        
        
            <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
        
            <noscript>
        
              <div>
        
                You need javascript
        
              </div>
        
            </noscript>
        
        
        
        
        
        
          </body>
        
        
        
        
        </html>
        simpleTable.ds.xml
        Code:
        <DataSource ID="simpleTable" serverType="sql" tableName="t_schueler" requiresAuthentication="true">
        
        
        
        
        <fields>
        
        <field name="f_schueler_id" type="sequence" primaryKey="true" />
        
        <field name="f_name" type="text" />
        
        </fields>
        
        
        
        
        
        
        </DataSource>
        login.html
        Code:
        <!DOCTYPE html>
        
        <html>
        
        <head>
        
        <title>Login</title>
        
        </head>
        
        <body>
        
        <div id="loginPanel">
        
        <div id="formDiv">
        
        <div class="formular">
        
        <form method="POST" action="j_security_check">
        
        <table>
        
        <tr style="height:25px;">
        
          <td style="vertical-align:middle">username:</td>
        
          <td class="rightHandSide" style="vertical-align:middle"><input type="text" size="39" maxlength="50" name="j_username" class="form" id="input_username">
        
          </td>
        
        </tr>
        
        <tr><td class="vSpacer" colspan="2"></td></tr>
        
        <tr style="height:25px">
        
          <td>password:</td>
        
          <td class="rightHandSide"><input type="password" size="39" maxlength="50" name="j_password" id="j_password" class="form"></td>
        
        </tr>
        
        <tr style="height:25px">
        
          <td></td>
        
          <td class="rightHandSide"><input value="Login"  type="submit" class="form" id="submitButton">
        
          </td>
        
        </tr>
        
        </table>
        
        </form>
        
        </div>
        
        <br/>
        
        </div>
        
        </div>
        
        
        
        <SCRIPT>//'"]]>>isc_loginRequired
        
        //
        
        // Embed this whole script block VERBATIM into your login page to enable
        
        // SmartClient RPC relogin.
        
        //=======    
        
        
        
        
        
        
        
        
        
        
        if (!window.isc && document.domain && document.domain.indexOf(".") != -1
        
        && !(new RegExp("^(\\d{1,3}\\.){3}\\d{1,3}$").test(document.domain)))
        
        {
        
        
        
            var set = false;
        
            while (document.domain.indexOf(".") != -1) {
        
                try {
        
        
        
                    if (window.parent && window.parent.isc) break;
        
                    if (window.opener && window.opener.isc) break;
        
                    if (window.top.isc) break;
        
        
        
                    if (!set) { document.domain = document.domain; set = true; }
        
                    else { document.domain = document.domain.replace(/.*?\./, ''); }
        
                } catch (e) {
        
                    try {
        
                        if (!set) { document.domain = document.domain; set = true }
        
                        else { document.domain = document.domain.replace(/.*?\./, ''); }
        
                    } catch (ee) {
        
                        break;
        
                    }
        
                }
        
            }
        
        }
        
        
        
        
        var isc = window.parent ? window.parent.isc : null;
        
        if (!isc) isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
        
        if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginRequired", [window]);
        
        </SCRIPT>
        
        
        
        </body>
        
        </html>
        To recreate you need a user with this role: "MYROLE". Just log in and wait 1 minute for the session to expire. Then scroll the listgrid to fetch the next 75 records from the server, and then you will see the relogin window. Enter your log in information and the listgrid fetches the records correctly.
        But take a look at the screenshots.
        1.png is taken immediately after the relogin.
        2.png is taken 4 minutes later. The timeout seems to be 4 minutes.
        So:
        loginSuccessMarker.html gets a SERVER_TIMEOUT after 4 minutes
        j_security_check seems not to return
        but this doesn't make a lot of sense. Nevertheless, it is happening and can be easily reproduced.
        Using smartgwt 6.1p 20180203 power and tomcat 8.0.27
        Click image for larger version  Name:	1.png Views:	1 Size:	133.9 KB ID:	251712
        Click image for larger version  Name:	2.png Views:	1 Size:	134.9 KB ID:	251713
        Last edited by edulid; 10 Feb 2018, 15:26.

        Comment


          #5
          It looks like you've set this up so that a request to loginSuccessMarker.html is what triggers the relogin process. If so, you need to either cancelTransaction() or resubmitTransaction() on that request, or it will remain in limbo and eventually time out as you've seen.

          Comment


            #6
            In the validateLogin() method I have:
            Code:
            else {
            
            RPCManager.resendTransaction();
            
            }
            and the documentation says: "You can resend all suspended transactions by calling resendTransaction() with no arguments."
            So the transaction with the request to "loginSuccessMarker.html" should be resent here, or am I incorrect? as long with all other suspended transactions.

            Or where exactly should I put this ? Note that I took this from the wiki and I did not modify the request to loginSuccessMarker in any way.

            Comment


              #7
              In addition, as you can see in the screenshot in the first post, the request has status 200 and SERVER_TIMEOUT, and as you said, this does not make a lot of sense. And I already call RPCManager.resendTransaction() after authenticating.

              Comment


                #8
                Hi Isomorphic , have you been able to reproduce the issue?

                Comment


                  #9
                  Hi Isomorphic,

                  in order to be completely sure that I didn't have a dependency, I decided to use one of your samples to reproduce my problem. I chose "builtinds", and I slightly modified it to use my realm and authentication and include the relogin. I chose a role "ADMIN" for authentication.
                  And the issue is still there, exactly the same behavior! So please check what may be the problem. This problem has been there for years and I don't know how to solve it. You told me to call resubmitTransaction(), but I already do:
                  RPCManager.resendTransaction();

                  To reproduce, just login, wait one minute for the session to expire, and then scroll in order to make the relogin process to trigger. Then check the DSRequests and wait 4 minutes for the time out.
                  The relogin process was taken from here: https://isomorphic.atlassian.net/wik...mcat+JDBCRealm

                  web.xml
                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  
                  <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
                  
                  
                  
                  
                      <welcome-file-list>
                  
                  <welcome-file>BuiltInDS.html</welcome-file>
                  
                  </welcome-file-list>
                  
                  
                  
                  
                      <!-- Note: The servlets/filters referenced here are documented in the SDK javadoc -->
                  
                  
                  
                  
                  
                  
                  
                  <!-- Init: initializes SmartClient framework.  This listener should be the first one listed
                  
                           in web.xml because part of its function is to make JDBC DataSources available via JNDI
                  
                           to Spring and other Listeners.  See the client-side documentation topic "serverInit"
                  
                           for a discussion of this.  -->
                  
                  <listener>
                  
                  <listener-class>com.isomorphic.base.InitListener</listener-class>
                  
                  </listener>
                  
                  
                  
                      <!-- Dynamic Compression -->
                  
                      <filter>
                  
                          <filter-name>CompressionFilter</filter-name>
                  
                          <filter-class>com.isomorphic.servlet.CompressionFilter</filter-class>
                  
                      </filter>
                  
                      <!-- CompressionFilter for dynamic compression -->
                  
                      <filter-mapping>
                  
                          <filter-name>CompressionFilter</filter-name>
                  
                          <url-pattern>/*</url-pattern>
                  
                      </filter-mapping>
                  
                  
                  
                  
                      <!-- The IDACall servlet handles all Built-in DataSource operations -->
                  
                      <servlet>
                  
                          <servlet-name>IDACall</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.IDACall</servlet-class>
                  
                      </servlet>
                  
                  
                  
                  
                      <!-- The RESTHandler servlet is like IDACall, but for REST requests -->
                  
                      <servlet>
                  
                          <servlet-name>RESTHandler</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.RESTHandler</servlet-class>
                  
                      </servlet>
                  
                  
                  
                  
                      <!-- The DataSourceLoader servlet returns Javascript representations of the dataSources whose
                  
                           ID's are passed to it - it is an alternative to using the <loadDS> JSP tag -->
                  
                      <servlet>
                  
                          <servlet-name>DataSourceLoader</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.DataSourceLoader</servlet-class>
                  
                      </servlet>
                  
                  
                  
                  
                      <!-- The screenLoader servlet loads screen definitions in javascript notation -->
                  
                      <servlet>
                  
                          <servlet-name>screenLoader</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.ScreenLoaderServlet</servlet-class>
                  
                      </servlet>
                  
                  
                  
                  
                      <!-- The FileDownload servlet downloads static files, like a webserver -->
                  
                      <servlet>
                  
                          <servlet-name>FileDownload</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.FileDownload</servlet-class>
                  
                      </servlet>
                  
                  
                  
                  
                      <servlet>
                  
                          <servlet-name>HttpProxy</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.HttpProxyServlet</servlet-class>
                  
                      </servlet>
                  
                  
                  
                  
                      <!-- The PreCache servlet initializes when the servlet engine starts up and pre-loads
                  
                           data need for all client requests.  This is optional, and improves performance
                  
                           of the first few page requests.  PreCache cannot be invoked by a browser, because
                  
                           there is no "servlet-mapping" defined for it. -->
                  
                  
                  
                  
                      <!-- PreCache is disabled by default because of an issue when debugging
                  
                           the project for the first time. However, it can be safely enabled
                  
                           when compiling with the GWT compiler prior to deployment. See
                  
                           the README.txt for more information. -->
                  
                  
                  
                  
                      <!--
                  
                      <servlet>
                  
                          <servlet-name>PreCache</servlet-name>
                  
                          <servlet-class>com.isomorphic.servlet.PreCache</servlet-class>
                  
                          <load-on-startup>2</load-on-startup>
                  
                      </servlet>
                  
                      -->
                  
                  
                  
                  
                      <!-- RPCManager uses this URL by default for Built-in DataSource operations -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>IDACall</servlet-name>
                  
                          <url-pattern>/builtinds/sc/IDACall/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <servlet-mapping>
                  
                          <servlet-name>RESTHandler</servlet-name>
                  
                          <url-pattern>/builtinds/sc/RESTHandler/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- DataSourceLoader requests -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>DataSourceLoader</servlet-name>
                  
                          <url-pattern>/builtinds/sc/DataSourceLoader</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- The screenLoader servlet loads screen definitions in javascript notation -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>screenLoader</servlet-name>
                  
                          <url-pattern>/builtinds/sc/screenLoader</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <servlet-mapping>
                  
                          <servlet-name>HttpProxy</servlet-name>
                  
                          <url-pattern>/builtinds/sc/HttpProxy/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- Use FileDownload servlet to download all static content that's part of the skin, such as
                  
                           image files, so we can set Expires headers and other cache control directives.  In a
                  
                           production deployment, you'd want to use a webserver such as Apache to do this.  
                  
                      -->
                  
                      <servlet-mapping>
                  
                        <servlet-name>FileDownload</servlet-name>
                  
                        <url-pattern>/builtinds/sc/skins/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- serve ISC modules compressed, with expires headers -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>FileDownload</servlet-name>
                  
                          <url-pattern>/builtinds/sc/system/modules/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- serve ISC development modules compressed, with expires headers -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>FileDownload</servlet-name>
                  
                          <url-pattern>/builtinds/sc/system/development/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- serve skin assets with expires headers -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>FileDownload</servlet-name>
                  
                          <url-pattern>/builtinds/sc/system/reference/skin/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- serve the contents of the helpers/ directory with expires headers -->
                  
                      <servlet-mapping>
                  
                          <servlet-name>FileDownload</servlet-name>
                  
                          <url-pattern>/builtinds/sc/system/helpers/*</url-pattern>
                  
                      </servlet-mapping>
                  
                  
                  
                  
                      <!-- General config -->
                  
                      <session-config>
                  
                          <session-timeout>1</session-timeout>
                  
                      </session-config>
                  
                  
                  
                  
                      <jsp-config>
                  
                          <!-- Isomorphic JSP tags -->
                  
                          <taglib>
                  
                              <taglib-uri>isomorphic</taglib-uri>
                  
                              <taglib-location>/WEB-INF/iscTaglib.xml</taglib-location>
                  
                          </taglib>
                  
                      </jsp-config>
                  
                  
                  
                  
                      <mime-mapping>
                  
                          <extension>manifest</extension>
                  
                          <mime-type>text/cache-manifest</mime-type>
                  
                      </mime-mapping>
                  
                  
                  
                      <security-constraint>
                  
                      <web-resource-collection>
                  
                          <web-resource-name>no-auth</web-resource-name>
                  
                          <url-pattern>/builtinds/sc/system/helpers/Log.html</url-pattern>
                  
                      </web-resource-collection>
                  
                      <!-- OMIT auth-constraint -->
                  
                  </security-constraint>
                  
                  
                  
                  
                  <security-constraint>
                  
                  <web-resource-collection>
                  
                  <web-resource-name>minimaltestcase</web-resource-name>
                  
                  <url-pattern>*.html</url-pattern>
                  
                  <url-pattern>/BuiltInDS.html</url-pattern>
                  
                  <url-pattern>/builtinds/sc/IDACall/*</url-pattern>
                  
                  <http-method>GET</http-method>
                  
                  <http-method>POST</http-method>
                  
                  </web-resource-collection>
                  
                  <auth-constraint>
                  
                  <role-name>ADMIN</role-name>
                  
                  </auth-constraint>
                  
                  
                  
                  
                  </security-constraint>
                  
                  
                  
                  
                  <login-config>
                  
                  <auth-method>FORM</auth-method>
                  
                  <realm-name>User Auth</realm-name>
                  
                  
                  
                  
                  <form-login-config>
                  
                  <form-login-page>/login.jsp</form-login-page>
                  
                  <form-error-page>/autherr.jsp</form-error-page>
                  
                  </form-login-config>
                  
                  
                  
                  
                  </login-config>
                  
                  
                  
                  
                  <security-role>
                  
                  <role-name>ADMIN</role-name>
                  
                  </security-role>
                  
                  
                  
                  
                  </web-app>
                  login.jsp
                  Code:
                  <!DOCTYPE html>
                  
                  <html>
                  
                  <head>
                  
                  <title>Login</title>
                  
                  </head>
                  
                  <body>
                  
                  <div id="loginPanel">
                  
                  <div class="infoPanel">
                  
                  <p class="infoMessage">
                  
                  <B>Welcome!</B>
                  
                  </p>
                  
                  </div>
                  
                  <div id="formDiv">
                  
                  <div class="formular">
                  
                  <form method="POST" action="j_security_check">
                  
                  <table>
                  
                  <tr style="height:25px;">
                  
                    <td style="vertical-align:middle">Username:</td>
                  
                    <td class="rightHandSide" style="vertical-align:middle"><input type="text" size="39" maxlength="50" name="j_username" class="form" id="input_username">
                  
                    </td>
                  
                  </tr>
                  
                  <tr><td class="vSpacer" colspan="2"></td></tr>
                  
                  <tr style="height:25px">
                  
                    <td>Password:</td>
                  
                    <td class="rightHandSide"><input type="password" size="39" maxlength="50" name="j_password" id="j_password" class="form"></td>
                  
                  </tr>
                  
                  <tr style="height:25px">
                  
                    <td></td>
                  
                    <td class="rightHandSide"><input value="Login"  type="submit" class="form" id="submitButton">
                  
                    </td>
                  
                  </tr>
                  
                  </table>
                  
                  </form>
                  
                  </div>
                  
                  <br/>
                  
                  </div>
                  
                  </div>
                  
                  
                  
                  <SCRIPT>//'"]]>>isc_loginRequired
                  
                  //
                  
                  // Embed this whole script block VERBATIM into your login page to enable
                  
                  // SmartClient RPC relogin.
                  
                  //=======    
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  if (!window.isc && document.domain && document.domain.indexOf(".") != -1
                  
                  && !(new RegExp("^(\\d{1,3}\\.){3}\\d{1,3}$").test(document.domain)))
                  
                  {
                  
                  
                  
                      var set = false;
                  
                      while (document.domain.indexOf(".") != -1) {
                  
                          try {
                  
                  
                  
                              if (window.parent && window.parent.isc) break;
                  
                              if (window.opener && window.opener.isc) break;
                  
                              if (window.top.isc) break;
                  
                  
                  
                              if (!set) { document.domain = document.domain; set = true; }
                  
                              else { document.domain = document.domain.replace(/.*?\./, ''); }
                  
                          } catch (e) {
                  
                              try {
                  
                                  if (!set) { document.domain = document.domain; set = true }
                  
                                  else { document.domain = document.domain.replace(/.*?\./, ''); }
                  
                              } catch (ee) {
                  
                                  break;
                  
                              }
                  
                          }
                  
                      }
                  
                  }
                  
                  
                  
                  
                  var isc = window.parent ? window.parent.isc : null;
                  
                  if (!isc) isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
                  
                  if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginRequired", [window]);
                  
                  </SCRIPT>
                  
                  
                  
                  </body>
                  
                  </html>

                  autherr.jsp
                  Code:
                  <!DOCTYPE html>
                  
                  <html>
                  
                  <head>
                  
                  <title>Login</title>
                  
                  </head>
                  
                  <body>
                  
                  
                  
                  
                  Wrong username and/or password.
                  
                  
                  
                  </body>
                  
                  </html>
                  BuiltInDS.java
                  Code:
                  package com.smartgwt.sample.client;
                  
                  
                  
                  
                  import java.util.HashMap;
                  
                  import java.util.Map;
                  
                  
                  
                  
                  import com.google.gwt.core.client.EntryPoint;
                  
                  import com.smartgwt.client.rpc.LoginRequiredCallback;
                  
                  import com.smartgwt.client.rpc.RPCCallback;
                  
                  import com.smartgwt.client.rpc.RPCManager;
                  
                  import com.smartgwt.client.rpc.RPCRequest;
                  
                  import com.smartgwt.client.rpc.RPCResponse;
                  
                  import com.smartgwt.client.types.Alignment;
                  
                  import com.smartgwt.client.util.SC;
                  
                  import com.smartgwt.client.widgets.IButton;
                  
                  import com.smartgwt.client.widgets.Label;
                  
                  import com.smartgwt.client.widgets.Window;
                  
                  import com.smartgwt.client.widgets.events.ClickEvent;
                  
                  import com.smartgwt.client.widgets.events.ClickHandler;
                  
                  import com.smartgwt.client.widgets.form.DynamicForm;
                  
                  import com.smartgwt.client.widgets.form.fields.PasswordItem;
                  
                  import com.smartgwt.client.widgets.form.fields.TextItem;
                  
                  import com.smartgwt.client.widgets.grid.ListGrid;
                  
                  import com.smartgwt.client.widgets.grid.ListGridField;
                  
                  import com.smartgwt.client.widgets.layout.HLayout;
                  
                  import com.smartgwt.client.widgets.layout.VLayout;
                  
                  
                  
                  
                  /**
                  
                   * Entry point classes define <code>onModuleLoad()</code>.
                  
                   */
                  
                  public class BuiltInDS implements EntryPoint {
                  
                  
                  
                  
                  private Window windowRelogin = new Window();
                  
                  private DynamicForm formLogin;
                  
                  private TextItem login;
                  
                  
                  
                  
                  /**
                  
                  * This is the entry point method.
                  
                  */
                  
                  public void onModuleLoad() {
                  
                  
                  
                  
                  setupRelogin();
                  
                  
                  
                  
                  final VLayout vlayout = new VLayout();
                  
                  final ListGrid lg = new ListGrid();
                  
                  ListGridField nameField = new ListGridField("itemName");
                  
                  lg.setFields(nameField);
                  
                  lg.setDataSource("supplyItem");
                  
                  lg.fetchData();
                  
                  
                  
                  
                  vlayout.addMember(lg);
                  
                  vlayout.setWidth100();
                  
                  vlayout.setHeight100();
                  
                  vlayout.draw();
                  
                  
                  
                  
                  }
                  
                  
                  
                  
                  private void setupRelogin() {
                  
                  windowRelogin = new Window();
                  
                  windowRelogin.setAutoCenter(true);
                  
                  windowRelogin.setTitle("relogin");
                  
                  windowRelogin.setShowCloseButton(false);
                  
                  windowRelogin.setShowMinimizeButton(false);
                  
                  windowRelogin.setShowMaximizeButton(false);
                  
                  windowRelogin.setWidth(370);
                  
                  windowRelogin.setIsModal(true);
                  
                  windowRelogin.setShowModalMask(true);
                  
                  windowRelogin.setHeight(190);
                  
                  
                  
                  
                  VLayout vlayout = new VLayout(10);
                  
                  Label lMsg = new Label("login time out");
                  
                  lMsg.setWidth100();
                  
                  lMsg.setHeight(20);
                  
                  
                  
                  
                  vlayout.setPadding(10);
                  
                  
                  
                  
                  formLogin = new DynamicForm();
                  
                  formLogin.setAlign(Alignment.CENTER);
                  
                  formLogin.setIsGroup(false);
                  
                  
                  
                  
                  login = new TextItem();
                  
                  login.setTitle("username");
                  
                  login.setName("j_username");
                  
                  
                  
                  
                  PasswordItem password = new PasswordItem();
                  
                  password.setTitle("password");
                  
                  password.setName("j_password");
                  
                  password.setRequired(true);
                  
                  IButton loginButton = new IButton();
                  
                  loginButton.setTitle("login");
                  
                  loginButton.setWidth(100);
                  
                  loginButton.addClickHandler(new ClickHandler() {
                  
                  
                  
                  
                  @Override
                  
                  public void onClick(ClickEvent event) {
                  
                  if (!formLogin.validate())
                  
                  return;
                  
                  
                  
                  
                  RPCRequest request = new RPCRequest();
                  
                  request.setActionURL("loginSuccessMarker.html");
                  
                  RPCManager.sendRequest(request);
                  
                  
                  
                  
                  validateRelogin(formLogin.getValueAsString("j_username"), formLogin.getValueAsString("j_password"));
                  
                  }
                  
                  });
                  
                  
                  
                  
                  HLayout buttonsLayout = new HLayout(5);
                  
                  buttonsLayout.addMember(loginButton);
                  
                  
                  
                  
                  formLogin.setFields(login, password);
                  
                  vlayout.addMember(lMsg);
                  
                  vlayout.addMember(formLogin);
                  
                  vlayout.addMember(buttonsLayout);
                  
                  
                  
                  
                  windowRelogin.addItem(vlayout);
                  
                  
                  
                  
                  // setup Relogin
                  
                  RPCManager.setLoginRequiredCallback(new LoginRequiredCallback() {
                  
                  
                  
                  
                  @Override
                  
                  public void loginRequired(int transactionNum, RPCRequest request, RPCResponse response) {
                  
                  if ((!windowRelogin.isDrawn()) || (!windowRelogin.isVisible())) {
                  
                  formLogin.clearValues();
                  
                  windowRelogin.redraw();
                  
                  windowRelogin.show();
                  
                  formLogin.focusInItem("j_username");
                  
                  }
                  
                  }
                  
                  
                  
                  
                  });
                  
                  
                  
                  
                  }
                  
                  
                  
                  
                  public void validateRelogin(String j_username, String j_password) {
                  
                  
                  
                  RPCRequest request = new RPCRequest();
                  
                  request.setContainsCredentials(true);
                  
                  request.setActionURL("j_security_check");
                  
                  request.setUseSimpleHttp(true);
                  
                  request.setShowPrompt(false);
                  
                  Map<String, String> params = new HashMap<String, String>();
                  
                  params.put("j_username", j_username);
                  
                  params.put("j_password", j_password);
                  
                  request.setParams(params);
                  
                  RPCManager.sendRequest(request, new RPCCallback() {
                  
                  
                  
                  
                  @Override
                  
                  public void execute(RPCResponse response, Object rawData, RPCRequest request) {
                  
                  windowRelogin.hide();
                  
                  String data = String.valueOf(rawData);
                  
                  if (data.contains("Wrong username")) {
                  
                  formLogin.clearValues();
                  
                  windowRelogin.redraw();
                  
                  windowRelogin.show();
                  
                  formLogin.focusInItem("j_username");
                  
                  SC.say("Your login information was not correct, try again");
                  
                  } else {
                  
                  RPCManager.resendTransaction();
                  
                  }
                  
                  
                  
                  
                  }
                  
                  
                  
                  
                  });
                  
                  
                  
                  
                  }
                  
                  
                  
                  
                  }
                  BuiltInDS.html
                  Code:
                  <!DOCTYPE html>
                  
                  
                  
                  
                  <html>
                  
                    <head>
                  
                      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
                  
                      <!--                                           -->
                  
                      <!-- Any title is fine                         -->
                  
                      <!--                                           -->
                  
                      <title>BuiltInDS</title>
                  
                  
                  
                      <!-- IMPORTANT : You must set the variable isomorphicDir to [MODULE_NAME]/sc/ so that the SmartGWT resource are
                  
                    correctly resolved -->
                  
                  <script> var isomorphicDir = "builtinds/sc/"; </script>
                  
                  
                  
                      <!--                                           -->
                  
                      <!-- This script loads your compiled module.   -->
                  
                      <!-- If you add any GWT meta tags, they must   -->
                  
                      <!-- be added before this line.                -->
                  
                      <!--                                           -->      
                  
                      <script type="text/javascript" language="javascript" src="builtinds/builtinds.nocache.js"></script>
                  
                  
                  
                  
                      <!-- The following script is required if you're running (Super)DevMode and are using module
                  
                           definitions that contain <script> tags.  Normally, this script is loaded automatically
                  
                           by builtinds.nocache.js above, but this isn't possible when (Super)DevMode is running.
                  
                           Note: it should not create any issue to always load it below (even if already loaded). -->
                  
                      <script type="text/javascript" language="javascript" src="builtinds/loadScriptTagFiles.js"></script>
                  
                  
                  
                  
                    </head>
                  
                  
                  
                  
                    <!--                                           -->
                  
                    <!-- The body can have arbitrary html, or      -->
                  
                    <!-- you can leave the body empty if you want  -->
                  
                    <!-- to create a completely dynamic UI.        -->
                  
                    <!--                                           -->
                  
                    <body>
                  
                  
                  
                  
                      <!--load the datasources-->
                  
                      <script src="builtinds/sc/DataSourceLoader?dataSource=supplyItem,animals,employees"></script>
                  
                  
                  
                  
                      <!-- OPTIONAL: include this if you want history support -->
                  
                      <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
                  
                  
                  
                  
                    </body>
                  
                  </html>
                  loginSuccessMarker.html
                  Code:
                  <SCRIPT>//'"]]>>isc_loginSuccess
                  
                  //
                  
                  // When doing relogin with a webserver-based authenticator, protect this page with it and
                  
                  // target your login attempts at this page such that when the login succeeds, this page is
                  
                  // returned.
                  
                  //
                  
                  // If you are integrating with a web service that returns a fault, paste this entire script
                  
                  // block VERBATIM into the fault text.
                  
                  //=======    
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  if (!window.isc && document.domain && document.domain.indexOf(".") != -1
                  
                  && !(new RegExp("^(\\d{1,3}\\.){3}\\d{1,3}$").test(document.domain)))
                  
                  {
                  
                  
                  
                      var set = false;
                  
                      while (document.domain.indexOf(".") != -1) {
                  
                          try {
                  
                  
                  
                              if (window.parent && window.parent.isc) break;
                  
                              if (window.opener && window.opener.isc) break;
                  
                              if (window.top.isc) break;
                  
                  
                  
                              if (!set) { document.domain = document.domain; set = true; }
                  
                              else { document.domain = document.domain.replace(/.*?\./, ''); }
                  
                          } catch (e) {
                  
                              try {
                  
                                  if (!set) { document.domain = document.domain; set = true }
                  
                                  else { document.domain = document.domain.replace(/.*?\./, ''); }
                  
                              } catch (ee) {
                  
                                  break;
                  
                              }
                  
                          }
                  
                      }
                  
                  }
                  
                  
                  
                  
                  var isc = window.parent ? window.parent.isc : null;
                  
                  if (!isc) isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
                  
                  if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginSuccess", [window]);
                  
                  </SCRIPT>
                  server.properties
                  Code:
                  # The webRoot directory:
                  
                  # the directory that the servlet engine regards as the place where applications 
                  
                  # that use the servlet engine should be installed.  Generally, it is safe to leave
                  
                  # this at the default setting of __AUTODETECT__.  When the SmartClient server is
                  
                  # started, it logs a message to stdout telling you the autodetected path to your
                  
                  # webRoot.  If this path is not your actual webRoot, then you'll want to override
                  
                  # this config parameter here.
                  
                  #
                  
                  # Valid values: 
                  
                  #
                  
                  # 1. Absolute path to the webRoot directory
                  
                  #
                  
                  # 2. Special token:  __AUTODETECT__
                  
                  #    When this token is used, SmartClient attempts to auto-detect the webRoot using
                  
                  #    standard servlet APIs.  This may or may not work - depending on your
                  
                  #    container type and deployment type.  For example, WAR/EAR deployments
                  
                  #    on some containers never make it to disk, and so the container refuses
                  
                  #    to provide the webRoot path.
                  
                  #  
                  
                  #    If SmartClient cannnot detect the webRoot, it sets the webRoot to
                  
                  #    __USE_CONTAINER__ (see below).
                  
                  #
                  
                  # 3.  Special token: __USE_CONTAINER__
                  
                  #     When this token is used, SmartClient uses standard servet APIs for accessing
                  
                  #     filesystem resources.  This is slower than direct file access and, since
                  
                  #     the servlet APIs provide no mechanism for writing to disk, means that some
                  
                  #     development tools like the FileAssembler will not work.
                  
                  #
                  
                  webRoot: __AUTODETECT__
                  
                  
                  
                  
                  # Set this to the GWT module name.
                  
                  gwtModuleName: builtinds
                  
                  
                  
                  
                  # if you've moved the isomorphic directory from its default location in webRoot,
                  
                  # set the root-relative path to it here
                  
                  #
                  
                  # For example, if in your deployment the 'isomorphic' dir is in /foo/bar, then set
                  
                  # then you'll need to set this to foo/bar/isomorphic
                  
                  isomorphicPathRootRelative: $gwtModuleName/sc
                  
                  
                  
                  
                  
                  
                  
                  # -------------- PICK DATABASE TO USE --------------------
                  
                  #
                  
                  # The SmartClient SDK ships with examples that use a database as the persistence
                  
                  # layer.  By default, the SDK uses a built-in version of HSQLDB, but you can
                  
                  # specify a different database to use here.
                  
                  
                  
                  
                  # which database do you want to use?  HSQLDB is enabled by default.
                  
                  #sql.defaultDatabase: HSQLDB
                  
                  # Publish the JDBC endpoint for the defaultDatabase via JNDI at the specified path for use by
                  
                  # other frameworks such as Spring, Hibernate, etc.
                  
                  # Note that we do not use the java:comp or java:comp/env prefix because that
                  
                  # subtree is read-only on Tomcat (and possibly other containers) due to security
                  
                  # considerations
                  
                  sql.defaultDatabase.jndi.publish.path: isomorphic/jdbc/defaultDatabase
                  
                  
                  
                  
                  sql.defaultDatabase: SQLSERVER
                  
                  
                  
                  
                  # If you want to use Mysql instead, uncomment the following line
                  
                  # and comment all other sql.defaultDatabase definitions
                  
                  #sql.defaultDatabase: Mysql
                  
                  
                  
                  
                  # If you want to use Oracle instead, uncomment the following line
                  
                  # and comment all other sql.defaultDatabase definitions
                  
                  #sql.defaultDatabase: Oracle
                  
                  
                  
                  
                  # If you want to use Postgres instead, uncomment the following line
                  
                  # and comment all other sql.defaultDatabase definitions
                  
                  #sql.defaultDatabase: PostgreSQL
                  
                  
                  
                  
                  # If you want to use DB2 instead, uncomment the following line
                  
                  # and comment all other sql.defaultDatabase definitions
                  
                  #sql.defaultDatabase: DB2
                  
                  
                  
                  
                  # -------------- SETTINGS FOR HSQLDB --------------------
                  
                  
                  
                  
                  sql.SQLSERVER.database.type: sqlserver
                  
                  sql.SQLSERVER.interface.type: driverManager
                  
                  
                  
                  
                  sql.SQLSERVER.driver: com.microsoft.sqlserver.jdbc.SQLServerDriver
                  
                  sql.SQLSERVER.driver.url: jdbc:sqlserver://IP;UserName=myuser;password=pwd;databaseName=mydb
                  
                  
                  
                  
                  
                  
                  
                  # -------------- LOADING APP AND DATASOURCE DEFINITIONS --------------------
                  
                  
                  
                  
                  # Where the system looks for DataSource definition files ([dataSourceId].ds.xml or
                  
                  # [dataSourceID].ds.js).  It's useful to put all your DataSources in one 
                  
                  # directory since DataSources are frequently shared between applications.  
                  
                  # "project.datasources" is also where the DataSource Importer tool looks 
                  
                  # for available DataSources.
                  
                  project.datasources: $webRoot/ds
                  
                  project.ui: $webRoot/shared/ui
                  
                  project.apps: $webRoot/shared/app
                  
                  
                  
                  
                  # -------------- Other settings --------------------
                  
                  # The setting RPCManager.enabledBuiltinMethods enables or disables the BuiltInRPCs - RPC calls
                  
                  # that are built into the SmartClient Server.  The setting below reflects the framework default
                  
                  # of enabling only those RPCs that are typically needed in an application.
                  
                  # 
                  
                  # See the JavaDoc for com.isomorphic.rpc.BuiltinRPC and com.isomorphic.tools.BuiltinRPC for all
                  
                  # available builtinRPCs and their behavior.
                  
                  # 
                  
                  # Note that many of the BuiltinRPCs are designed for use by tools such as Visual Builder, and
                  
                  # provide services such as direct access to the file system (for load and save of screens) that
                  
                  # would be unsafe to expose to untrusted users.
                  
                  #
                  
                  #RPCManager.enabledBuiltinMethods: getPdfObject, xmlToJS, uploadProgressCheck, exportClientData, downloadClientExport, setAttributes
                  
                  
                  
                  
                  # Note: modulesDir is only used with the loadISC and loadModules JSP tags; if
                  
                  # you intend to use those tags, do not change this setting
                  
                  modulesDir: modules/
                  Last edited by edulid; 17 Feb 2018, 09:16.

                  Comment


                    #10
                    Please, try removing the following code:

                    Code:
                        RPCRequest request = new RPCRequest();
                        request.setActionURL("loginSuccessMarker.html");
                        RPCManager.sendRequest(request);
                    this extra request is required in some installations of JDBC Realms.

                    Regards
                    Isomorphic Software

                    Comment


                      #11
                      Hi Isomorphic

                      thank you!!! this seems to be the solution. The relogin approach is very interesting and I am now trying to understand how this works and have some questions:

                      1. In which installations of JDBC Realms is this necessary ? When is this necessary and when not?
                      2. Why is the relogin process working although I am not explicitely requesting the "loginSuccessMarker.html" file? In my developer tools I see the following requests:

                      First request when no relogin happens:
                      localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                      Response:
                      //isc_RPCResponseStart-->[{affectedRows:0,data:[{itemID:120,itemName:"Duplicate Carbon Book 8 x 5 Delivery #633" ............. totalRows:3959}]//isc_RPCResponseEnd

                      Second request (after session expires):
                      localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                      Response:
                      My login HTML site with the isc_loginRequired marker. So the application now knows it has to relogin. Ok.

                      Third request:
                      localhost:8080/mini/j_security_check
                      Response headers:
                      Code:
                      HTTP/1.1 303 See Other
                      Server: Apache-Coyote/1.1
                      Location: http://localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                      Content-Length: 0
                      Date: Wed, 21 Feb 2018 09:44:29 GMT
                      Response in Smartgwt console (this contains slightly different data, since I gathered this in another execution):
                      DSRequest:
                      Code:
                      {
                          "actionURL":"j_security_check",
                          "showPrompt":false,
                          "transport":"xmlHttpRequest",
                          "useSimpleHttp":true,
                          "promptStyle":"cursor",
                          "params":{
                              "j_username":"myusername",
                              "j_password":"mypassword"
                          },
                          "containsCredentials":true
                      }
                      DSResponse:
                      Code:
                      {
                          affectedRows:0,
                          data:[
                              {
                                  itemID:1381,
                                  itemName:"Pens Uniball Ub100 Medium 0.4mm Red",
                                  unitCost:1.15,
                                  units:"Ea",
                                  SKU:"54906705",
                                  category:"Rolling Ball Pens",
                                  rowID:1381
                              },
                      ......
                          endRow:1455,
                          invalidateCache:false,
                          isDSResponse:true,
                          operationType:"fetch",
                          queueStatus:0,
                          startRow:1380,
                          status:0,
                          totalRows:3959
                      }
                      Fourth request:
                      localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                      Response:
                      //isc_RPCResponseStart-->[{affectedRows:0,data:[{itemID:1521,itemName:"Pens Pilot Bps-gp Super Grip Ballpoint Med Black" ........................ queueStatus:0,startRow:1520,status:0,totalRows:3959}]//isc_RPCResponseEnd

                      Fifth request:
                      localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                      Response:
                      //isc_RPCResponseStart-->[{affectedRows:0,data:[{itemID:1521,itemName:"Pens Pilot Bps-gp Super Grip Ballpoint Med Black" ........................ queueStatus:0,startRow:1520,status:0,totalRows:3959}]//isc_RPCResponseEnd

                      So some things I noticed:

                      3. Why am I seeing two equal requests/responses (fourth and fifth)? Am I getting this data twice? If I check in my SmartGWT developer console, I see only one request after the j_security_check request. You can see it here:
                      RPCRequest:
                      Code:
                      {
                          "actionURL":"http://localhost:8080/mini/builtinds/sc/IDACall",
                          "showPrompt":true,
                          "prompt":"Finding Records that match your criteria...",
                          "transport":"xmlHttpRequest",
                          "promptStyle":null,
                          "bypassCache":true,
                          "data":{
                              "criteria":{
                              },
                              "operationConfig":{
                                  "dataSource":"supplyItem",
                                  "repo":null,
                                  "operationType":"fetch",
                                  "textMatchStyle":"exact"
                              },
                              "startRow":1520,
                              "endRow":1595,
                              "componentId":"isc_ListGrid_0",
                              "appID":"builtinApplication",
                              "operation":"supplyItem_fetch",
                              "oldValues":{
                              }
                          }
                      }
                      DSRequest:
                      Code:
                      {
                          dataSource:"supplyItem",
                          operationType:"fetch",
                          componentId:"isc_ListGrid_0",
                          data:{
                          },
                          startRow:1520,
                          endRow:1595,
                          textMatchStyle:"exact",
                          resultSet:[ResultSet ID:isc_ResultSet_0 (dataSource: supplyItem, created by: isc_ListGrid_0)],
                          callback:{
                              caller:[ResultSet ID:isc_ResultSet_0 (dataSource: supplyItem, created by: isc_ListGrid_0)],
                              methodName:"fetchRemoteDataReply"
                          },
                          willHandleError:true,
                          showPrompt:true,
                          prompt:"Finding Records that match your criteria...",
                          oldValues:{
                          },
                          requestId:"supplyItem$6273",
                          internalClientContext:{
                              requestIndex:4
                          },
                          fallbackToEval:false,
                          lastClientEventThreadCode:"TMR9",
                          bypassCache:true,
                          dataProtocol:"getParams"
                      }
                      Response:
                      Code:
                      {
                          affectedRows:0,
                          data:[
                              {
                                  itemID:1521,
                                  itemName:"Pens Pilot Bps-gp Super Grip Ballpoint Med Black",
                                  unitCost:1.36,
                                  inStock:true,
                                  units:"Ea",
                                  SKU:"58482602",
                                  category:"Office Paper Products",
                                  rowID:1521
                              },
                      .....
                       endRow:1595,
                          invalidateCache:false,
                          isDSResponse:true,
                          operationType:"fetch",
                          queueStatus:0,
                          startRow:1520,
                          status:0,
                          totalRows:3959
                      }
                      So why am I seeing two equal requests in my developer tools?

                      4. How is the relogin process working without the explicit request to "loginSuccessMarker.html" ? I never see the loginSuccessMarker.html in my responses, as you also see in my example above. The loginSuccessMarker.html is a protected resource, as stated in your docs:
                      https://www.smartclient.com/smartgwt...s/Relogin.html
                      configure your authentication system to send back the loginSuccessMarker as part of a successful login response, and the loginRequiredMarker as part of a failed login response.
                      If your authentication system can accept POST'd credentials at any URL it protects, the last step may be as simple as configuring the loginSuccessMarker file itself as a protected resource. The loginSuccessMarker is found in docs/loginSuccessMarker.html in your SDK.
                      But I am not seeing the loginSuccessMarker in any response! Or am I missing something ? How is the relogin working without having this loginSuccessMarker.html in a response?

                      In the loginSuccessMarker.html file I see:
                      // When doing relogin with a webserver-based authenticator, protect this page with it and
                      // target your login attempts at this page such that when the login succeeds, this page is
                      // returned.
                      But as I said I never see this response! My login attempts are targeted to j_security_check.

                      5. In my original approach, i.e. with the following:
                      Code:
                       RPCRequest request = new RPCRequest(); request.setActionURL("loginSuccessMarker.html"); RPCManager.sendRequest(request);
                      I see a timeout, as you know, together with a 200 status. Isn't this a bug? A 200 status and a timeout don't make much sense, as you said. And why am I getting always a timeout if sending this request? Is this a bug?

                      Thanks
                      Edulid
                      Last edited by edulid; 21 Feb 2018, 05:43.

                      Comment


                        #12
                        1. we don't know. It was required as a workaround in a previous version of JDBC Realms and does not seem to be required in the current version.

                        2, 3 & 4. all we require is that you authenticate in some way, then resubmit or cancel any suspended transactions. One way to handle re-authentication is to embed the loginSuccessMarker into whatever page is returned when some *pre-existing* login process completes and returns an end-user-intelligible page. But it is not required that it is done this way, and for JDBC realms, there is a means to send credentials to a given target URL, and those credentials can be gathered via a SmartGWT interface rather than trying to script a series of interactions with a pre-existing login page. With this in mind, hopefully the request series of more intelligible.

                        5. that request times out because it is suspended, and is never cleared or resubmitted. We will be revising the sample code to note that issuing that request at all is a workaround for an old JDBC Realms bug, and adding code that correctly clears it.

                        Comment


                          #13
                          Hi Isomorphic ,

                          thank you for the explanation, now I understand better and it makes more sense. So in our case we don't need the loginSuccessMarker.html page, since we are using JDBC realms, which authenticate by the call to j_security_check. As I suggestion maybe you can also make the text here more explicit: https://www.smartclient.com/smartgwt...s/Relogin.html
                          3. configure your authentication system to send back the loginSuccessMarker as part of a successful login response, and the loginRequiredMarker as part of a failed login responseIf your authentication system can accept POST'd credentials at any URL it protects, the last step may be as simple as configuring the loginSuccessMarker file itself as a protected resource. The loginSuccessMarker is found in docs/loginSuccessMarker.html in your SDK.
                          In the link, it seems that 3. is always necessary, since 1. and 2. are.

                          One last question:
                          Your explanation of the approach doesn't seem to answer my 3) question: why am I seeing a duplicate request/response in my developers console, while in my smartgwt console I only see one response ? It seems like a duplicate since I get the same data twice.
                          Here the duplicate:

                          Fourth request:
                          localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                          Response:
                          //isc_RPCResponseStart-->[{affectedRows:0,data:[{itemID:1521,itemName:"Pens Pilot Bps-gp Super Grip Ballpoint Med Black" ........................ queueStatus:0,startRow:1520,status:0,totalRows:3959}]//isc_RPCResponseEnd

                          Fifth request:
                          localhost:8080/mini/builtinds/sc/IDACall?isc_rpc=1&isc_v=v11.1p_2018-02-15&isc_xhr=1
                          Response:
                          //isc_RPCResponseStart-->[{affectedRows:0,data:[{itemID:1521,itemName:"Pens Pilot Bps-gp Super Grip Ballpoint Med Black" ........................ queueStatus:0,startRow:1520,status:0,totalRows:3959}]//isc_RPCResponseEnd

                          Thanks,
                          Edulid

                          Comment


                            #14
                            Checking again, I see that in the first request (in this case my "fourth request") the initiator is "j_security_check". In the second ("fifth") the initiator is "ISC_Core.js?isc_version=11.1p_2018-02-15.js:1709".
                            So I checked my smartgwt console again and in fact, there are two requests both returning the same data:

                            First request:
                            Type: RPCRequest
                            URL: j_security_check

                            RPCRequest:
                            Code:
                            {
                                "actionURL":"j_security_check",
                                "showPrompt":false,
                                "transport":"xmlHttpRequest",
                                "useSimpleHttp":true,
                                "promptStyle":"cursor",
                                "params":{
                                    "j_username":"myusername",
                                    "j_password":"mypassword"
                                },
                                "containsCredentials":true
                            }
                            Raw response:
                            Code:
                            {
                                affectedRows:0,
                                data:[
                                    {
                                        itemID:2684,
                                        itemName:"Compatible Reman Toner Cartridge To Suit Canon Fx2",
                                        unitCost:41.18,
                                        SKU:"86540241",
                                        category:"Office Filing and Storage",
                                        rowID:2684
                                    },
                            ......
                                endRow:2758,
                                invalidateCache:false,
                                isDSResponse:true,
                                operationType:"fetch",
                                queueStatus:0,
                                startRow:2683,
                                status:0,
                                totalRows:3959
                            }
                            Second request:
                            Type: DSRequest
                            URL: localhost:8080/mini/builtinds/sc/IDACall

                            DSRequest:
                            Code:
                            {
                                dataSource:"supplyItem",
                                operationType:"fetch",
                                componentId:"isc_ListGrid_0",
                                data:{
                                },
                                startRow:2683,
                                endRow:2758,
                                textMatchStyle:"exact",
                                resultSet:[ResultSet ID:isc_ResultSet_0 (dataSource: supplyItem, created by: isc_ListGrid_0)],
                                callback:{
                                    caller:[ResultSet ID:isc_ResultSet_0 (dataSource: supplyItem, created by: isc_ListGrid_0)],
                                    methodName:"fetchRemoteDataReply"
                                },
                                willHandleError:true,
                                showPrompt:true,
                                prompt:"Finding Records that match your criteria...",
                                oldValues:{
                                },
                                requestId:"supplyItem$6272",
                                internalClientContext:{
                                    requestIndex:3
                                },
                                fallbackToEval:false,
                                lastClientEventThreadCode:"TMR9",
                                bypassCache:true,
                                dataProtocol:"getParams"
                            }
                            Raw response:
                            Code:
                            {
                                affectedRows:0,
                                data:[
                                    {
                                        itemID:2684,
                                        itemName:"Compatible Reman Toner Cartridge To Suit Canon Fx2",
                                        unitCost:41.18,
                                        SKU:"86540241",
                                        category:"Office Filing and Storage",
                                        rowID:2684
                                    },
                            .............
                               endRow:2758,
                                invalidateCache:false,
                                isDSResponse:true,
                                operationType:"fetch",
                                queueStatus:0,
                                startRow:2683,
                                status:0,
                                totalRows:3959
                            }
                            Different request types/different requests but with duplicate response data? Is this necessary ?

                            Thanks,
                            Edulid

                            Comment


                              #15
                              This does not appear to be correct diagnostic information. The j_security_check servlet would not be returning data similarly to IDACall - that's not a servlet we provide, after all. You should double check this result, and perhaps also check with the browser's built-in tools, in case what's going on is an error in our RPC tab.

                              Comment

                              Working...
                              X