Monday, September 29, 2008

Stack + Emma + JUnit

Premise:
In this experiment I'll take a look at testing techniques and programming coverage using both JUnit and Emma. All programs in this experiment will be edited and tested using Eclipse with built-in integration of JUnit's plugin. Emma is an open source Java coverage tool that integrates well with Ant. I will be running Emma and building my subsequent tests from command prompt (using Ant), while making changes that reflect improving coverage in Eclipse. The program below is the remanence of my previous "Stack" post. I will be using the Stack program as the basis of running my unit tests.

Improving Coverage:
The goal of this experiment is to improve code line coverage. Emma makes this very easy to accomplish by using a few commands from my previous setup of Ant. After executing the following build command: "ant -f emma.build.xml," Emma conveniently gives quantified metrics for class, method, block and line converage. Emma is also nice enough to provide an html (emma/coverage.html) summary describing the covered, partially covered and uncovered code line executions. It also indicates the file and highlights each line with a neat color scheme: green - fully covered, yellow - partially covered and red - uncovered.
Initial Emma Coverage Metrics:
  • class: 100% (3/3)
  • method: 73% (8/11)
  • block: 69% (65/94)
  • line: 75% (15/20)
Analysis of uncovered lines are specified by filename, percentage of coverage and methods containing non-executed code lines:
  1. ClearStack.java, (50%), getTop() & isEmpty()
  2. Stack.java, (79%), toString() & top()
I proceeded to first improve the most trivial test cases indicated by Emma for files Stack.java and ClearStack.java. I was able to raise the line-level coverage to 99.8%. However, I was stuck at a partially uncovered item in the isEmpty() method of the ClearStack class. In this case Emma has no further input other than to say that this is a line that needs more tests. It took me a while to notice that the isEmpty method needed to thoroughly be tested for both true and false cases, when initially I only had one. This minimal unit test boosted my line-level status to 100% and thus achieving what looks to be good code, right? Unfortunately, I was drawn to notice a couple flawed attributes that adhere from my tests and the confluence of using Emma as a fully trustworthy tool. Although my first intentions of this experiment is to improve code coverage, I've also come to realize Emma's vita flaw that could potentially separate good testers from the bad. I've also notice how Emma's tricks the programmer into thinking about only achieving code coverage, rather than helping the coder gain greater insight into their code analysis. Even at 100% coverage, my tests are not completely tested in terms of its context. For example, one unit test required that I needed to test the toString() method in the Stack class. In my TestStack class, I did the toString() method test by simply asserting the expected output while having prior knowledge of what toString() must express.
Here's my test case: assertEquals("Testing stack toString", "[Stack []]", stack.toString());
I found that this test builds upon the assumption that stack.elements works. I needed to conclude to myself that this statement truely executes without flaw, so I tested the List's toString method.
2nd test case: assertEquals("Testing list toString", "[]", stack.elements.toString());
It turns out that my curiousity only led me to remember that Collections have a default format of outputing elements in a form of an array-like string, enclosed with square-brackets. The point of this assertion was to distinguish the mindset of good and bad testers. Good being the ones who take it a further step by objectively analyzing the hidden points being made by their program, and bad ones who leave after the 100% coverage which may or may not be truely 100% valid.
Overall, Emma is still a great tool that should be used continuously in pre-development to production stages. However, I would not recommend using Emma in the middle of a project, unless the task is minimally affected by the program as a whole.

Here's a link to the final Stack code: stack-anthony.m.du-6.0.930.zip

Conclusion:
I learned the importance of building my programs using some sort of coverage tool. Although, coverage tools evidently determines if our code is tested for certain conditions, it limits us from determining the thorough aspects of what our program is truly expressing in terms of context. Upon questioning the effectiveness of converage tools, such as Emma, I've come to realize that there is no better tool than human analysis. Sure we can ease the pain of manually checking whether or not our code is executing like it should, but we must also take into account for its lack of human ingenuity and influence. Since we wrote the program using our own patterns and processes, we should also rely on our instinct when it comes to assessing our own work. I feel that the usage of Emma should go hand-in-hand in the beginning stages of developing test cases. Again, the concept of incremental programming should be exercised for assuring the quality of your code. As for future use, I would recommend using the integrated plugin called: EclEmma for Eclipse. It works very much like Emma. It also gives visual highlights of what code has been tested or "covered," as well as the usual quantified metrics provided after every build.

Wednesday, September 24, 2008

Automated vs Manual QA (CodeRuler)

Overview:
Simply compare the validity of human QA and automated QA tools on previous CodeRuler project.

Running Ant + CodeRuler:
QA Tool: QA Violation (Comments)

CheckStyle: Line Type Javadoc comment is missing an @author tag. (JavaDoc issue)
CheckStyle: Line contains a tab character. (Format issue)
CheckStyle: Unused @param tag for 'int'. (Logic issue)
CheckStyle: Expected @param tag for ‘x’ or ‘y’ (Logic issue)
CheckStyle: Line is longer than 100 characters. (Format issue)
CheckStyle: Type Javadoc comment is missing an @author tag. (JavaDoc issue)
CheckStyle: 'static' modifier out of order with the JLS suggestions. (Logic issue)
CheckStyle: Missing a Javadoc comment. (JavaDoc issue)
CheckStyle: '}' should be alone on a line. (Format issue)
CheckStyle: First sentence should end with a period. (Format issue)
**CheckStyle errors: 101152 errors across 10 files

PMD: Avoid if (x != y) ..; else ..;
PMD: Avoid unnecessary comparisons in boolean expressions
PMD: Private field 'castle' could be made final; it is only initialized in the declaration or constructor.
PMD: Avoid using if statements without curly braces
PMD: Avoid using implementation types like 'ArrayList'; use the interface instead
PMD: Substitute calls to size() == 0 (or size() != 0) with calls to isEmpty()
PMD: These nested if statements could be combined
PMD: Document empty constructor
PMD: An empty method in an abstract class should be abstract instead
PMD: Return an empty array rather than null.
PMD: Document empty method
PMD: All methods are static. Consider using Singleton instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning.
PMD: Return an empty array rather than null.
**PMD errors: 60 errors across 3 files

FindBugs: 439 lines of code analyzed, in 11 classes, in 2 packages.
**FindBugs errors: 0 errors and 0 warnings!

Conclusion:
Obviously, this would have been a nightmare without some kind of automated tool system for checking styles and coding rules. Upon receiving the numerous style errors, these QA tools give a descriptive audit of exactly when and where each error occurs. Using QA tools helps our code exist in one or many standards depending on the situation. After seeing what a mess things could be when we go against the standard, I'm now leaning more toward coding in a much safer and higher quality standard environment.

Friday, September 19, 2008

Software Quality Assurance

Overview:
Quality Assurance (QA) of code is the basis of source code analysis development. The quintessential part of distributing your code with high quality production standards is that it ensures a good product (reliable, maintainable, and manageable) and enables other organizations to easily pickup your software.

System Requirements:
  • Java: JDK 1.4 or higher
  • OS: Windows, Linux, Unix, or Mac OS X
QA Tools:
  • Ant - "Anther Neat Tool" used to assist programmers in scripting custom automated build process similar to that of "make" for C/C++.
  • CheckStyle - used to help ensure that your Java code adheres to a set of coding standards. (static analysis)
  • PMD - used to enforce certain coding rules. (static analysis)
  • FindBugs - is another static analysis tool that examines your class or JAR files looking for potential problems by matching your bytecodes against a list of bug patterns.
  • JUnit - used to incrementally assert test conditions/statements that presumably matches an expected outcome.
Installation:
The installation process is quite simple once you get the hang of it. Below is a quick walk through of installing the above QA tools on both Mac OS X/Linux platforms:

Mac OS X (Unix) / Linux Users:
** the instructions below can also be tailored for Linux users too, but just with slight differences.

Fortunately for mac users, Java and Ant come pre-installed with the latest version of Mac OS X (10.5.4). All I ended up doing was export the path variables (JAVA_HOME & ANT_HOME) to point to the installed locations on the system. *If you need to install it manually, then you can consult to instructions here.
  • $ cd
  • $ emacs .profile
  • edit file by adding the following:
  • export JAVA_HOME="/Library/Java/Home"
  • export ANT_HOME="/usr/share/ant"
  • save and close the file
  • $ source .profile
  • you can also check to see if your environment variables have been added by typing:
  • $ env
Once you get the hang of just installing one tool, the rest follow the same methodology for both Unix and Linux platforms. Below is a generalized version of installing and updating the environment variables
  • Download and extract: qa_tool (e.g. checkstyle, pmd, findbugs, etc.)
  • $ cd downloads/
  • $ wget qa_tool_url
  • $ unzip qa_tool_version.zip -d /usr/local
  • Update environment variables
  • $ cd
  • emacs .profile
  • add the following env variables
  • export QA_TOOL_HOME="/usr/local/qa_tool"
  • save and close file
  • $ source .profile
Stack + QA:
The program called stack will help us test our newly installed QA tools.
Setup project:
  1. Download project source code here: stack.zip
  2. Extract source project into development directory (workspace in Eclipse)
  3. Open Eclipse and select File>Import, General>Existing Projects into Workspace, select root directory by browsing to where the stack source was extracted, and click on Finish.
  4. Right-click on stack project, Refactor>Rename>stack-(username)
  5. Edit build.xml file by renaming the project name to match "stack-(username)"
Running Ant + QA tools:
At the command prompt/terminal, switch to the location of your stack project folder and run the following Ant commands:
  • ant clean compile
  • ant -f checkstyle.build.xml
  • ant -f dist.build.xml
  • ant -f findbugs.build.xml
  • ant -f javadoc.build.xml
  • ant -f junit.build.xml
  • ant -f pmd.build.xml
  • ant -f verify.build.xml
The last statement should render a BUILD FAILED plus something similar:
:stack-anthony.m.du directory
$ ant -f verify.build.xml

Buildfile: verify.build.xml

clean:
[delete] Deleting directory /Users/admin/Develop/java/stack-anthony.m.du/build

compile:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/classes
[javac] Compiling 5 source files to /Users/admin/Develop/java/stack-anthony.m.du/build/classes

junit.tool:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/junit
[junit] Running edu.hawaii.stack.TestClearStack
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.071 sec
[junit] Running edu.hawaii.stack.TestStack
[junit] Tests run: 2, Failures: 1, Errors: 0, Time elapsed: 0.031 sec

BUILD FAILED
/Users/admin/Develop/java/stack-anthony.m.du/junit.build.xml:18: Test edu.hawaii.stack.TestStack failed

Stack + QA tool fixes:
**description of errors can be found in build directory under tool directory subfolder in html format.
JUnit errors:
junit.framework.AssertionFailedError: Testing stack top of three expected same:<3> was not:<1>
at edu.hawaii.stack.TestStack.testNormalOperation(TestStack.java:37)


**edited top() logic in file: Stack.java

Checkstyle errors:
[checkstyle] /Users/admin/Develop/java/stack-anthony.m.du/src/edu/hawaii/stack/Stack.java:52: Expected an @return tag.
[checkstyle] /Users/admin/Develop/java/stack-anthony.m.du/src/edu/hawaii/stack/Stack.java:79:3: '{' should be on the previous line.


**made fixes to those minor style checks in file: Stack.java

PMD errors:
5 total:
Private field 'one' could be made final; it is only initialized in the declaration
... again for both 'two' and 'three'
**added final to all three declaration statements in file: TestClearStack.java

Avoid using implementation types like 'ArrayList'; use the interface instead
**replaced with List interface declaration in file: Stack.java

Consider simply returning the value vs storing it in local variable 'obj'
**replaced with returning top value instead of storing in file: Stack.java

FindBugs errors:
Method new edu.hawaii.stack.TestClearStack() invokes inefficient new Integer(int) constructor; use Integer.valueOf(int) instead
Method new edu.hawaii.stack.TestStack() invokes inefficient new Integer(int) constructor; use Integer.valueOf(int) instead
**replaced declaration with "Integer.valueOf(int)" in file: TestClearStack.java & TestStack.java

Final Stack + Ant Run:
amd:stack-anthony.m.du admin$ ant -f verify.build.xml
Buildfile: verify.build.xml

clean:
[delete] Deleting directory /Users/admin/Develop/java/stack-anthony.m.du/build

compile:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/classes
[javac] Compiling 5 source files to /Users/admin/Develop/java/stack-anthony.m.du/build/classes

junit.tool:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/junit
[junit] Running edu.hawaii.stack.TestClearStack
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.105 sec
[junit] Running edu.hawaii.stack.TestStack
[junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.015 sec

checkstyle.tool:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/checkstyle
[checkstyle] Running Checkstyle 5.0-beta01 on 5 files

pmd.tool:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/pmd
[echo] PMD found ${pmd.failure.count} problem(s).

findbugs.tool:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/findbugs
[findbugs] Executing findbugs from ant task
[findbugs] Running FindBugs...
[findbugs] Error: The path /usr/share/findbugs-1.3.5/plugin does not seem to be a directory!
[findbugs] No FindBugs plugins could be loaded
[findbugs] Output saved to /Users/admin/Develop/java/stack-anthony.m.du/build/findbugs/findbugs.xml

emma.tool:
[mkdir] Created dir: /Users/admin/Develop/java/stack-anthony.m.du/build/emma
[instr] processing instrumentation path ...
[instr] instrumentation path processed in 90 ms
[instr] [3 class(es) instrumented, 0 resource(s) copied]
[instr] metadata merged into [/Users/admin/Develop/java/stack-anthony.m.du/build/emma/metadata.emma] {in 2 ms}
[junit] Running edu.hawaii.stack.TestClearStack
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.261 sec
[junit] Output:
[junit] EMMA: collecting runtime coverage data ...
[junit]
[junit] Running edu.hawaii.stack.TestStack
[junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.254 sec
[junit] Output:
[junit] EMMA: collecting runtime coverage data ...
[junit]
[report] processing input files ...
[report] 2 file(s) read and merged in 7 ms
[report] writing [xml] report to [/Users/admin/Develop/java/stack-anthony.m.du/build/emma/coverage.xml] ...
[report] writing [html] report to [/Users/admin/Develop/java/stack-anthony.m.du/build/emma/coverage.html] ...
[delete] Deleting directory /Users/admin/Develop/java/stack-anthony.m.du/build/classes

emma.echo:
[xslt] Processing /Users/admin/Develop/java/stack-anthony.m.du/build/emma/coverage.xml to /Users/admin/Develop/java/stack-anthony.m.du/build/emma/coverage.brief.txt
[xslt] Loading stylesheet /Users/admin/Develop/java/stack-anthony.m.du/lib/emma/echo.emma.xsl
[concat] Emma Coverage summary
[concat] class: 100% (3/3)
[concat] method: 73% (8/11)
[concat] block: 69% (65/94)
[concat] line: 75% (15/20)

verify:

BUILD SUCCESSFUL
Total time: 7 seconds

**Here's a link to the new build: stack-anthony.m.du-6.0.921.zip

Conclusion:
I learned that functional software products must also have high quality attributes to pass being labeled a legitimate software product. Besides meeting your company's functional requirements, your software must also verify with quality assurance guidelines. In doing so, software products will be more reliable, maintainable, manageable and even distributed in a timely matter with functionality. In another exploration, I would like to find ways to quantify the quality assurance of source code. The elements of benchmarking your QA is most likely related to process aspects and operations. Perhaps, we could benchmark the number of errors or unsuccessful builds using Ant or some other tool.

Friday, September 12, 2008

CodeRuler Review

First look:
I was assigned to review Daniel and Erin's CodeRuler implementation. In the first trial their ruler outperformed against the migrate ruler by a large margin. Unfortunately they weren't too successful against either smart-splitter or gang-up rulers. In both trials (smart and gang) their ruler performed the same way by killing all enemy peasants before capturing its castle. But by the time they captured the enemy's castle, their first castle gets occupied by knights of the opposing team. While they attempt to re-capture their first castle, no peasants are being produced in their second castle. The opposing ruler keeps producing knights after every turn, thus covering and protecting its castle. Their ruler consistantly battles the knights, but unsuccessfully captures back their first castle. For every battle lost between their knights and the opposing team, the enemy gains battle points and they lose precious points from not claiming land. Although the end result is not fully desired, there is much to learn from this implementation.

Review:
Besides what the CodeRuler strategy implies, this review is based on the creators' coding style and class logic structure.

JavaDocs:
The provided JavaDocs for this MyRuler is quite clear and concise. The method summary is descriptive and easy to follow. You can almost get the gist of what each method is intended to do without looking at any code. However, I would like to see a better introduction to their MyRuler class by describing more of their strategy rather than listing the resulting trial matches.

Class logic and structure:
The overall class structure is simple and easy to follow. Each method provides a readable description that matches the code segments. Method references are nicely encapsulated and broken down into smaller reusable routines. I found it much easier to read each function due to the fact that this group followed good naming conventions. As for the effectiveness of their code, I would have to disagree with one routine called: buildUnits (line # 231). I found this method to be less effective in the process of replicating more peasants at each captured castle. This method stops the production of peasants when the team has only one aquired castle. Due to this limitation, other methods relating to the movement of peasants, such as: optimizePeasantMove (line #413) was wasted during gameplay.

Coding style:
Below are some minor code style violations within the MyRuler class. Most of these errors can be set to fix automatically (format) or easily avoided the next time around.

File

Lines

Violations

Comments

MyRuler

93-94,
100-101,
143-144, *

EJS - 5,

ICS-SE-Eclipse-2

opening brace should be at end of the line that introduced the block.

MyRuler

87, 88, 175, *

ICS-SE-Eclipse-2

Some lines exceed the 100 column max limit.

MyRuler

155, 159, 177, *

EJS – 7

Increase white spaces by placing them between keywords (if, for, while, switch) and parenthesis or braces to better readability of code.

MyRuler

4

ICS-SE-Java-2

Must explicitly specify each class import rather than using a wildcard “*”.

MyRuler

130, 133, 146, *

ICS-SE-Java-10

Needs to pluralize names of collection objects.

MyRuler

96, 117, 168, *

EJS - 49

Omit subject in method description to reduce redundancy.


Final thoughts:
After reviewing the coding style and class structure of this CodeRuler implementation, I learned that documenting your code is just as hard as implementing it. Maybe a better approach to programming would be to self document first and then extract code statements and method functions from that as you build the application. The all important methodologies of "Top-Down" programming would be an essential skill to practice for even the simplest of classes or methods. This should be applied also to the way we program and document our work. Overall, Daniel and Erin did a good job and I hope they take away as much from this as I did.

Here's a link back to each member's blog. There you can also find a link to their source code.

Sunday, September 7, 2008

Lessons learned from Code Ruler

Overview: CodeRuler is a Java programming game based on the Eclipse IDE. It is intended for testing skills in Java programming as well as strategic reasoning. The basic idea of the game is to capture other opponents' castles and claim the most land resources. In doing so, the player with the highest score wins the game!

MyRuler Group Members:

Strategy Outline:
Break knights and peasants into smaller groups with specific objectives.

InsideCastleGuards
  • they will stay and move around inside the castle.
  • they will capture any opponent knight inside the castle.
OutsideCastleGuards
  • they will attempt to capture any knight that moves too close to the castle.
  • they will roam around the castle area capturing opponents peasants.
  • they are the first line of defense against opponent knights.
KnightCastleInvaders
  • they will attempt to capture opponents' castle.
  • they will attempt capture of opponents' peasants that they encounter, but they will not chase them.
  • they will avoid contact with opponents' knights.
LandCapturePeasants
  • they will attempt to capture unoccupied land and opponents' land.
  • they will attempt to avoid capture from opponents' knight.
KnightDistractionPeasants
  • they will attempt to get opponents' knight to chase them, leading the opponents' knight away from the castle.
Sample Game Results:

MyRuler vs MigrateMyRuler vs Gang-upMyRuler vs Split-up
1503-36455-117412-182
2540-32455-140513-119
3462-40370-156466-234


Lessons learned:
  • Eclipse became a good companion for this project. I consider it an all-purpose IDE and has well lived up to its expectations for all backgrounds of developers. The built-in JavaDocs generator has proven to give ease and painless professional documentation.
  • Java still surprises me with its wealth of runtime exceptions. Here's one that I found annoying and difficult to fix: "ConcurrentModificationException" - impermissible for one thread to modify a Collection while another thread is iterating over it.
  • I learned that large projects such as this requires a large amount of effort from each person. It was difficult to have long continuous meetings due to our conflicting schedules, but we found other ways (email or online-chat) to communicate efficiently. 
Improvements:
My first recommendation for future projects that require the service of more than just one person would be to use some kind of source code version control like SVN or GIT. It seems cleaner to do it under version control rather than passing back and forth document copies through email, which requires you or your team member to patch-up manually. I also would recommend a task tracker such as Edgewall's Trac for project management software. A handy project or task management software (preferably open source) would be helpful for keeping track of project goals, tasks and progress.

Reflection:
I enjoyed taking the time to experience programming this Java based strategy game. It proved to be well worth my time and a great learning experience for myself and my group members.

CodeRuler source: du-okada-ancheta.zip

Monday, September 1, 2008

Sun's GlassFish: Application Server Review

Overview:
GlassFish is an opensource project held under a dual-license agreement by both CDDL & Apache's GPL licenses. It is an application server meant to service in deploying web applications. GlassFish is now certified and included by Java Enterprise Edition v5 (SDK). GlassFish provides enterprise quality features including support for high scalability of applications, robust clustering and advanced administration w/ GUI interface for management. The project also has a large growing community of developers/users and solid documentation/API (quick-start tutorials, roadmaps & architecture documents).
Since its 2005 release, GlassFish has gained monumental support for both independent and commercial distributions. In recent news, GlassFish will be announcing its v3 release. It claims to have made numerous improvements including, simplified Web 2.0 style applications, better optimization for version specific Java applications, and a useful notifiable update center for GlassFish's new components. Currently, you can try out GlassFish v3 under Technology Preview 2 (TP2) and test it out on your local machine. WARNING: As noted on the Tech Preview site, the code is still in its raw experimental stages and should not be used to deploy production applications.

Satisfying Prime Directives:
PD#1 (Useful functionality):
GlassFish provides an open source referential implementation for developing high quality enterprise applications. Its support for Java EE v5 enables developers and companies to integrate with ease and to deploy business standard applications. The administration section is fully featured with a strong sense of security and management. I found that logging into the Admin Console to be very easy to configure and use. The Admin Console features tools that provide you a great deal of control over your serviced application(s). Admin Console also provides common administrator tasks through a straightforward web-interface which include: 1) Easy enable/disable applications, 2) service logs on applications currently running, 3) configurable Java Database Connectivity (JDBC) - module for wide range of database support and 4) many server side settings. GlassFish also provides scalable clustering techniques for rendering multiple in-memory state sessions. Although a great feature, I will need more time to find a better/suitable comparative data for cluster instances and its impact on scalability.

PD#2 (Ease of Installation & Deployment):
GlassFish has a number of resources including the very straightforward quickstart guide here. The quickstart guide helps you verify your server needs, gives you instructional steps into deploying your first web application, and using the administrative tools. I tested GlassFish on Eclipse v3.4 (on mac osx 10.5.4) using these instructions for installing the application server as a plugin and deploying my first Java EE application. There are also other supportive IDE's that make it just as easy to install GlassFish (as a plugin) and can be found here. As for deploying my first Java EE application, I also found this great screencast created by a fellow Sun developer named
Arun Gupta. The screencast has a bit of an audio glitch, but I found myself just turning the volume down and mimicking his actions.

PD#3 (Accessbility for Future Enhancements):
GlassFish's popularity has grown since Sun released its Binary (.jar) in 2005, where countless number of people in the millions tried it for the first time. The project has up to date news, discussion boards/forums, and RSS supportive mailing lists. Although GlassFish's licence agreements are semi-proprietary, in that some of its components are given out as binaries rather than pure source code, the community of active developers are still able to contribute to the development future of the project. Again, GlassFish is under CDDL agreement which authorizes anyone to make changes, fix bugs, and contribute new features. You can visit this site for more information on CDDL and GPL licenses. I also found this wiki page useful for having a general overview of which components are under which licensing term.

Final Thoughts:
In my brief experience with GlassFish v2, I've found myself more aware of the possibilities and power of one application server. Considering that this was my very first application server written in Java and for Java EE applications, I will need to give it more tests to verify its specifications. I've also heard of other application server alternatives to GlassFish, such as JBoss, Apache's Tomcat and Geronimo. Its a good possibility that I will post a comparison chart displaying its pros and cons. But I'm actually more tempted to wait for the highly acclaimed release of v3 for GlassFish.
After seeing that open source communities are now driving the market of consumers by its free price and popularity, I wouldn't be so surprised that big companies like Microsoft will start to become more open source.