28 April 2014

Building GlassFish from Source


Introduction
     This blog will look at building Glassfish 4.0.1 from source and configuring NetBeans 8.0 to then use, modify, and debug it. While GlassFish can be downloaded ready for use, even coming bundled with NetBeans, there will be some among us who need (or just want) to build it from scratch. This build was conducted using a 64bit Linux Distro, JDK 1.7.0_55, Maven 3.2.1, and SVN 1.8.8.

Building GlassFish
     If you want to see the official instructions from Oracle for building GlassFish (which was my first port of call), follow this link: https://wikis.oracle.com/display/GlassFish/FullBuildInstructions

     Despite initially sounding complex, building GlassFish from source is a fairly straightforward thing to do; the most complex thing required of you is to configure some Maven parameters! Let’s start off with this, as it’s a step that you don’t want to get wrong, lest you find yourself waiting for Maven to install GlassFish to only then give up after 20 minutes!

Configuring Maven
     Create a MAVEN_OPTS environment variable and set it as:

     -Xmx1024M -XX:MaxPermSize=512m 

     This is to stop Maven from running out of memory; the default settings do not provide enough memory for it to successfully complete the installation. If you are fortunate to have a surplus of memory, feel free to bump this up! With the “hard” bit done, let’s now get the GlassFish source code.

Getting the Source Code
     Being open-source, GlassFish can be downloaded and modified for free. To download the source code, navigate to where you would like the files to be downloaded to with the terminal and use the following command (make sure you have it on your path if it isn't by default):

     svn checkout https://svn.java.net/svn/glassfish~svn/trunk/main
 
     This will download the source code to a folder called main in the current directory. With that done, it’s about time we got down to building GlassFish.

Building GlassFish
     If all goes well, GlassFish can be built with a single command; told you it was relatively simple! Navigate into the main directory with the terminal, and run the following command (again, make sure you have it on your path):

     mvn install

     Please ensure you have the correct versions of Maven and JDK before building. The following are required:

Maven 3.0.3 and above
JDK 1.7.0_09 and above

     If you want to save a bit of time when building GlassFish, you can append the install command with the following flag to skip all of the tests:

     -DskipTests

     If you find that it throws a “peer not authenticated” error, this is due to the JVM not trusting the certificates of the Maven repository. To get around this, you can temporarily disable the certificate validation of Maven by appending the following flags to the install command:

     -Dmaven.wagon.http.ssl.insecure=true –Dmaven.wagon.http.ssl.allowall=true

     Whilst it would be better to configure the JVM to trust the certificates so these flags aren’t necessary, it’s outside the scope of this blog.

     The first build can take a while to complete, so unless you find watching the log text scrolling by particularly mesmerising, find something to do for about 20-30 minutes.

Using GlassFish as an Application Server
     Once GlassFish has been built, we can use it just like as if we’d downloaded it pre-compiled.
  • From NetBeans, expand the Tools drop-down list from the toolbar, select Servers, and click on Add Server.
  • From the new popup window, select GlassFish Server from the server type list, and give it a name, before clicking Next.
  • You will be presented with the Server Location window, prompting you to enter the GlassFish installation location. For our newly built GlassFish server, this can be found at:
    • install_dir/main/appserver/distributions/glassfish/target/stage/glassfish4 (where install_dir refers to the directory that main is located in)
  • At the next window, leave the settings as their defaults.
     With that, our GlassFish server should now be configured and ready to be started!

Modifying GlassFish
     NetBeans natively understands Maven due to a bundled plugin, so using NetBeans to modify the Glassfish code is as easy as opening any other project. Simply open the main folder as a project, and then browse through the modules for the one you wish to modify or add to.

     As an example, let’s break GlassFish!
  • Load GlassFish (the main directory) into NetBeans.
  • Open the Core Bootstrap Classes module: Modules, GlassFish Nucleus Parent Project, GlassFish Nucleus Core modules, Appserver Core Bootstraping Classes glassfish-jar. (The typo of Bootstraping is actually there at time of writing!). 
  • Open up the MainHelper class for editing by double clicking on it from the Projects pane.
     From here, let’s make a little mayhem by changing a single number. Scroll down to the checkJdkVersion() method, and change the if statement from this:
 if (minor < 7) { 
     To this:
 if (minor < 12) { 
     In human speak, this means the Java code is no longer checking if the JDK being used is less than JDK 7, and instead is checking if the JDK being used is less than JDK 12. This will cause GlassFish to exit immediately upon trying to start a domain; a nice, easy way to see if our change has actually taken effect.

     Make sure you’ve saved the change for it to be compiled, and then open up a terminal. Navigate to the main directory, and execute the following command to build our changes:

     mvn install -pl nucleus/core/bootstrap –amd

     This command will only build the specified module and those that are dependent upon it. The –pl (projects) flag specifies the specific projects to build, and the –amd (also-make-dependents) flag specifies that all dependent modules also be built. For future reference, if you change more than one module, the –pl flag allows you to specify multiple modules in a comma separated list like this: 

     mvn install –pl module1_path,module2_path.

      If you want to be thorough (which is best if you want to properly test your changes), just rebuild the entire code; it will likely not take as long as the first time.

     Once Maven has finished working its magic, navigate to the GlassFish bin directory, install_dir/main/appserver/distributions/glassfish/target/stage/glassfish4/glassfish/bin, and try to start the domain (./asadmin start-domain). You should get an error message that makes GlassFish sound a little unreasonable (below), proving that our change has taken effect.

     The server exited prematurely with exit code 1.
     Before it died, it produced the following output:
     Apr 25, 2014 10:38:44 AM com.sun.enterprise.glassfish.bootstrap.MainHelper checkJdkVersion
     SEVERE: GlassFish requires JDK 7, you are using JDK version 7. 

Debugging GlassFish
     Change back the if statement we modified in the previous section to its original value, and rebuild the module using the same command as before (it helps to have a working GlassFish to continue!).

     To debug GlassFish, we first need to set up our debugger:
  • From NetBeans, start the GlassFish Server in debug mode. 
  • Click on the Debug drop-down from the toolbar, and select Attach Debugger.
  • Use the JDPA debugger, with a SocketAttach Connector. The host will be the localhost(or the name of your machine), and the Port should be 9009 (the GlassFish default).
  • Open the Window drop-down from the toolbar, expand the Debugging list, and click on Sources to open the Sources window.
  • Right click in the Sources window, select Add Source Root, and add the main directory.
     If everything has gone smoothly, you should see the main directory be present in the Sources window, signifying that we've now linked the source code to our GlassFish Server, ready to be debugged. Let's just check it's working with a quick example before we start celebrating:
  • Open the RestResponse class, found under GlassFish Appserver Parent Project, Admin Console Packages, Admin Console Common glassfish-jar (you may notice that the path to this module will be added to the Sources window).
  • In the getResponseCode() method, add in the highlighted line before the large if statement, such that it looks like this (feel free to alter the message):
 ...
 String contentType = response.getHeaderString("Content-type");  
 Logger.getLogger(RestResponse.class.getName()).log(Level.INFO, "Help me! The author keeps breaking me!");  
 if (contentType != null) { 
 ... 
  • Add in a break point on our newly added line.
  • Save and then rebuild GlassFish with Maven.
  • Restart GlassFish in debug mode and re-attach the NetBeans Debugger (you don't need to add the source root again).
  • Open up a browser and navigate to the Admin Console.
      The break point should trigger, and if you step over or continue a few times, you will see our logger message being output in the GlassFish Server pane of the Output window.
Wrapping Up
Captain Picard face-palming: one bracket missing, whole coding is screwed up     And with that, you should now have built GlassFish from source and taken your first steps on modifying and debugging it. Have fun, and remember to make backups; we just aptly showed how easy it is to break it!


No comments :

Post a Comment