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