Monday Jul 18, 2011

The GlassFish Upgrade Tool: End of the Line

In the 2.X timeframe of GlassFish, there was an upgrade tool that would transform your existing configuration information and move you to a newer version of GlassFish. This tool did all the work of mapping one version's configuration information to another.

Starting with GlassFish v3, the application server became modular, and components became responsible for their own part of the configuration upgrade. See the upgrade one pager for more details on how configuration upgrades work.

With the real work of the upgrade happening in the application server itself, the job of the upgrade tool became smaller and smaller until it now does the following:

  1. Copies the source domain to the target app server.
  2. Runs asadmin start-domain --upgrade.

When the steps are that simple, there isn't much value in having the tool. If you read the Oracle GlassFish Server 3.1 Upgrade Guide, you'll see that there are several upgrade uses cases that do not involve the upgrade tool at all. One example is an in-place upgrade using the update center.

For this reason, and to avoid confusion between the upgrade tool and update center, we'll be removing the upgrade tool from versions of GlassFish after 3.1.X. Upgrades should still be a simple affair. After all, the tool is just doing a copy and starting the server. If it can, you can.

Friday Mar 04, 2011

Validating Multicast Transport: Where Did My Instances Go?

For cluster health information and communication of high-availability state, GlassFish 3.1 depends on GMS. To dynamically discover the members of a cluster, GMS depends on UDP multicast. So if there's something about your network preventing multicast communication among hosts, instances will become isolated from each other.

As I wrote in my last blog on the 'asadmin get-health' command, it's a good idea after starting your cluster to make sure everything is working correctly. With the asadmin validate-multicast command, you can diagnose issues with intra-instance communication or plan your cluster deployment before creating the cluster instances.

This asadmin subcommand is used to send and receive UDP multicast information, and so acts to validate that various hosts can all communicate with each other. The usage is simple in concept: run the tool on each host at the same time, using the same multicast address and port, and verify from the tool's output that each host receives messages from the others. So if you're running on hosts 1, 2, and 3, then you should see this when running on host 1:

    Listening for data...
    Sending message with content "host1" every 2,000 milliseconds
    Received data from host1 (loopback)
    Received data from host2
    Received data from host3

Likewise, hosts 2 and 3 should see messages from all 3 machines. Make sure you're not running the DAS and instances at the same time, or else there will be interference with the UDP traffic. Here is a video showing some features of the tool:

Debugging, Step 1: Use Same Multicast Port/Address as Cluster

While this tool can be useful to check your network before deploying your cluster, it is most helpful when one instance is not communicating with the DAS/other instances. You may see this if you run the 'get-health' command described in the previous blog. If you know that an instance is up according to its server log, but it's showing up as "not started" in the get-health output, then it's likely that the DAS and the instance are not seeing each others' UDP multicast messages. In this case, you want to run asadmin validate-multicast with the following options:

  • --multicastport The value of gms-multicast-port for your cluster in domain.xml.
  • --multicastaddress The value of gms-multicast-address for your cluster in domain.xml.

Using those options will make the tool use the same values as the members of your cluster, in effect simulating the GMS traffic between the DAS and instances. To find the values for those options, you can read them from the attributes on the <cluster> element in domain.xml. For instance:

  <clusters>
    <cluster name="mycluster"
        gms-multicast-port="22262"
        gms-multicast-address="228.9.244.214"
        [etc.] >
      <server-ref ref="instance1"></server-ref>
      <!-- [etc.] -->
    </cluster>
  </clusters>

Debugging, Step 2: TTL

Unless specified on the command line, the validate-multicast tool and GMS use the default MulticastSocket time-to-live for your operating system or 4, whichever is greater. You can see this in the tool's output if you run with the --verbose flag. For example:

    McastSender: The default TTL for the socket is 1. Setting it to minimum 4 instead.

You can try increasing this value to see if it is the limiting factor that prevents packets from reaching the cluster members with your network configuration. To specify a different value, use the following option with the tool (in addition to --multicastport and --multicastaddress):

  • --timetolive Sets the time-to-live value of the multicast packets sent by the tool.

If you are now seeing all the instances you expect, you can change your cluster configuration so that GMS uses this TTL value. It is simple to pass this value into the asadmin create-cluster command. See the "To Create a Cluster" section of the High Availability Administration Guide for an example. If your cluster is already running, however, you can set this value with asadmin set. See the "To Change GMS Settings After Cluster Creation" section of the HA guide. The property to be set is GMS_MULTICAST_TIME_TO_LIVE, and it is listed in the "Dotted Names for GMS Settings" section.

Debugging, Step 3: Specifying the Network Adapter

On a multi-home machine machine (possessing two or more network interfaces), you may need to specify the local interface that should be used for UDP multicast traffic. You can use ifconfig, or the equivalent on your system, to list the network interfaces and obtain the local IP address of the interface you wish to use. This address can then be used with the following command line parameter (along with any you're already specifying):

  • --bindaddress Sets the local interface used to receive packets.

Note that this value will be different on each machine where you are running the tool. If you are now seeing all the instances you expect, you can set the GMS bind interface for each instance following the instructions in the "Traffic Separation Using Multi-Homing" section of the HA guide.

If one or more machines are still missing in the output, then it may be that they are located on different subnets from each other. Or it could be that UDP multicast is not enabled on the network. You may need to ask the network administrator to verify that the network is configured so that the UDP multicast transport is available.

For more information, see the validate-multicast man page. A copy of the help information is attached here as well. The validate-multicast tool is also covered in more depth in the HA guide referenced above.

Tuesday Mar 30, 2010

Authentication Without the Form

The nice thing about form-based authentication is that it allows a simple way for an application to let the container handle common security tasks. The bad thing about it is that, well, you need an HTML form. For a "Rich Internet Application" (RIA) that doesn't normally use JSPs or HTML pages, this means tacking on some extra files that don't have a natural fit in your application: the JSPs and/or HTML pages themselves, along with a deployment descriptor to specify the security settings. With the new features of the Servlet 3.0 spec, form-based login is no longer needed. Instead, your application can collect username and password credentials however you'd like and simply pass them to the container during an HTTP request. (Logout is equally simple.)

With form-based authentication, you would normally select some set of URLs and protect them with a security constraint. To access these URLs, a user would have to be authenticated and properly authorized. In some RIAs, this pattern no longer makes sense. For example, there may be few (or one) URL for the entire application. Instead, you can apply declarative security at the EJB level to protect any sensitive information (remember that EJBs can be used within a war file in Java EE 6!)

In this blog, I'll show an example of user authentication that doesn't involve an HTML form (or any JSP or HTML pages). There is a simple session bean acting as our back end service, and one of the two "hello world" style methods can only be called by a caller in the 'ADMIN' role:

    @RolesAllowed("ADMIN")
    public String getAdminMessage() {
        return String.format("Hello again '%s', it's great to see you!",
            context.getCallerPrincipal().getName());
    }

While the entire application is available in this zip file, you can see the full session bean, copiously commented, here. The rest of the sample application is simple as well: there is a main, servlet-based application class using Vaadin that includes these two panels (the authentication panel has been broken out into a separate class). See the code in the authentication panel for the full details, but the code to log the user in is this simple:

    String name = // retrieved from web UI
    String pass = // retrieved from web UI
    
    // exception handling omitted here
    // app.getRequest() returns the current HttpServletRequest
    app.getRequest().login(name, pass);

Logging the user out, of course, uses the logout() method instead. Here is the full user interface:

The ee6auth example application

In the "Actions" panel, there are two buttons that call a method in the EJB when clicked. The top button can be used whether there is an authenticated user or not. The other will result in an exception if there is not an authenticated user who is authorized to make the call (a user in the 'ADMIN' role). The exception is popped up in the browser to let you know what happened. Please see the three class files for comments describing the details of each part of the application. Note: while we're keeping this example simple, remember to use SSL any time you're dealing with user credentials such as passwords. The only other file in the application is a deployment descriptor that maps users in the authentication realm to the proper application role.

Before using the application, you need to add some users in the proper group in the default realm in the application server. The group we're using is 'ADMIN_GROUP,' but you can use any group you'd like as long as the mapping is correct in sun-web.xml. To help get you set up, here is a screen cast that shows how to create users in the default realm in GlassFish. We're keeping this very simple by using the file realm in the server, but you could use any realm you'd like. To use a realm other than the default one, add a web.xml file to specify it:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <login-config>
        <realm-name>your-realm-here</realm-name>
    </login-config>
</web-app>

Important note: because of this issue, you need a post-3.0 build of GlassFish v3. You can download a promoted build of v3.0.1 here -- to install, just unzip it. One more time, here's a link to the example application.

To build the application, you can use any IDE that supports Maven or use the command 'mvn clean package' to build it directly. Then deploy with the admin console or use this command (the --force option is only necessary on the 2nd or later deployment):

asadmin deploy --force --contextroot /ee6a <somepath>/ee6auth/target/ee6auth.war

Then you can access the application in a browser with http://localhost:8080/ee6a/. Let me know if you have any problems with the example. For any general questions, you'll get an answer more quickly at users@glassfish.dev.java.net.

I'd like to give a big thanks to Petter Holmström from the Vaadin team for his help, especially the article Creating Secure Vaadin Applications Using JEE6 that explains the steps needed to use regular form-based authentication (and a lot more) with a Rich Internet App such as Vaadin.

Thursday Mar 04, 2010

A Simple UI for Exploring Java EE

Java EE 6 has greatly simplified life for the EE developer. New annotations like @Startup and packaging options such as EJBs inside a war file save time and brain cycles. However, this makes writing the web UI for an application all the more time-consuming by comparison. If you're like me, you may have found yourself creating some entities and a session bean or two for controlling them, and then you just want to test it all out. Maybe step through the code in a debugger. Here's what I've done over and over -- it's simple, but it's silly. Just create a servlet, inject my session bean, and do something when the page is loaded:

    @EJB
    private MyBean myBean;
   
    @Override
    protected void doGet(...) throws ... {
        myBean.someMethod();
    } 

Then it's a simple matter to load the page in a browser and kick off the cool EJB code that you want to try. To check what really happened in the database, I use another tool (e.g., the database explorer in NetBeans). Simple, yes, but almost useless. In this blog, I'll show you a UI for testing Java EE services that is simple to write and trivial to adapt to your own applications. Not only can it provide a slick front end for calling business methods, but also access the database directly to show you what happened after the transactions have committed. As a bonus, it will show you the stack trace when something doesn't go quite right.

Yes, there are a number of tools that provide simple drag-and-drop interfaces for creating things like JSF front ends, but my goal is to create a UI with useful features as easily as I've created the session beans and entities. If you've ever written a Swing application, this should look very familiar. And there are no cryptic deployment descriptors, configuration files, or html/jsp templates needed. The only non-Java file in the application is a simple persistence.xml file.

To give you an idea before diving in, here is a screencast of the application in action.


Part 1: The Application

All of the application code is included in this zip file. I've included a pom.xml file so you can build with maven 2 without any additional setup. If you'd like to compile the sources and create the war another way, you just need the Java EE APIs in your classpath along with Vaadin, which comes in a single jar file that you can download from here. Look for the "Just the jar-file, please" text if you only want the one resource.

The back end consists of two simple entities, a SimplePerson and SimplePet. They both have a name, age, and one-to-one reference to each other. There is a PersonService session bean that has some normal CRUD operations on the person (which are cascaded to the pet). This bean is injected into the web UI -- see below for more details. Finally, there is a singleton bean loaded on startup that simply makes sure there is a pet named "Fred" in the database: FredCreatorBean. All of the classes are fairly simple and include comments to guide the reader. The persistence.xml file is very simple and uses a JTA data source jdbc/EE6Vaadin -- instructions for creating the resource are in part 2 of this blog. If you use a different JNDI name when creating the JDBC resource, make sure you change the name here. Also, after deploying the first time, you may want to comment out this line to avoid some warnings upon subsequent deployments:

    <property name="eclipselink.ddl-generation" value="create-tables"/>

For the presentation layer, I'm using Vaadin, a Java framework for creating rich internet applications. Since it's all Java, you write code that looks like Swing -- there are objects for layouts, widgets, and event handlers. GWT is similar, but with Vaadin the code you write stays on the server rather than being compiled into JavaScript objects. This is why I can inject a session bean into the presentation code to call my business logic. (Vaadin uses GWT for rendering the client in a web browser.) I should note that I'm not a Vaadin expert, so there may be better ways to create the UI. The Vaadin site has a nice forum for discussions like that -- I'll add a link here if there is any related discussion there.

Vaadin applications are loaded by a servlet com.vaadin.terminal.gwt.server.ApplicationServlet that you can configure in your web.xml file. This servlet creates the application object your write, initializes it, and the web page is displayed. In this example, I have included my own subclass of the Vaadin servlet in order to inject the session bean, and then I pass this bean to a custom constructor of my application. This also allows me to avoid having any configuration files except for persistence.xml. Here is the code included at the end of the main application class VaadinEE6App:

    /\*
     \* This code is adapted from the Vaadin example here:
     \* http://vaadin.com/wiki/-/wiki/Main/Hello%20GlassFish%203
     \*/
    @WebServlet(urlPatterns = "/\*")
    public static class Servlet extends AbstractApplicationServlet {

        @EJB
        private PersonService service;

        @Override
        protected Class<? extends Application> getApplicationClass() {
            return VaadinEE6App.class;
        }

        @Override
        protected Application getNewApplication(HttpServletRequest request)
            throws ServletException {
            return new VaadinEE6App(service);
        }
    }

In the application constructor, I store the EJB and create a couple class-level fields such as some panels that handle display and creation of the person/pet POJOs. The init() method creates some simple layouts, adds the panels, buttons, text field, etc., and connects the buttons to some actions for calling the back end. See the (hopefully) well-commented VaadinEE6App.java file for all the details. Everything there should look more or less familiar to a Java developer who has seen any Swing code.


Part 2: Setup and deployment using GlassFish v3

I'm using GlassFish v3 for this example, along with the JavaDB database that is included. In production, we would create the DB tables with SQL, but for a simple demo the JPA provider will do this for us. We just need to create the database connection pool, create a JNDI resource for it, and then build and deploy the application.

If you haven't already, download and unzip GlassFish v3, which supports Java EE 6. The database and server can be started with:

    asadmin start-database
    asadmin start-domain

Then visit the administration console at http://localhost:4848 -- the default username is admin with no password if prompted. On the left side, open the Resources->JDBC node and click Connection Pools. Click the New button and enter the following information, then click Next:

Step 1 of creating JDBC connection pool

In step 2, scroll to the Additional Properties table at the bottom. Delete properties as needed and enter information as shown below. Then click Finish.

Step 2 of creating JDBC connection pool

In the table above, the "create=true" property tells JavaDB to create the database when it is needed. The database name, user name, and password can be set to whatever you'd like, but you'll need to remember to change this information in the com.sun.bobby.ee6vaadin.presentation.SQLPanel class, which access the database directly.

Before moving on, you can check to make sure the database connection is working by clicking your new EE6VaadinPool entry in the Connection Pools list and then click the Ping button.

The last setup step is simple: creating the JDBC resource that points to the connection pool you just created. In the administration console, open the Resources->JDBC node again and click JDBC Resources. Click the New button, enter the following info, and click OK. If you choose a different name here, it has to match the jta-data-source element in the persistence.xml file in the application. That's all there is for setting up the database and server.

Creating the JNDI resource

Now you can create and deploy the war file. If using maven, you can use a simple "mvn package" from the ee6vaadin directory to build the war file. One more time, I'd like to point out that we have EJBs running without an ejb-jar file or an application .ear file! Good stuff.

To deploy, you can use the admin console or the following from the command line. The "--force" option isn't necessary the first time, but it is used in subsequent deployments to overwrite the deployed application. After your first deployment, you may want to comment out the table-creation property in persistence.xml and rebuild. Here is the command, but feel free to use whatever context root you'd like:

    asadmin deploy --force --contextroot /ee6v target/ee6vaadin.war

Assuming deployment proceeds without an issue, you can access the web application at http://localhost:8080/ee6v/ and give it a spin. It's not meant to include every conceivable feature -- there are even a couple "homework" features left for the user. But I hope it's enough to show how easily a web UI can be constructed that a) avoids configuration files, expression languages, templates, etc.; and b) can take full advantage of the Java EE server and use EJBs directly.

Update: I noticed I left an entity manager call in the code that isn't necessary at all. The 'else' block in the only method of FredCreatorBean looks like this:

        } else {
            // doesn't matter which one for this demo
            SimplePet fred = (SimplePet) fredPets.get(0);
            fred.setAge((fred.getAge() % 10) + 1);
            em.merge(fred);
            System.out.println(String.format(
                "Wow, Fred is %s years old already!",
                fred.getAge()));
        }

The 'em.merge(fred);' statement isn't necessary since the entity is still being managed throughout the method.

Thursday Oct 09, 2008

Screen Cast: Developing Project SocialSite

As more and more people are trying out Project SocialSite, we're finding out that some people want to be able to download and use the latest code without waiting for a promoted build. So this blog is for the code-happy developer types who want to build and try things out, and then rebuild and re-try if we (or they!) fix some particular issue. This isn't necessarily the best or only way to install SocialSite and then get into the twiddle/compile/test cycle (twiddle being the technical term), but it works for me.

As background, this blog assumes that you've downloaded the code, have an instance of GlassFish ready, already have ant, etc. There are a couple files that I have ready beforehand in the screen cast. Two are properties files that I edit ahead of time and copy somewhere else. You can do the same if you'd like:

  • socialsite/installer/sjsas.props
  • socialsite/installer/socialsite.props

The other step I mention in the screen cast is to change the socialsite.search.index.path property in socialsite/src/java/com/sun/socialsite/config/socialsite.properties. After that, you're ready to follow along with the screencast.

I use FireFox as my browser, and there are a couple extensions that are very helpful when working on Project SocialSite or pretty much any other web application. You can find them both through FireFox's "Get Add-Ons" functionality, but here are some links as well:

  • Firebug. Can't live without this one. I use it for debugging JavaScript code and for checking the outgoing/incoming messages for requests made by gadgets. If you're working on gadget code and want to see what some generated html is really doing in a page, "Inspect Element" is a handy feature.
  • Web Developer. This extension does a lot more than I use it for, but it's essential for a couple things. The biggest for me is turning off my browser's cache so that it doesn't keep loading an old version of a gadget xml file long after I've made changes. Being able to clear your session data is nice as well when working on login/authentication. This extension does just about anything to a web page that you'd like.

Tuesday May 27, 2008

GlassFish Presentation to Connecticut JUG

Last week I gave a presentation on GlassFish to the Connecticut Java User's Group. I wanted to answer a couple questions here that came up during the talk. Big thanks to the group for letting me come talk to them, and also thanks to Arun for letting me use his presentation.

One issue that came up was how GlassFish works with other frameworks, applications, etc., and I was asked about setting up GF as the servlet container with Apache as the web server for static content. The user was already using Apache web server in front of Tomcat and wanted to know how it would work with GF. The official docs one the topic are here, and the conversation can be followed on the GlassFish forum.

A related question was about the performance of GlassFish compared to Tomcat when used just as the servlet container with another web server in front. While I can't provide any official answer to this, the email thread can be followed (and continued!) on the forum page.

While talking about scripting support in GlassFish, I asked the group if there were other languages/frameworks that they were using besides the ones already supported. Someone asked about Perl with the Catalyst framework. I've passed along the info to the scripting team for their consideration. Please stay tuned to GlassFish Scripting for continuing information on scripting support.

Thanks again to the CT JUG for having me and for letting me plug my current project, Project SocialSite. I'll update this post with any more information as it comes in.

Friday Sep 21, 2007

GlassFish v3 Demo at Sun Tech Days

The Sun Tech Days Boston event was held last week. As part of Sun Tech Day on Wednesday, Tom Kincaid gave a talk on Java EE 6 and the future of the EE platform. This blog captures the demonstration that we gave of an early preview of GlassFish v3 (which is implementing Java EE 6). For more information on Sun Tech Days Boston, Ryan Shoemaker has recorded his days at the conference: part 1, part 2.

In the demonstration, we wanted to show four main features of GFv3:

  • The modular nature of GFv3, which results in very fast startup time.
  • Containers for web apps and JRuby apps loading on demand.
  • Simplified deployment of JRuby applications.
  • The inclusion of Java code inside a Ruby application.
Tom said I could have about ten minutes for the demonstration, but GFv3 is so fast I think we only needed five. Hopefully the audience appreciated that -- more of Tom, less of me fumbling around on a laptop.

To put together the demonstration, I borrowed (stole) from a screencast by Jerome Dochez and a blog by Arun Gupta. Add in a daily build of NetBeans IDE and you have just the mix.


The Software

GlassFish v3: The "preview1-b2" build is available here. Installation is simple: just java -jar <filename>. Drop the bin directory into your path and you're all set.

NetBeans and the GFv3 plugin: By now, the Beta 1 version of NetBeans 6 is out. Since it hadn't been released at the time of the conference, I went with a daily build from September 7th and grabbed the GlassFish v3 plugin from the beta update center. When you add GF to the NetBeans's server list, NB gives you a download button to grab the app server:


The version isn't the same as the preview 1 b2 shapshot that I was using, but that combination worked anyway. You don't need to add the GFv3 server to NetBeans for these examples since I give instructions for deploying/undeploying from the command line.

JRuby: Following the directions on Arun's blog, you can install JRuby 1.0, add the bin directory to your path, and install Rails with

      jruby -S gem install rails -y --no-rdoc

After this, just add the JRUBY_HOME value to the end of the asenv.\* file in glassfish/config/.


The Demonstration

Running GlassFish v3: In your glassfish/lib directory, you can see all of the jars that make up the kernel and containers of GFv3. That little (less than 15k) jar file called glassfish-10.0-SNAPSHOT.jar is your target. Assuming you are in the glassfish directory, give the Java command:

      java -jar lib\\glassfish-10.0-SNAPSHOT.jar

...and you should see something like this:

D:\\glassfish>java -jar lib\\glassfish-10.0-SNAPSHOT.jar
[#|2007-09-14T16:32:02.589-0400|INFO|GlassFish10.0|javax.enterprise.system.core|_ThreadID=
10;_ThreadName=Thread-2;|Listening on port 8080|#]

[#|2007-09-14T16:32:02.770-0400|INFO|GlassFish10.0|javax.enterprise.system.core|_ThreadID=
10;_ThreadName=Thread-2;|Supported containers : phobos,web,php,jruby|#]

[#|2007-09-14T16:32:02.790-0400|INFO|GlassFish10.0|javax.enterprise.system.core|_ThreadID=
10;_ThreadName=Thread-2;|Glassfish v3 started in 791 ms|#]
Note the startup time, in this case under .8 seconds on a slightly old laptop. You can browse http://localhost:8080 to see that the server has indeed started and is serving static html content. Add another html file to domains/domain1/docroot and you can view it in the browser, or edit index.html (go ahead, it's your app server!) to see changes. Now it's time to add some applications.

 

A web application example: In NetBeans, create a simple web application. Ctrl-Shift-n is one way to bring up the "New Project" window, and you can choose Web -> Web Application to create a simple web app. The index.jsp file will come up automatically in the editor. Just add some text of your choosing and build with F11. We called the project "jsphello" and the war file was built in jsphello/dist/jsphello.war. If you have the GFv3 plugin, you can deploy with NetBeans, but we deployed from the command line in order to watch both the server and asadmin output at the same time. To deploy, use

      asadmin deploy --path <path to jsphello.war>

The asadmin script will call a Java command to deploy the application, and your output should look something like:

D:\\examples>asadmin deploy --path jsphello\\dist\\jsphello.war

D:\\examples>java -jar D:\\glassfish\\bin\\\\..\\lib\\admin-cli-10.0-SNAPSHOT.jar deploy --path jsphello\\dist\\jsphello.war
SUCCESS : Application jsphello deployed successfully

Note that in the GlassFish server log, the web container is loaded when it is needed. If you stop and restart the server now, you will that the web container is loaded at startup since a web application has been deployed. You can undeploy the application with:

      asadmin undeploy --name jsphello

To get a list of deployed applications, use:

      asadmin list-applications

After undeploying the web application and using the "list-applications" command, your output will look like the text below. You can see that the web container is loaded, ready for another web application to be deployed (if you restart the server, it will not load the web container until you need it).

D:\\examples>asadmin list-applications

D:\\examples>java -jar D:\\glassfish\\bin\\\\..\\lib\\admin-cli-10.0-SNAPSHOT.jar list-applications
SUCCESS : List of deployed applications per container
ContractProvider : web_ContractProvider
        properties=(Connector module=com.sun.enterprise.glassfish:gf-web-connector,
        Sniffer module=class com.sun.enterprise.v3.web.WebSniffer)

 

A JRuby example: In NetBeans, open the New Project window and choose Ruby -> Ruby on Rails Application. On the next page, give the application a name (e.g., "railshello") and click Finish. After the IDE is finished generating the files needed, you can add a controller and view for a simple "Hello World" application. Right-click on the project name and choose Generate. Fill out the resulting dialog as below and click Ok:

NetBeans will then generate say_controller.rb and hello.rhtml files for you. We edited the controller to add a string and then used that string in the "hello" view.

say_controller.rb:

class SayController < ApplicationController

  def hello
    @hello_string = "Hello World"
  end
end
hello.rhtml:
<h1>Say#hello</h1>
<p>Find me in app/views/say/hello.rhtml</p>
<%= @hello_string %>

GlassFish v3 supports a "straight" deployment of JRuby code. To deploy our 'railshello' application, we don't have to first wrap it in a war file. We can simply call asadmin and deploy the application directory (asadmin calls the proper "java -jar ..." command):

D:\\examples>asadmin deploy --path railshello

D:\\examples>java -jar d:\\glassfish\\bin\\\\..\\lib\\admin-cli-10.0-SNAPSHOT.jar deploy --path railshello
SUCCESS : Application railshello deployed successfully

Watching the server log, you can see that the JRuby/Rails runtime is loaded into GFv3 as needed. Then the application is deployed and is ready to run. To access the page once it's deployed, use http://localhost:8080/railshello/say/hello. This directory deployment of the application makes for a very fast development cycle. For instance, if you change the @hello_string value in say_controller.rb, you only have to save the file and reload the page in your browser.

 

Adding some Java into the Ruby code: Using the same JRuby/Rails application, you can add Java code directly into the say_controller.rb file without any other compilation or deployment steps. For our example, we added some trivial Java code in to create a HashMap and set the value of @hello_string using a value in this map. The new version of say_controller.rb:

require 'java'
include_class 'java.util.HashMap'

class SayController < ApplicationController

  def hello
    myMap = HashMap.new
    myMap.put("key", "Hello from Java code!")
    @hello_string = myMap.get("key")
  end
end

Now simply save the file and reload the page in your browser. The mix of Java and JRuby code works without any other steps since we have done the directory deployment. Finally, to undeploy the application, give the same command that you used to undeploy the jsphello example:

      asadmin undeploy --name railshello

Though this early version of GFv3 does not show anything in the log when you undeploy the app, you can verify that it is no longer deployed with the asadmin 'list-applications' command described above.

About

Whatever part of GlassFish or the Java EE world that catches my attention. (Also, go Red Sox.)

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today