||David Chou blogged about Run Java with GlassFish in Windows Azure ... super! I've been thinking of trying this for sometime and was quite stoked when an initial introduction from Doris and a nudge from me expedited a task pending since past few months. Thanks a lot David for blogging the steps and answering my multiple emails (about 70+ over the past few days :) to help fine tune these steps for the GlassFish community.
This Tip Of The Day (TOTD) will provide detailed steps for running GlassFish in Azure. Lets get started!
- Request a free 30-day Windows Azure Pass (or click here). It took me about 15 days between the request and issue of this pass so plan accordingly.
Download and Install the softwares
Download and Install Visual Studio Express.
- Install Virtual Clone Drive such that Visual Studio ISO image can be mounted and then installed.
- Download and Install Azure SDK and Tools.
"VCloudService.exe" is the plug-in for Visual Studio and provides integration of Azure tools to Visual Studio. The SDK provides out-of-Visual Studio help so you could do things on the CLI or test the project using Compute and Storage emulator (more on this later).
- Install IIS 7.0 on Windows Vista following these instructions.
- Make sure to enable "World Wide Web Services", "Application Development Features", ".NET Extensiblity" and "ASP.NET" in Control Panel as shown:
- Download JDK 1.6 (latest update) for Windows and install it on a Windows machine.
- Download GlassFish 3.1 b40.
Upload installation files to Azure Blob Storage - Upload the GlassFish zip file and JDK installation zip to Azure Blob Storage service. These images will then be used by the Compute Cloud to install JDK and GlassFish during the image initialization.
- Using Azure Management Console, create a New Storage Account as shown:
- The typical convention is to create multiple containers in Blob Storage and load your application into "apps" container and JDK installer into "java" container. There are several tools that allow you to manage the Azure Storage service such as Neudesic's Azure Storage Explorer and Cerebrata's Cloud Storage Studio. I prefer Cloud Storage Studio because it gave me a nice debug error message when the local Windows machine date/time were too much out of sync with the storage server. However once the error was identified and fixed, Azure Storage Explorer worked as well.
Note for creating a new account in either of these tools, create a new "Storage Account" using "Azure Management Console", and use "Primary access key" and "Account Name" for account credentials
This is the same access key specified in the project configuration later. I used GlassFish 3.1 build 40 and installed JDK locally on my machine, made a zip, and then uploaded in the storage. Another option is to silent install JDK.
Here are snapshots from Azure Storage Explorer after the files are uploaded to Azure Blob Storage:
Make sure to select "HTTPS" check box when the connection is created. And now Cloud Storage Studio snapshot ...
Create the Visual Studio project
- Start Visual Studio using Administrator privileges. This will ensure that service package created later can be deployed to Azure Compute Emulator (used for testing in the local environment) from within the IDE.
- Select "File", "New Project ..." and create a cloud-based project by selecting/entering the values as shown:
and click on "OK".
- Create a new worker role as:
Select "Worker Role", click ">", edit the name to "GlassFishWorker", and click on "OK".
Extract MinimalJavaWorkerRole.zip (from Mario Kosmiska's article) and copy the following files:
from "JettyWorkerRole" to this newly created solution. The updated directory structure looks like:
- Make sure to save "Launch.ps1" and "Run.cmd" using "Save As...", "Save with encoding" and selecting "Western European (Windows) - Codepage 1252" instead of the default "UTF-8".
- Change the properties of the copied files such that these files are copied to output directories for compilation and packaging. In Solution Explorer, right-click on each file and select "Properties" and change the value from "Do not copy" to "Copy always" as shown below:
Edit "Launch.ps1", keep the two pre-defined functions as is and change the text as shown below:
$jdk = 'jdk1.6.0_23.zip'
download_from_storage 'java' $jdk $connection_string (Get-Location).Path
unzip ((Get-Location).Path + "\\" + $jdk) (Get-Location).Path
$glassfish = 'glassfish-3.1-b40.zip'
download_from_storage 'apps' $glassfish $connection_string (Get-Location).Path
unzip ((Get-Location).Path + "\\" + $glassfish) (Get-Location).Path
# Launch GlassFish
.\\glassfish3\\glassfish\\modules\\admin-cli.jar start-domain --verbose
"jdk1.6.0_23.zip" is the name of zipped directory JDK 6 installation uploaded to Azure Blob Storage and similarly "glassfish-3.1-b40.zip" is name of the zip file for your GlassFish 3.1. The latest build of GlassFish 3.1 can always be downloaded from here.
Edit "ServiceDefinition.csdef" to change the service definition and add the following fragment:
as shown below:
<Task commandLine="Run.cmd" executionContext="limited"taskType="background" />
<InputEndpoint name="Http_Listener_1" protocol="tcp" port="80" localPort="8080" />
<InputEndpoint name="Http_Listener_2" protocol="tcp" port="8181" localPort="8181" />
<InputEndpoint name="Http_Listener_3" protocol="tcp" port="4848" localPort="4848" />
<InputEndpoint name="JMX_Connector_Port" protocol="tcp" port="8686" localPort="8686" />
<InputEndpoint name="Remote_Debug_Port" protocol="tcp" port="9009" localPort="9009" />
Notice the external "port" for "Http_Listener_1" is 80 and "localPort" is 8080. This ensures that public requests can be received without specifying the port number (80 being the default) and then internally it is routed to port 8080 which is where GlassFish is running anyway. For all others, the same port is exposed.
Deploy the project from Visual Studio, complete steps are described here and the relevant ones are captured below:
- Create a new Hosted Service using Azure Management Console by clicking on "New Hosted Service" and entering the details as shown below:
and click on "OK". If you recall, we set the external port to be 80 and redirecting to local port 8080. With this setup, your requests will be received at "glassfish-service.cloudapp.net:80" or "glassfish-service.cloudapp.net" and redirected to GlassFish 3.1 b40 running on the provisioned instance. Choose the service name carefully as that becomes the URL of your deployed service.
- In Solution Explorer, right-click on the project and choose "Publish ..."
The default operating system provisioned is "Windows Server 2008 SP2" and can be configured by editing "osFamily" and "osVersion" attributes in ServiceConfiguration.csdef. For example changing "osFamily" to "2" will use "Windows Server 2008 R2".
- Specify the Credentials as shown below:
and click on "OK".
- Click on "Copy the full path" and then copy the certificate to "Management Certificates" section of the Management Portal.
Select the "production" environment as shown below:
and click on "OK".
Optionally, you can configure Remote Desktop Connection in case you want to look at the provisioned system later. Here is how the configuration looks like:
More details about the configuration are described here. Some clarifications on this step ...
- The password must contain a mix of lower-case letters, upper-case letters, and numbers or symbols otherwise will not accept it. Just a red icon appears to the right with no indication of the error message.
- After the certificate is created, click on "View ...", "Details" tab, "Copy to file ..." button to copy the generated certificate to a file. This certificate need to be imported in Management Portal.
- Make sure to select "Yes, export the private key".
- Select "Delete the private key if the export is successful".
Upload this certificate to Management Portal (before publishing the project) as explained in "To upload a certificate using the management portal" here.
How I could not get this configured successfully and kept getting the error:
There was no endpoint listening at https://management.core.windows.net/SUBSCRIPTION-ID/services/hostedservices/glassfish-service/deploymentslots/Production
that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
- The "Windows Azure Activity Log" displays log as the project is deployed to Azure. The following is displayed once the project is successfully deployed:
Now you can access the "Website URL" to see:
And web-based Admin Console is seen as:
This GlassFish instance is the default installation. What would you like to do with it - hack it, break it, deploy apps to it, something else ? :-) I can just right-click in my Visual Studio project and deploy this instance again!
Once again, many many thanks to David Chou for helping me through these steps!
Some TODOs for the future blog entries ...
- Create a Java EE 6 application using NetBeans and remote deploy it to this instance.
- Try out this installation locally using Azure Compute Emulator and Storage Emulator.
- Try debugging Launch.ps1 scripts using Power Shell.
- Use JPA to access data in SQL Azure.
- Debug SOAPAction error in Remote Desktop Connection.
- Windows Azure VM Role feature for JDK installation.
- Is ServiceConfiguration extensible ? I'd love to have an attribute in this file take care of JDK/GlassFish installation.
- GlassFish 3.1 clustering integrated with Azure Clustering and Load Balancing.
Which one are you going to author ? :-)
Technorati: totd glassfish javaee6 microsoft windows azure cloud