Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The underlying reason for your problems is that Java EE was designed to work in a different way - attempting to block/wait on a service thread is one of the important no-no's. I'll give the reason for this first, and how to solve the issue after that. </p> <p>Java EE (both the web and EJB tier) is designed to be able to scale to very large size (hundreds of computers in a cluster). However, in order to do that, the designers had to make the following assumptions, which are specific limitations on how to code:</p> <ul> <li><p>Transactions are:</p> <ol> <li>Short lived (eg don't block or wait for periods greater than a second or so)</li> <li>Independent of each other (eg no communication between threads)</li> <li>For EJBs, managed by the container</li> </ol></li> <li><p>All user state is maintained in specific data storage containers, including:</p> <ol> <li>A data store accessed through, eg, JDBC. You can use a traditional SQL database or a NoSQL backend</li> <li>Stateful session beans, if you use EJBs. Think of these as Java Bean that persists its fields to a database. Stateful session beans are managed by the container</li> <li><p><a href="http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSession.html" rel="nofollow noreferrer">Web session</a> This is a key-value store (kinda like a NoSQL database but without the scale or search capabilities) that persists data for a specific user over their session. It's managed by the Java EE container and has the following properties:</p> <ol> <li>It will automatically relocate if the node crashes in a cluster</li> <li>Users can have more than one current web session (i.e. on two different browsers)</li> <li>Web sessions end when the user ends their session by logging out, or when the session is inactive for longer than the configurable timeout. </li> <li>All values that are stored <strong>must</strong> be serializable for them to be persisted or transfered between nodes in a cluster.</li> </ol></li> </ol></li> </ul> <p>If we follow those rules, the Java EE container can successfully manage a cluster, including shutting down nodes, starting new ones and migrating user sessions, without <em>any specific developer code</em>. Developers write the graphical interface and the business logic - all the 'plumbing' is managed by configurable container features.</p> <p>Also, at run time, the Java EE container can be monitored and managed by some pretty sophisticated software that can trace application performance and behavioural issues on a live system.</p> <p>&lt; snark >Well, that was the theory. Practice suggests there are pretty important limitations that were missed, which lead to AOSP and code injection techniques, but that's another story &lt; /snark > </p> <p>[There are many discussions around the 'net on this. One which focuses on EJBs is here: <a href="https://stackoverflow.com/questions/533783/why-spawning-threads-in-java-ee-container-is-discouraged">Why is spawning threads in Java EE container discouraged?</a> Exactly the same is true for web containers such as Tomcat]</p> <p>Sorry for the essay - but this is important to your problem. Because of the limitations on threads, you should not block on the web request waiting for another, later request. </p> <p>Another problem with the current design is what should happen if the user becomes disconnected from the network, runs out of power, or simply decides to give up? Presumably you will time out, but after how long? Just too soon for some customers, perhaps, which will cause satisfaction problems. If the timeout is too long, you could end up blocking <em>all</em> worker threads in Tomcat and the server will freeze. This opens your organisation up for a denial of service attack.</p> <p><strong>EDIT :</strong> Improved suggestions after a more detailed description of the algorithm was published.</p> <p>Notwithstanding the discussion above on the bad practice of blocking a web worker thread and also the possible denial of service, it's clear that the user is presented with a small time window in which to react to the the notification on the Android phone, and this can be kept reasonably small to enhance security. This time window can also be kept below Tomcat's timeout for responses as well. So the thread blocking approach could be used.</p> <p>There are two ways this problem can be resolved:</p> <ol> <li><strong>Change the focus of the solution to the client end</strong> - polling the server using Javascript on the browser</li> <li><strong>Communication between nodes in the cluster</strong> allowing the node receiving the authorization response from the Android App to unblock the node blocking the servlet's response.</li> </ol> <p>For approach 1, the browser polls the server via Javascript with an AJAX call to a web service on Tomcat; the AJAX call returns <code>True</code> if the Android app authenticated. Advantage: client side, minimal implementation on the server, no thread blocking on the server. Disadvantages: During the waiting period, you have to make frequent calls (maybe one a second - the user will not notice this latency) which amounts to <em>a lot</em> of calls and some additional load on the server.</p> <p>For approach 2, there is again choice:</p> <ol> <li><p>Block the thread with an <code>Object.wait()</code> optionally storing the node ID, IP or other identifier in a shared data store: If so, the node receiving the Android app authorization needs to:</p> <ol> <li>Either find the node that is currently blocking or broadcast to all nodes in the cluster</li> <li><p>For each node in 1. above, send a message that identifies the user session to unblock. The message could be sent via:</p> <ol> <li>Have an internal-only servlet on each node - this is called by the servlet performing the Android app authorization. The internal servlet will call <code>Object.notify</code> on the correct thread</li> <li>Use a JMS pub-sub message queue to broadcast to all members of the cluster. Each node is a subscriber that, on receipt of a notification will call <code>Object.notify()</code> on the correct thread.</li> </ol></li> </ol></li> <li><p>Poll a data store until the thread is authorized to continue: In this case, all the Android app needs to do is save the state in a SQL DB </p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload