We Stealz Your Dataz
[WeStealzYourDataz.git] / index.html
1 <!DOCTYPE HTML>
2 <html>
3  <head>
4   <meta charset="utf-8"/>
5   <title>
6    Made with Remarkable!
7   </title>
8   <link href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/styles/github.min.css" rel="stylesheet"/>
9   <script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/highlight.min.js">
10   </script>
11   <script>
12    hljs.initHighlightingOnLoad();
13   </script>
14   <script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript">
15   </script>
16   <script type="text/javascript">
17    MathJax.Hub.Config({"showProcessingMessages" : false,"messageStyle" : "none","tex2jax": { inlineMath: [ [ "$", "$" ] ] }});
18   </script>
19   <style type="text/css">
20    @import url(http://fonts.googleapis.com/css?family=Indie+Flower);body{font-family:Indie Flower,Daniel,cursive}h1,h2{text-align:center}blockquote{margin:1.5em 10px;padding:.5em 10px}blockquote:before{color:#000;content:open-quote;font-size:2em;line-height:.1em;margin-right:.25em;vertical-align:-.4em}blockquote:after{color:#000;content:close-quote;font-size:2em;line-height:.1em;margin-left:.25em;vertical-align:-.4em}blockquote p{display:inline}hr{border:0;border-top:dashed 2px gray}table{padding:0}table tr{border-top:1px solid #ccc;background-color:#fff;margin:0;padding:0}table tr:nth-child(2n){background-color:#aaa}table tr th{font-weight:700;border:1px solid #ccc;text-align:left;margin:0;padding:6px 13px}table tr td{border:1px solid #ccc;text-align:left;margin:0;padding:6px 13px}table tr td :first-child,table tr th :first-child{margin-top:0}table tr td:last-child,table tr th :last-child{margin-bottom:0}
21   </style>
22  </head>
23  <body>
24   <h1 id="we-stealz-your-dataz-wsyd-social-network">
25    We Stealz Your Dataz (WSYD) social network
26   </h1>
27   <p>
28    This document is created as
29    <code>
30     index.md
31    </code>
32    in Markdown text. It can be manually converted to HTML using pandoc with the command:
33   </p>
34   <pre><code>pandoc --standalone --from=markdown --to=html5 --output=index.html index.md
35 </code></pre>
36   <h2 id="introduction">
37    Introduction
38   </h2>
39   <p>
40    In this Java project I wanted to challenge myself to use some of the same concepts I’ve used in previous C++ projects in order to contrast and understand the different approaches taken in both languages.
41   </p>
42   <p>
43    The project criteria already suggested to me that the design would need to implement
44    <strong>
45     multi-threading
46    </strong>
47    and as there was no specific requirement to use a database I opted to use
48    <strong>
49     object serialization
50    </strong>
51    which would provide two useful functions: persisting the member data to file and passing pure java objects over the network.
52   </p>
53   <p>
54    I adopted the
55    <strong>
56     Javadoc
57    </strong>
58    standard for all my code annotations and as a result the
59    <strong>
60     <a href="dist/javadoc/index.html">
61      entire code base is consistently documented
62     </a>
63    </strong>
64    in the same style as the Java API in HTML without requiring me to write separate documentation.
65   </p>
66   <p>
67    I used
68    <a href="Made with Remarkable!">
69     <strong>
70      Remarkable
71     </strong>
72    </a>
73    , a
74    <a href="http://daringfireball.net/projects/markdown/syntax">
75     <strong>
76      Markdown text
77     </strong>
78    </a>
79    editor with live HTML preview, to create this report and allow the report and the Javadoc to link together as one HTML web.
80   </p>
81   <p>
82    After becoming familiar with the NetBeans IDE I explored its Test-Driven Development (TDD) support using
83    <strong>
84     <a href="http://junit.org">
85      Junit
86     </a>
87    </strong>
88    and found it provided valuable feedback on bugs in my code that were not obvious before the tests were written.
89   </p>
90   <p>
91    I set out to implement the assessment criteria specified for a
92    <strong>
93     First class
94    </strong>
95    result.
96   </p>
97   <h2 id="design">
98    Design
99   </h2>
100   <p>
101    The criteria requires a minimum of three separate executable processes: GUI User client, Social Server and Chat Server. I opted to add a fourth: GUI Server Management client. This allowed me to implement the Social and Chat servers as true
102    <strong>
103     background service daemons
104    </strong>
105    and have them communicate with the GUI Server Management client over the network.
106   </p>
107   <p>
108    As well as displaying log messages received from the servers the GUI Server Management client allows the
109    <strong>
110     independent restarting or stopping
111    </strong>
112    of each server.
113   </p>
114   <p>
115    The GUI User client makes extensive use of Swing components. The NetBeans IDE is responsible for generating most of the GUI skeleton code for handling user actions via
116    <code>
117     ActionEvent
118    </code>
119    and
120    <code>
121     PropertyChange
122    </code>
123    event listeners and several function-specific child windows and dialogs for presentation during log-in, profile editing, chat and configuration. After the GUI skeleton code was complete I added support for the network services background threads and then implemented the links between them and the the GUI components.
124   </p>
125   <p>
126    Since the criteria requires a range of network functionality shared across clients and servers I implemented a
127    <strong>
128     <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/package-frame.html">
129      common network library
130     </a>
131    </strong>
132    . This network library, and the server services it implements, needs to support
133    <strong>
134     multi-threading
135    </strong>
136    especially on the client since listening for incoming connections is an
137    <strong>
138     operation that blocks
139    </strong>
140    in the operating system kernel. If those blocking operations were performed on the GUI Event Dispatch thread it would cause
141    <strong>
142     poor response
143    </strong>
144    in the user interface.
145   </p>
146   <p>
147    Fortunately the
148    <a href="http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html">
149     <code>
150      javax.swing.SwingWorker
151     </code>
152    </a>
153    class was designed especially for this purpose. As it implements the
154    <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html">
155     <code>
156      java.lang.Runnable
157     </code>
158    </a>
159    interface too it made the
160    <strong>
161     perfect base class
162    </strong>
163    for my own
164    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html">
165     <code>
166      NetworkServerAbstract
167     </code>
168    </a>
169    class because I could use it for both service daemon (non-GUI) and client (Swing GUI) applications.
170   </p>
171   <p>
172    I considered adopting an existing network protocol (or designing my own) for the communications between servers and clients and clients with clients. I considered Hyper Text Transport Protocol (HTTP) for the server to client connections. For client chat I looked at Internet Relay Chat (IRC) and its related Client To Client Protocol (CTCP) and the Direct Client Connect (DCC) sub-protocol (that supports file transfer) which together implement a server-mediated peer-to-peer (P2P) approach as a chat solution that has been in use since the 1990s.
173   </p>
174   <p>
175    The problem I found was that each
176    <em>
177     type
178    </em>
179    of communication would require a different protocol to be implemented. As well as requiring a lot of work to implement this had the risk of introducing
180    <strong>
181     subtle hard-to-find runtime bugs
182    </strong>
183    in the live communications.
184   </p>
185   <p>
186    I investigated using some form of pre-existing
187    <a href="http://blog.codepath.com/2013/01/06/asynchronous-processing-in-web-applications-part-2-developers-need-to-understand-message-queues/">
188     <code>
189      Message Queue
190     </code>
191    </a>
192    implementation such as Java
193    <code>
194     Enterprise Edition (EE)
195    </code>
196    <a href="http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html">
197     <code>
198      Java Message Service (JMS)
199     </code>
200    </a>
201    but decided most of these would be too over-engineered and complex for my requirements and therefore I would
202    <strong>
203     create a simple message queue
204    </strong>
205    implementation myself.
206   </p>
207   <p>
208    I’d already decided I’d use serialization for persisting member data and after looking at some examples of how easy it is to
209    <strong>
210     serialize Java objects
211    </strong>
212    over any kind of stream, including
213    <strong>
214     network streams
215    </strong>
216    , I realised it could make network communications reliable and consistent with minimal additional code both at run-time and at coding time since Java provides serialization as part of the Virtual Machine. The only requirement to support serialization is that each class of object that would be passed over the network should implement
217    <a href="http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html">
218     <code>
219      java.io.Serializable
220     </code>
221    </a>
222    - which usually only requires a single addition:
223   </p>
224   <pre><code>public MyClass extends SomeClass implements java.io.Serializable {
225 </code></pre>
226   <p>
227    This design decision makes it as
228    <strong>
229     easy to pass an image or other file-type over the network
230    </strong>
231    as it does to send simple text and with 100% reliability. In my implementation I wrapped each object being sent over the network in a
232    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html">
233     <code>
234      NetworkMessage
235     </code>
236    </a>
237    wrapper class that contains additional information such as sender and target service and the
238    <em>
239     intent
240    </em>
241    of the message.
242   </p>
243   <p>
244    A further issue I considered was
245    <strong>
246     how the clients would discover the servers
247    </strong>
248    . Since in the lab setting there will be no facility for adding Domain Name System (DNS) records to the local DNS server zone file it would require either:
249   </p>
250   <ol>
251    <li>
252     hard-coding an IP address into the source-code and rebuilding the code each time the project was demonstrated
253    </li>
254    <li>
255     providing for the user to enter the IP address manually when each application starts
256    </li>
257    <li>
258     Using some form of automatic network discovery
259    </li>
260   </ol>
261   <p>
262    I decided to opt for (3) implemented using
263    <a href="http://docs.oracle.com/javase/7/docs/api/java/net/MulticastSocket.html">
264     <code>
265      java.net.MulticastSocket
266     </code>
267    </a>
268    with a fall-back to (2) in case automatic discovery fails.
269   </p>
270   <p>
271    Clients will create long-running Transmission Control Protocol (TCP) connections to the server for passing serialized
272    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html">
273     <code>
274      NetworkMessage
275     </code>
276    </a>
277    objects back and forth, starting with log-in.
278   </p>
279   <p>
280    Clients can discover each other via the Organisation-scope Multicast group, or if it isn’t available, by requests to the Chat server which will mediate chat authorisations.
281   </p>
282   <p>
283    I implemented the asynchronous update from server to client requirement with User Datagram Protocol (UDP). If the Multicast group isn’t active the update service will fall-back to using Unicast to each known client.
284   </p>
285   <p>
286    To avoid using something other than object serialization for sending notifications via UDP packets (which do not have support for streams) I used the
287    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html">
288     <code>
289      NetworkMessage
290     </code>
291    </a>
292    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#serialize(uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage)">
293     <code>
294      serialize()
295     </code>
296    </a>
297    and
298    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#deserialize(byte[])">
299     <code>
300      deserialize()
301     </code>
302    </a>
303    methods to convert the object to and from a
304    <code>
305     byte[]
306    </code>
307    that can be transported by
308    <a href="http://docs.oracle.com/javase/7/docs/api/java/net/DatagramPacket.html">
309     <code>
310      java.net.DatagramPacket
311     </code>
312    </a>
313    .
314   </p>
315   <h2 id="functionality">
316    Functionality
317   </h2>
318   <p>
319    <mark>
320     TODO:
321    </mark>
322    Describe each application’s core functionality and stand-out features
323   </p>
324   <h3 id="social-server">
325    Social Server
326   </h3>
327   <h3 id="chat-sever">
328    Chat Sever
329   </h3>
330   <h3 id="gui-server-management-client">
331    GUI Server Management client
332   </h3>
333   <h3 id="gui-user-client">
334    GUI User client
335   </h3>
336   <h2 id="code">
337    Code
338   </h2>
339   <p>
340    I began by designing and creating the skeleton GUI client using the NetBeans IDE.
341   </p>
342   <p>
343    Questions that came up during GUI client design led to coding
344    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html">
345     <code>
346      WSYD_Member
347     </code>
348    </a>
349    , the class that wraps the data structure representing each member of the WSYD social network. As well as data storage I implemented a static CSV parser
350    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#createWSYD_Member(java.lang.String)">
351     <code>
352      createWYSD_Member()
353     </code>
354    </a>
355    , the inverse method
356    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#toString()">
357     <code>
358      toString()
359     </code>
360    </a>
361    , and support for the
362    <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html">
363     <code>
364      java.lang.Comparable
365     </code>
366    </a>
367    interface in
368    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#compareTo(uk.ac.ntu.n0521366.wsyd.libs.WSYD_Member)">
369     <code>
370      compareTo()
371     </code>
372    </a>
373    . I inherited serialization for free because all the attribute classes already support the
374    <a href="http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html">
375     <code>
376      java.io.Serializable
377     </code>
378    </a>
379    interface.
380   </p>
381   <p>
382    The networking library was the next task. I investigated Java’s networking support and looked at several code snippets and examples at sites such as
383    <em>
384     StackOverflow
385    </em>
386    as well as the official Java API documentation. I realised there were two requirements: the network services themselves, and the object passing.
387   </p>
388   <p>
389    Objects being passed need to encode the destination. For example, a “
390    <em>
391     Friend Is Online
392    </em>
393    ” notification needs to be handled by a client method that knows what to do with that information. The network services only deal with transport not context. Therefore
394    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html">
395     <code>
396      NetworkMessage
397     </code>
398    </a>
399    objects know their
400    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#getSender()">
401     <code>
402      sender
403     </code>
404    </a>
405    ,
406    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#setTarget(java.lang.String)">
407     <code>
408      target
409     </code>
410    </a>
411    and the
412    <strong>
413     <code>
414      intent
415     </code>
416    </strong>
417    -
418    <code>
419     java.lang.String
420    </code>
421    s that allow received messages to be dispatched by the server service to the correct handler and for acknowledgements to be sent in return.
422   </p>
423   <p>
424    The mechanism for passing received objects from the server service to the GUI (or server process) implements a custom event
425    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEvent.html">
426     <code>
427      NetworkMessageEvent
428     </code>
429    </a>
430    which extends
431    <a href="http://docs.oracle.com/javase/7/docs/api/java/util.EventObject.html">
432     <code>
433      java.util.EventObject
434     </code>
435    </a>
436    and adds  interface
437    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEventGenerator.html">
438     <code>
439      NetworkMessageEventGenerator
440     </code>
441    </a>
442    to
443    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html">
444     <code>
445      NetworkServerAbstract
446     </code>
447    </a>
448    which registers objects of classes that implement the
449    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEventListener.html">
450     <code>
451      NetworkMessageEventListener
452     </code>
453    </a>
454    interface. These objects are notified when a new
455    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html">
456     <code>
457      NetworkMessage
458     </code>
459    </a>
460    is received.
461   </p>
462   <p>
463    The network server classes all inherit their core functionality from
464    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html">
465     <code>
466      NetworkServerAbstract
467     </code>
468    </a>
469    . Common functionality implemented here includes
470    <a href="http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html">
471     <code>
472      javax.swing.SwingWorker
473     </code>
474    </a>
475    multi-threading,
476    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEvent.html">
477     <code>
478      NetworkMessageEvent
479     </code>
480    </a>
481    dispatching, the socket listener main loop in
482    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#doInBackground()">
483     <code>
484      doInBackground()
485     </code>
486    </a>
487    , logging, and unsolicited outbound message queuing via
488    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#queueMessage(uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage)">
489     <code>
490      queueMessage()
491     </code>
492    </a>
493    and
494    <a href="dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#dequeueMessage()">
495     <code>
496      dequeueMessage()
497     </code>
498    </a>
499    .
500   </p>
501   <p>
502    The implementing classes
503    <code>
504     NetworkServerTCP
505    </code>
506    ,
507    <code>
508     NetworkServerUDP
509    </code>
510    and
511    <code>
512     NetworkServerMulticast
513    </code>
514    add minimal code via method overrides to support protocol specific functionality.
515   </p>
516   <p>
517    <mark>
518     TODO:
519    </mark>
520    discuss other classes and notable features and coding/learning experiences
521   </p>
522   <p>
523    I used NetBeans
524    <strong>
525     Action Items
526    </strong>
527    to keep track of
528    <code>
529     TODO:
530    </code>
531    and
532    <code>
533     FIXME:
534    </code>
535    outstanding tasks, and
536    <code>
537     XXX:
538    </code>
539    to call attention to important notes.
540   </p>
541   <h2 id="testing">
542    Testing
543   </h2>
544   <p>
545    I used the NetBeans-generated
546    <code>
547     Junit version 4
548    </code>
549    test class templates as the basis for my
550    <strong>
551     Unit Tests
552    </strong>
553    , creating
554    <strong>
555     close to 100% coverage
556    </strong>
557    of the non-network library code. I didn’t write tests for network connections functionality although they would have been very useful due to the amount of time, and the difficulty, I estimated it would require to develop them - much more than writing the network library itself.
558   </p>
559   <p>
560    <mark>
561     TODO:
562    </mark>
563    add examples of bugs the testing revealed and experiences in writing the more complicated test cases.
564   </p>
565   <h2 id="bibliography">
566    Bibliography
567   </h2>
568   <p>
569    This is a list of many, but not all, of the very many resources I looked at in developing this project. Some were of more use than others but all of these contributed something to the development, design and coding.
570   </p>
571   <h3 id="references">
572    References
573   </h3>
574   <p>
575    <a href="http://en.wikipedia.org/wiki/Multicast_address#Administratively_Scoped_IPv4_Multicast_addresses">
576     Administratively Scoped IPv4 Multicast Addresses
577    </a>
578   </p>
579   <h3 id="html-formatted-note-taking">
580    HTML formatted note taking
581   </h3>
582   <p>
583    <a href="http://pandoc.org/demo/example9/pandocs-markdown.html">
584     Pandoc extended Markdown syntax
585    </a>
586   </p>
587   <p>
588    <a href="http://daringfireball.net/projects/markdown/syntax">
589     Markdown syntax
590    </a>
591   </p>
592   <h3 id="netbeans-ide">
593    NetBeans IDE
594   </h3>
595   <p>
596    <a href="http://stackoverflow.com/questions/15922390/netbeans-how-to-change-author">
597     How to configure \@author tag
598    </a>
599   </p>
600   <p>
601    <a href="https://netbeans.org/kb/docs/java/junit-intro.html#Exercise_20">
602     Writing JUnit tests
603    </a>
604   </p>
605   <h3 id="java-documentation">
606    Java documentation
607   </h3>
608   <p>
609    <a href="http://docs.oracle.com/javase/7/docs/index.html">
610     Java Platform Standard Edition 7 Documentation
611    </a>
612   </p>
613   <p>
614    <a href="http://docs.oracle.com/javase/7/docs/api/">
615     Java SE 7 API
616    </a>
617   </p>
618   <p>
619    <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html">
620     Controlling Access to Members of a Class
621    </a>
622   </p>
623   <h3 id="java-generics">
624    Java Generics
625   </h3>
626   <p>
627    <a href="https://docs.oracle.com/javase/tutorial/java/generics/">
628     Java Tutorials: Generics
629    </a>
630   </p>
631   <p>
632    <a href="https://docs.oracle.com/javase/tutorial/extra/generics/index.html">
633     Java Tutorials: Generics (by Gilad Bracha)
634    </a>
635   </p>
636   <h3 id="serialization">
637    Serialization
638   </h3>
639   <p>
640    <a href="http://www.javaworld.com/article/2077539/learn-java/java-tip-40--object-transport-via-datagram-packets.html">
641     Serialize Object over UDP
642    </a>
643   </p>
644   <p>
645    <a href="http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/">
646     Deep cloning techniques
647    </a>
648   </p>
649   <p>
650    <a href="http://stackoverflow.com/questions/8642012/why-should-a-comparator-implement-serializable">
651     Why should a Comparator implement Serializable
652    </a>
653   </p>
654   <h3 id="multi-threading">
655    Multi-threading
656   </h3>
657   <p>
658    <a href="http://wenda.soso.io/questions/2765593/using-swingworker-to-implement-a-udp-client-server">
659     Using SwingWorker to implement a UDP Client/Server
660    </a>
661   </p>
662   <p>
663    <a href="http://www.tutorialspoint.com/javaexamples/net_multisoc.htm">
664     Multi-threaded Network Server
665    </a>
666   </p>
667   <p>
668    <a href="http://stackoverflow.com/questions/782265/how-do-i-use-swingworker-in-java">
669     How do I use SwingWorker in Java
670    </a>
671   </p>
672   <p>
673    <a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/">
674     Concurrency in Swing (multi-threading for background tasks)
675    </a>
676   </p>
677   <p>
678    <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html">
679     Synchronized Methods
680    </a>
681   </p>
682   <p>
683    <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html">
684     Synchronized Statements
685    </a>
686   </p>
687   <h3 id="network">
688    Network
689   </h3>
690   <p>
691    <a href="https://docs.oracle.com/javase/tutorial/networking/nifs/parameters.html">
692     Getting Network Interface Parameters
693    </a>
694   </p>
695   <p>
696    <a href="http://www.markhneedham.com/blog/2013/07/14/java-testing-a-socket-is-listening-on-all-network-interfaceswildcard-interface/">
697     Testing a socket is listening on all network interfaces/wildcard interface
698    </a>
699   </p>
700   <p>
701    <a href="https://blogs.oracle.com/CoreJavaTechTips/entry/socket_logging">
702     Socket Logging (network logger)
703    </a>
704   </p>
705   <h3 id="tutorials">
706    Tutorials
707   </h3>
708   <p>
709    <a href="http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html">
710     How to Write Doc Comments for the Javadoc Tool
711    </a>
712   </p>
713   <p>
714    <a href="http://examples.javacodegeeks.com/core-java/io/java-imageio-write-image-to-file/">
715     Write Image to File
716    </a>
717   </p>
718   <p>
719    <a href="http://stackoverflow.com/questions/1318980/how-to-iterate-over-a-treemap">
720     Iterating over a TreeMap
721    </a>
722   </p>
723   <p>
724    <a href="http://stackoverflow.com/questions/285177/how-do-i-call-one-constructor-from-another-in-java">
725     How do I call one constructor from another in Java
726    </a>
727   </p>
728   <p>
729    <a href="http://stackoverflow.com/questions/3108297/james-goslings-explanation-of-why-javas-byte-is-signed">
730     James Gosling’s explanation of why Java’s byte is signed
731    </a>
732   </p>
733   <p>
734    <a href="http://stackoverflow.com/questions/7300676/when-to-use-flush-in-java">
735     When to use flush() in Java
736    </a>
737   </p>
738   <p>
739    <a href="http://stackoverflow.com/questions/1816673/how-do-i-check-if-a-file-exists-in-java">
740     How do I check if a file exists in Java
741    </a>
742   </p>
743   <p>
744    <a href="http://stackoverflow.com/questions/767372/java-string-equals-versus">
745     Java String.equals() versus ==
746    </a>
747   </p>
748   <p>
749    <a href="http://stackoverflow.com/questions/3983360/calculating-byte-size-of-java-object">
750     Calculating byte-size of Java object
751    </a>
752   </p>
753   <p>
754    <a href="http://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html">
755     Mr. Happy Object teaches custom events
756    </a>
757   </p>
758  </body>
759 </html>