So you know how to code…

Most entry programmers learn how to program procedurally first, understanding that program instructions run one after another. Subsequently they learn control flow (if/else/for/while) and functions to modularize their code.

With these, one can almost write amazing programs. So where should we go from here?

For OO langauges like Java/.Net, I think there are two directions from here. One is to go lower level, to understand the foundation of the language, syntax, types, basic classes, including OO concepts like encapsulation, inheritance and polymorphism. This can be translated towards the Java Programmer certification. The other is to go higher level, to understand software architecture, data structures and design patterns. This will allow for better software that may be more efficient, maintainable and/or scalable.

The two directions are not XOR (one but not the other). Instead they are both as important. Looking at how other people write may also help in grasping style and technique, even identifying anti-patterns (style/design that should be AVOIDED).

JMF

JMF allows you to work with media – audio and video. Working with here means input (reading in from file/device), processing (encoding/decoding/multiplexing) and output (to file/network/screen).

Nitty-gritty details are mostly shielded from the programmer, yielding a clean interface for use. In fact once we completed our audio streaming, converting it to video streaming was almost a one-liner change for the Format class. However since we need to separate the components clearly (content vs transport), we had to try tear JMF apart. In fact JMF handled so much of RTP that we just need to give it a ip/port and off it goes.

The flexibility of the framework theoratically allows all forms of media to be processed, however it is currently limited to certain codecs and formats, maybe due to the need to interact with native hardware/OS, or licensing issues. We had some problems interacting with webcams, likely issue to be the webcam drivers are application specific, only their own apps know how to access the webcam. Hopefully more webcam providers make their cams OS-generic, such that it can be recognized by Windows. This way it is more likely JMF will be able to detect it.

Another issue we bumped into is that JMF binds to AWT. For displayable components like Video visual and Video controls, it is returned as an AWT component. Since we use SWT it could be a chore to code bridges.

Because of performance, JMF comes in certain performance packs, which probably have certain algorithms in native code so it runs faster/better by making use of the OS/hardware. (accelerator? processor opcodes?)

C++ compilation

Java goes through a single compilation step to translate source code (.java) to bytecode (.class). C++ goes through a few more steps to reach binary code. (.exe/.dll)

Source Code (.c) -> PREPROCESSOR -> COMPILER -> Assembly Code (.o)
Assembly Code (.o) -> LINKER (+Libraries) -> Executable Code (.exe/.dll)

The Preprocessor processes # preprocessor directives. For example this will #include the contents of the header file into this position. #define will define pre-processor variables, do substitution and include only relevant #ifdef sections.

The compiler will then translate source code into assembly code, similar to the Java compiler step. This step will catch all syntax errors. The compiler should be able to locate all #include files through the additional include directories specified by the /I command line.

The linker then produces the binary for the assembly code. Linker errors can occur here if the compiled libraries referenced are not found.

The end result of a compilation/linking is usually an .exe file, which can be directly executed on a Windows machine. There are also options to create a dynamic library (dll) or a static library (lib). A dynamic library is looked up at runtime, and is usually shared among multiple programs. A static library is compiled into the executable directly, and does not require the existance of the lib during execution. A program referencing a DLL library will be smaller than one referencing a LIB, since the DLL code is located inside the DLL.

To call another method, the method must be “declared” before the calling line. Declaration may mean the actual method implementation, or just a “header” specifying the method name and parameters. Thus the use of #include files often at the top which includes the method definitions so they may be referenced. Actual implementation is later linked using the linker.

Testing

(Warning: This is an incoherent post – there has been no attempt to organize the paragraphs such that it flows in a thoughtful manner. These thoughts just poured out of my mind at that moment in time…)

Software Testing is important to maintain the quality of software produced. Good testing is difficult, hindered by time, management, and possibly testing techniques.

To me, good tests must be documented. This may come in the simple form of documented test cases, although I seriously prefer automated tests to perform those test cases. Automated tests are usually run more often, as compared to needing people to sit and key in pre-defined input and check outputs.

Using human as testers have an additional advantage, they help to introduce human error. Good software should be able to recover and remain stable under human error conditions (prefably all kinds of error conditions) To simulate this situation, automated tests should introduce elements of randomness. For example, free text input such as text boxes should be tested with all possible input characters from the keyboard, as well as random combination of input keys. The former ensures that the system is able to handle all characters, and the latter simulates “a monkey banging the keyboard”.

Applying randomness in testing catches more errors than if you always used fixed input, say “John Smith” for full names. Or even worse, “test” as a full name. Can your system accept “Thomas D’Cruz”? Or a 94-character long indian full name? Yet once you catch an error with random input, are you able to reproduce the same input to verify that your system has handled that case?

This is a common flaw when doing automated random testing. Test sequences MUST be logged (to files) so that the errorneous test can be repeated with the exact same input so that the bug can be verified (as a bug) and verified (as fixed). Although threaded programs may not return you the same output given those same input, the information will also serve as a debug log that will assist you in reproducing the error. If the error cannot be reproduced, it cannot be verified.

Using frameworks such as JUnit will assist you in combining several tests into a test suite so that automatic regression testing is simplified. Hopefully every refactor or change to the base source can be accompanied by a test run.

New beginning

No entry for the last week, was getting used to my new work environment. Due to the shift to technologies like SWT and XMPP, my posts will be rather geared towards those topics. For now, I’ll need to understand SWT:

– How to access shells and displays correctly
– How to create and use simple SWT widgets
– Managing/swtiching between windows and composites
– SWT layouts, maybe creating SWT-AWT layout adapters

Annotations in J2SE 5.0

Among the new features available (enhanced for loop, generics) in J2SE 5.0 (or 1.5, or Tiger) is the annotations functionality. I have always been hoping to come across simple introduction to such stuff and it came in this issue’s Tech Tips.

Annotations allow us to associate metadata with program elements: metadata is information that describe the program elements, and the elements may be methods or member variables in a class. Annotations are defined using a @xxx tag before the element.

The most common and obvious use is the @Deprecated tag. This tag declares the method as deprecated: it is outdated and kept for backward-compatibility. When the method is called from another class, a warning will be generated.

Other annotations defined in Tiger are @Override and @SuppressWarnings. @Override insists that you are overriding a method in case of a typo or wrong method signature, similar to C#’s Overrides modifier. @SuppressWarnings will tell the compiler not to tell you about certain warnings such as deprecation or unchecked casts in the method. It can be used with some options, such as @SuppressWarnings(“fallthrough”). This looks a lot like .Net’s annotations.

In addition, the tip mentioned that custom annotations may be defined, probably something like XDoclet. That could be something else I could learn in the future. The tip also contains a link to a book “Effective Java Programming Language Guide” by Joshua Bloch, which contains 57 Java tips. Well likely could be the next tip review here.

Quote

“If the cost of breaking into a system is significantly higher than the benefits gained by attacking the system, and the cost of protecting the system is lower than the value of what is being protected, then we call a system secure.”

– Jian Zhong, senior software architect, ActioNet Inc.

Although posted once on the Starbean forum before, I felt that this quote is very apt to justify for how much security is desired. Perfection cannot be achieved; there is no unbreakable system. Spending too little on security can compromise the system, overspending waste resources, time and money, with no further benefits.

[1] http://www.javaworld.com/javaworld/jw-0 … ee-p3.html

JavaMail / Activation

Javamail is the standard answer for mail access using Java. Currently supported protocols are SMTP, POP3 and IMAP. In short it means you can send outgoing mail using SMTP, receive email using POP3, and I’m not familiar with IMAP, though I remember having it in my Networking course. I think IMAP’s mails are stored and manipulated on the server, as opposed to POP3 mails which are downloaded (generally).

Using the classes was rather easy to me, partly because I am familiar with the SMTP/POP3 protocol (telnet and manually send/receive mails). Might be a good experience for you to try it (the telnet) too, to understand protocols on top of TCP. Online examples also help me to cut&paste code quickly.

Once peculiar thing is that Javamail depends on the JavaBeans Activation Framework (JAF). I’ve seen it around for some time, but never really knew what it was and what it does. I finally learnt that the activation framework handles MIME types (but how?) and so was useful in the JavaMail package. JavaMail was the only library that really used activation for a few years until web services came along. Web services which uses SOAP calls had MIME types as their encoding.

JAXP – Java API for XML Processing

XML has grown to become important over the years, and it is natural that Java gradually adds support to it. Started from external packages in JDK1.3, core JDK1.5 now has JAXP 1.3 in it. JDK1.4 had JAXP version 1.2. Now java.net offers JAXP 1.3 as a standalone package so that JDK1.3 can make use of JAXP as well. However the bundle has no technical support (use at your own risk).

JAXP contains API to CRUD XML, both DOM and SAX. Thats alot of acronyms in one sentence… For DOM you create or obtain a Document, then manipulate elements and attributes within the document. DOM manipulation works generally the same for both Java and Javascript, since they adhere to the DOM specifications. For SAX you hook up handlers to perform tasks when start/end tags are encountered.

Transformers in the JAXP package allows you easily transform XML from one form to another, though I’ve only tried transforming it to a file. Handy output properties during transformation allow formatted output to make it more readable.

This post is purposely made very abstract — commenting very generally on JAXP. However it should contain enough keywords to allow searching for how to perform certain tasks. Dwelling into XML, DOM and SAX can potentially drag very long, with little benefits since there’s so much information out there already.

Best Practices – General

Other topics in the book did not have significant points (at this moment in time) for me to bring up. However certain bits and pieces keep recurring throughout the topics and are worth mentioning:

Consider Internationalization From the Start

If you’re doing an “Enterprise” application, always I18N your Strings. Especially on the JSPs. For database design, locale-specific fields should be normalized to another table with and additional locale column.

Design First, Optimize Later

Make sure you have a good design before you think about how to make your code run better. Don’t keep optimizing your code, let it go once it works (i.e. passes test case). Instead of worrying how well your code runs, think of the other business functions you have yet to fulfil.

In the end the code may not need to be optimized (maybe due to good design). Even if there is a need to, good design makes it easy to perform such optimizations. If optimization is considered first, the benefit may not be necessary, or further optimization is difficult later and hindered by poor design.