Saturday Apr 30, 2005

Drag-and-Drop Deployment to JBoss in NetBeans IDE 4.1

In a previous blog entry (Efficient Deployment via Ant Scripts from NetBeans IDE 4.1), I suddenly understood what deployment really means, thanks to my having to write an Ant script for this purpose:

 <target name="jboss-deploy" description="Deploy to JBoss">
      <copy file="${dist.dir}/${jar.name}" todir="${jboss.deploy.dir}"/>
 </target>

Since this target clearly does nothing more than copy an archive file (EAR, WAR, or EJB-JAR) to the server's deployment directory, it is 100% identical to manually copying the archive file from the directory where it is created to the directory from which the server can deploy it. Were it not for the fact that manually digging through the filesystem to find those directories is more cumbersome than creating the Ant script that does the same thing automatically, there'd be no point in writing the Ant script in the first place. But what if there were an easy way of finding those directories, from inside the IDE? Ah, but there is... thanks to the Favorites window! Three simple steps to set everything up:

  1. Click Ctrl-3 in the IDE and the Favorites window appears.
  2. Drag the window to the right side of the Source Editor.
  3. Right-click the Favorites node, which is the highest node in the window, select Add to Favorites, and browse to the JBoss server's deploy directory.

The result of the above steps should be the following (click to enlarge):

And now, after you've built the application, you can just drag the archive file from the Files window, across the Source Editor, and into the server's deploy directory. That's it! Mission accomplished -- you've deployed your application! (Note that the Source Editor has a cool vertical split-screen in the illustration above.)

It's a good idea to only start the server after you've dragged the archive file into the server's deployment directory. This way, you get the benefit of any application-related error messages that the server outputs into the IDE's Output window during start up. For example, if you start the JBoss server after you've dragged the application into it's deployment directory, the JBoss server will produce errors during start up when it can't find a jboss-web.xml file, if needed, or if a database server hasn't been started up.

Another cool thing that results from this setup is that undeployment is as simple as right-clicking an archive file in the Favorites window and choosing Delete. On top of that, any text files in the Favorites window can be opened in the Source Editor. This is particularly useful for XML files, because you can then use the Source Editor's XML validation. This is even more particularly useful when you're setting up a connection pool on JBoss, because the data source is defined in an XML file which you not only have to dig through the filesystem to locate, but -- if you open the file in a plain text editor -- which you also cannot validate. So far, though, the most significant advantage I've found to this way of working is that all the files I need are really accessible and everything is snugly integrated in the IDE -- without even a single Ant script.


Question of the Day. Charles Ditzel asks: "Could I add a menu item to kick off dbVisualizer from NetBeans?"

Answer: Of course. Any application that can be started by an operating system can be started by Ant. That's because Ant can call an application's executable. For example, an Ant script for starting dbVisualizer goes as follows:

  <target name="Start-App-DbVisualizer">
    <exec executable="C:\\Program Files\\DbVisualizer-4.2.2\\dbvis.exe" />
  </target> 

FYI, here are all my IDE-wide targets: ide-wide-targets.xml

After you create the Ant target for starting the dbVisualizer, right-click the target's node in the Files window, and choose Create Shortcut. Then you can add a menu item, toolbar button, or shortcut key which you can use to invoke the dbVisualizer.


Thursday Apr 28, 2005

Save Demi Moore in NetBeans IDE 4.1!

Let's say you've extended the IDE by creating a new menu, toolbar, menu item, or toolbar button. For example, you've created menu items that are hooked up to Ant scripts that start and stop JBoss, Tomcat 4, WebSphere, and JRun from the IDE. Or you've customized your window layouts and editor settings. Or maybe you've added a module to the IDE. Or maybe you've added some other customization... such as the Demi Moore macro. What happens when you delete your user directory without saving it beforehand? You lose all your customizations. So you've got to remember that you have, for example, hooked an Ant script to the menu bar and that therefore you've got to save the user directory before you delete it. Normally, you delete the user directory long after you've customized the IDE. Hence, you might forget that you've customized it, that you're very comfortable with the customizations, and that you therefore need to save the user directory in order to maintain your customizations. Wouldn't it be cool if you could save the user directory very quickly right after you've added some new customization? Wouldn't it be cool if you could click a menu item or button or keyboard shortcut from inside the IDE, and save your user directory to some safe place in your filesystem, seconds after customizing the IDE in some way? Well, you can. And it's really easy. Add this to the build.xml file:

  <target name="save-demi-moore" description="Save Demi Moore">
     <copy  todir="c:\\DemiMoore\\config">
           <fileset dir="C:\\Documents and Settings\\${user.name}\\.netbeans\\${release.number}\\config"/>
     </copy>
  </target>

Update 06/27/05: A better Ant script than the one above can be found here.

You'd need to set the user.name property and release.number property somewhere in a properties file and then, if either the user name or release number change, you'd only have to change the two properties to update the script. Note that this script copies everything in the user directory's config directory to a directory called c:\\DemiMoore\\config. Therefore, if you don't want to copy everything, you can append an excludes attribute to the dir attribute and then list all the directories or files you'd like to exclude. (Examples of the use of the excludes attribute can be found elsewhere in this blog.)

Then expand the build.xml node in the IDE (it's in the Files window if you're using a standard project and in the Projects window if you're using a free-form project). You'll see that each target has its own subnode within the build.xml node. Right-click the save-demi-moore node, choose Create Shortcut, and add the save-demi-moore target as a menu item, toolbar button, or keyboard shortcut. You could, for example, add it in the File menu. (When you add an Ant script to a menu, it is placed at the top of the list of menu items within the menu. To re-order the menu items, go to Tools > Options, then expand IDE Configuration, Look and Feel, and right-click Menu Bar or any of its nodes and then choose Reorder.) This is where I've placed it:

Now, whenever you customize the IDE in any way, you can copy all the configurations in one click to a safe place. And then, when you delete your user directory and the IDE creates a new one for you, you can reverse the procedure. If you create an Ant script to copy everything back to the user directory, and hook it up to a menu item in the IDE, you won't be able to use that menu item the first time you have a fresh and clean user directory, of course, because the menu item won't be in your clean user directory.

Therefore, why not add both the "Save Demi Moore" and the "Revert Demi Moore" Ant scripts to the IDE-wide-targets.xml file. (This is a build.xml file that I've been building over the past blog entries. It contains IDE-wide targets, such as starting and stopping JBoss, opening StarOffice in the IDE, and other things that are not related to a particular project. A target that relates to a particular project is, for example, one that deploys a particular project to a particular server. See previous blog entries for details on this subject.) This means that when I have a fresh user directory, I just need to open this IDE-wide-targets.xml file in the IDE as a free-form project, run the "Revert Demi Moore" script, and all my saved customizations are back in the user directory.

However, I then need to restart the IDE, so that it can load the new menus, menu items, etc. (And then I need to re-order the menus, because new menus end up on the extreme left of the menu bar, irrespective of where I've ordered them before. This means that the order of menus is not saved in my user directory, which is probably a bug.) Still, that's probably less work than digging through all my directories to find the place where I need to paste the saved config directory. And, on top of that, it's just a lot more fun to do it from the IDE, using an Ant script I made myself.

Wednesday Apr 27, 2005

Kickstart Wicket in NetBeans IDE 4.1

"Wicket is a new Java web application framework that takes simplicity, separation of concerns and ease of development to a whole new level. Wicket pages can be mocked up, previewed and later revised using standard WYSIWYG HTML design tools. Dynamic content processing and form handling is all handled in Java code using a first-class component model backed by POJO data beans that can easily be persisted using your favourite technology." (From What is Wicket?.)

  1. Download and unzip the wicket-kickstart-1.0 sources.
  2. In the IDE, click Ctrl-Shift-N. (Or choose File > New Project.) The New Project Wizard appears. Choose Web and then Web Application with Existing Sources:

  3. Click Next and browse to the location where you unzipped the Wicket Kickstart sources. Select the "wicket-kickstart-1.0" folder for the Location field. Name the project "Kickstart". Click Next and Finish.

From a traditional NetBeans IDE (or probably any other) perspective, the structure of the kickstart project is novel, because the HTML file is located within the source package:

However, the reason for this is that everything in a wicket project is nothing more than a component and, in Tim Boudreau's words, "both the HTML and Java code needed are as simple as the things they're supposed to do". He also says that Wicket is "possibly the cleanest solution to POJO web apps that I've seen at release candidate phase". Matt Raible also has some cool things to say about Wicket here. One thing I personally like about Wicket's philosophy is that it "does not introduce any special syntax to HTML. Instead, it extends HTML in a standards-compliant way via a Wicket namespace that is fully compliant with the XHTML standard." They cite JSP as being "by far the worst offender, allowing the embedding of Java code directly in web pages", while most other frameworks "introduce some kind of special syntax to your HTML code". No special syntax! Wow. This is cool, in Wicket's own words, because special syntax "changes the nature of HTML from the kind of pure-and-simple HTML markup that web designers are familiar with, to some kind of special HTML. This special HTML can be more difficult to preview, edit and understand".

Now that you've got the Kickstart up and running (all you need to do to run the Kickstart application is right-click the project and choose Run Project), you should check out the Wicket Stuff site, which "provides additional Java web components to the core components supplied by the Wicket framework". The additional components include Spring, Hibernate, and Groovy. Or check out their cool samples.

Update 5/7/05: You can now download all the Wicket samples as NetBeans projects. When you do so, you can just open them as projects, just like any other project, from inside the IDE. After resolving some dependencies, you can deploy them, just like any other NetBeans IDE project. For more information, and for the downloadable ZIP file, click here.

Tuesday Apr 26, 2005

Easy JBoss Connection Pooling with NetBeans IDE 4.1 and XDoclet

Create the application described in the "Use a Java Class to Access the Data Source" section in the Connecting to Databases chapter of "Using NetBeans IDE 4.1", which is currently a work in progress. It consists of a Java class that accesses one of the default PointBase databases and displays two fields ("name" and "city") on a JSP page.

Fast Track: Too lazy to create the application yourself? Or maybe you just want to see how JBoss connection pooling works with NetBeans IDE 4.1. Either way, you can download the application here. And then open it in the IDE and take all the steps below to quickly set up JBoss connection pooling.

Note that the org.me.customer.CustomerDAO class accesses the database via a data source called jdbc/poolDB. It uses this code to make the connection to the data source:

private javax.sql.DataSource getPoolDB() throws javax.naming.NamingException {
        javax.naming.Context c = new javax.naming.InitialContext();
        return (javax.sql.DataSource) c.lookup("java:comp/env/jdbc/poolDB");
}

(The code above was generated by the IDE, as described in this blog entry.)

The jdbc/poolDB data source referred to in the code above doesn't exist yet. In the Connecting to Databases chapter you can see how to set up a data source on the Sun Java System Application Server and on the Tomcat Web Server, since both servers are officially supported in NetBeans IDE 4.1.

In the following steps, you will create a data source on the JBoss server and access it from NetBeans IDE 4.1.

  1. Create the data source. In the JBoss installation directory, go to docs/examples/jca and copy pointbase-ds.xml to your JBoss deployment directory. (The pointbase-ds.xml file, along with many other database-server-specific templates, is kindly provided by the JBoss folks.) For this example, the JBoss deployment directory is its autodeploy directory: server/default/deploy. Now customize the pointbase-ds.xml template so that it looks as follows:

    <datasources>
       <local-tx-datasource>
          <jndi-name>jdbc/poolDB</jndi-name>
          <use-java-context>false</use-java-context>
          <connection-url>jdbc:pointbase://localhost:9092/sample</connection-url>
          <driver-class>com.pointbase.jdbc.jdbcUniversalDriver</driver-class>
          <user-name>pbpublic</user-name>
          <password>pbpublic</password>
          <metadata><type-mapping>PointBase</type-mapping></metadata>
      </local-tx-datasource>
    </datasources>

    That's it. You now have a JBoss data source. It is called jdbc/poolDB and provides access to the Sample database that is part of the default PointBase installation.

  2. Set the JBoss Port Number. Make sure that you like JBoss's port number. The default port number is 8080. This may conflict with other port numbers (especially if you have been playing with multiple servers). Therefore, go here in the JBoss installation directory and take a look:

    \\server\\default\\deploy\\jbossweb-tomcat50.sar\\server.xml

    Just search for "8080" in the file and change it to something else.

  3. Make the PointBase database driver available to JBoss. Do this by copying pbclient from the PointBase installation directory to the lib directory within the JBoss server's installation directory. For the JBoss autodeploy directory, the applicable lib directory is server/default/lib.
  4. Get Ant targets for starting and stopping JBoss from the IDE. Download servers-build.xml and servers-build.properties from Brian Leonard's article Integrating NetBeans with other J2EE Server Vendors. Put them in the same directory as where your application's build.xml file is found. Now open the build.xml file and add the following import statement after the existing import statement:

    <import file="servers-build.xml"/>
  5. Start JBoss from the IDE. Modify the jboss.home property in servers-build.properties and run the jboss-start target. Run it from inside the IDE (you can create a menu item, toolbar button, or shortcut key for it, as described in earlier blog entries). JBoss starts up and the Output window displays output received from JBoss. You'll see a lot of output and it might take a while. Somewhere near the end you should see something similar to the following (truncated here for easier reading):

    12:34:14,906 INFO  [WrapperDataSourceService] 
    Bound connection factory for resource adapter 
    for ConnectionManager 'jboss.jca:service=DataSourceBinding,name=jdbc/poolDB 
    to JNDI name 'jdbc/poolDB'

    This means that the jdbc/poolDB is available and that you can access it.

  6. Build the project to the JBoss autodeploy directory. Right-click the project in the Projects window to build it. (You can also build it in the Files window -- choose File > Set Main Project, set the current project as the main project, and click F11 whenever you want to build.) Modify the jboss-deploy target in servers-build.xml so that war.name is used instead of jar.name. Now run the jboss-deploy target. (If you haven't built the project, you'll get errors because the WAR file that the target tries to copy to the JBoss deployment directory hasn't been built yet.) This copies the application's WAR file to the JBoss autodeploy directory. In the Output window you should see something similar to the following:

    Copying 1 file to C:\\jboss\\jboss-4.0.1sp1\\server\\default\\deploy
    BUILD SUCCESSFUL (total time: 0 seconds)

    Now that the application is in the JBoss autodeploy directory, JBoss deploys it automatically...

  7. Start PointBase. In the IDE, choose Tools > Pointbase Database > Start Local Pointbase Database.
  8. Access the application's URL. Modify the jboss.client.url property in servers-build.properties so that it points to the JBoss port number and so that the name of the project replaces the name used by Brian's project. Now run the jboss-runapp target. This opens the IDE's default browser and displays the application as found in the JBoss autodeploy directory. You will get a 404 error message in your browser, with this helpful description: "The requested resource (/CustomerNameAndCity) is not available." Back in the IDE, run the jboss-stop target. Once JBoss has stopped, run the jboss-start target again. JBoss will produce this error in the Output window (truncated here for readability):

    javax.naming.NamingException: resource-ref: 
    jdbc/poolDB has no valid JNDI binding. 
    Check the jboss-web/resource-ref.

    This means... we need a jboss-web.xml file, containing a <resource-ref> section. We will use XDoclet to generate the file as well as its <resource-ref> section.

This is how to add XDoclet to the mix:

  1. Get XDoclet. Download and extract XDoclet 1.2.2.
  2. Get the Ant target for creating the jboss-web.xml file from the IDE. Download xdoclet-web-build and xdoclet-web-build.properties from Brian Leonard's article Integrating NetBeans with other J2EE Server Vendors. Put them in the same directory as where your application's build.xml file is found. Open the xdoclet-web-build.properties file and make sure the xdoclet.root.dir property is set appropriately. Now open build.xml and add the following import statement after the existing import statement:

    <import file="xdoclet-web-build.xml"/>
  3. Add @jboss comments to a Java class. In org.me.customer.CustomerDAO, add the following as comments right above the class declaration:

    \*  @jboss.resource-ref  res-ref-name="jdbc/poolDB"
    \*                       jndi-name="jdbc/poolDB"

    This must be in the right place -- i.e., not in the comments right at the top of the file, but in the comments that come in between the import statements and the class declaration.

  4. Customize and run the target from the IDE. Modify the webdoclet target in xdoclet-web-build.xml so that the fileset looks as follows:

    <fileset dir="${src.dir}">
        <include name="\*\*/\*\*.java"/>
    </fileset>

    Now run the webdoclet target. You'll see a nice big comment block in the Output window (thanks to Demi Moore) and when you go to your application's web/WEB-INF directory you will see your brand new jboss-web.xml file. This file contains the following important tags:

    <resource-ref>
      <res-ref-name>jdbc/poolDB</res-ref-name>
      <jndi-name>jdbc/poolDB</jndi-name>
    </resource-ref>
  5. Redeploy, including the jboss-web.xml file. Now build the project again, run the jboss-deploy target to deploy the WAR file to the JBoss deployment directory, and then run the jboss_runapp target again. You will now see the PointBase Sample database's "name" and "city" fields displayed in the IDE's default browser:

Monday Apr 25, 2005

Lucky You: No Deleting of Projects in NetBeans IDE 4.1

One cool thing about blogs.sun.com is that I can see exactly what someone typed in a search engine to get to my blog. So, what happens is, someone types in a query in a search engine (mostly Google, but many others too), a long list of links is returned, one of which is the one to my blog. When someone then clicks on the link to my blog, the query that they typed in is recorded somewhere in the settings pages of my blog. Cool, huh? (Check out Roumen's blog entry today, about Javadoc Support in NetBeans, which he wrote because several people found his blog after querying "javadoc NetBeans".)

Over the last few days I've been collecting the queries randomly, every once in a while, and here they are, just to show what kind of things people seem to be looking for:

  • how do i create a menu item for an ant target in netbeans 4.1
  • jboss JSP IDE example
  • add a new menu to netbeans 4.1 that is an ant target
  • netbeans start tomcat 5.5.7
  • netbeans can't start 5.5.7
  • netbeans problems with tomcat 5.5.7
  • stop jboss from netbeans 4.0
  • jstl jboss ide
  • netbeans 4 jboss
  • deleting a netbeans project
  • Tomcat monitor
  • jsp editor
  • netbeans ide 4.1 and jboss
  • build web application in jboss
  • migrating ant from one server to another
  • client.urlPart=
  • NETBEANS DELETE A PROJECT
  • difference tomcat4 tomcat 5.5
  • netbeans 4.1 + jboss integration
  • netbeans 4.1 + jboss
  • JBoss 4.0 +Tomcat 5.5 +Connect
  • monitor jboss
  • jasper and ant script
  • start jboss from ant
  • jboss relative file read
  • netbeans deploy war server.xml
  • building and deploying a sample application on jrun using ant?
  • remote debugging jboss 4
  • exclude port on web connector with jrun4

One interesting thing is that every other day or so, there are people out there typing variations on "How do I delete a NetBeans IDE project?" (The capitalization of the "NETBEANS DELETE A PROJECT" in the list above is probably a reflection of the querier's frustration at not being able to work out how to delete a project in the IDE!) Well, you can't delete a project in the IDE (you can close it, however). As far as I'm aware, the reason for that is that a user might think that by deleting a project, they're only deleting it from the IDE (i.e., they might think they're just closing the project). Imagine the scene: After months and months of work your project is pretty much complete and you think to yourself: "Hmmm. I don't need this in my IDE anymore." So, you right-click the project and choose "Delete Project". You get a warning that says "Are you sure you want to do this?" and you think: "Yeah, sure. I don't need this in the IDE anymore." So you click OK and you've deleted your project from the file system! Lucky you -- this scenario will never happen in NetBeans IDE 4.1. If you want to delete your project, you'll have to do it in the file system. And you won't be able to blame NetBeans IDE when you do so accidentally...

Sunday Apr 24, 2005

NetBeans IDE 4.1: No More Worrying About Database Connections

In one of my first blog entries (Servlet Connection Pooling for Dummies), I explained the cool NetBeans IDE feature that allows you to see a JSP's translated servlet after it has been deployed. It has to be deployed first before you can see it, because the servlet that you see is translated by the server, hence it needs to be there before it can be translated. In that blog entry I mentioned that one way to connect to a database from a servlet is to simply copy the translated servlet and use that. However, as also pointed out in that blog entry, the disadvantage of that method is that each server translates a JSP page differently, so that you'd end up with an application that isn't really portable. On top of that, it seems like the server generates a lot of garbage and, as a result, I've found the translated servlet quite hard to read.

I've been generally quite daunted by servlets -- and Java source files in general -- and have tended to stick to JSP pages. So, I was pleasantly surprised this morning, while updating the Connecting to Databases chapter for the Using NetBeans IDE 4.1 Guide, to discover that the IDE can generate a whole bunch of code for you -- specifically, the code that makes the connection with the database -- which is not only helpful in general but also means that there's at least one part of my code that I can rely on as being correct. When debugging my Java source code in the past, it was often hard to know exactly where a problem originated. Now, when I'm creating Java source files that access a database, I can be sure that at least the database connection is not the place where things have gone haywire.

And it's all made possible with this dialog box:

It appears when I right-click anywhere in the body of a class in the Source Editor and choose Enterprise Resources > Use Database. After specifying the JNDI name of the data source, together with the connection URL, I click OK and get this:

   private javax.sql.DataSource getPoolDB() throws javax.naming.NamingException {
        javax.naming.Context c = new javax.naming.InitialContext();
        return (javax.sql.DataSource) c.lookup("java:comp/env/jdbc/poolDB");
    }

Before, when I had to come up with the code for the database connection myself, I'd always be thinking, "Now is this the correct format for my connection string?" But now the IDE does all that thinking for me. And the IDE also gives me this in my in my web.xml file:

  <resource-ref>
    <description>jdbc:pointbase://localhost:9092/sample [pbpublic on PBPUBLIC]</description>
    <res-ref-name>jdbc/poolDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
  </resource-ref>

...and this in my sun-web.xml file (but nothing in context.xml in 4.1 -- it's a known issue):

  <resource-ref>
    <res-ref-name>jdbc/poolDB</res-ref-name>
    <jndi-name>jdbc/poolDB</jndi-name>
  </resource-ref>

So now, instead of thinking about the connection, I'm left thinking about how to use it. Pretty cool.

Thursday Apr 21, 2005

Efficient Deployment via Ant Scripts from NetBeans IDE 4.1

Until now, I've been creating unnecessarily complex Ant scripts for deployment of applications to the server. What I've been doing is writing scripts that compile the classes and then move the whole application, piece by piece, to the server. (I don't compile the JSP pages, because the server does that automatically. In the case of Tomcat, JSP compilation happens the first time a JSP page is accessed. Click here for an earlier blog entry on this.) Then the server deploys it automatically, because I've moved the application to a very specific place on the server: its autodeploy directory. (For example, for JBoss this is \\server\\default\\deploy.)

However, now that I've read Brian Leonard's article Integrating NetBeans with other J2EE Server Vendors, I realize I've been doing a lot of unnecessary work, at least for standard IDE projects. This is the target he uses to deploy his application:

 <target name="jboss-deploy" depends="init" description="Deploy to JBoss">
      <copy file="${dist.dir}/${jar.name}" todir="${jboss.deploy.dir}"/>
 </target>

Could it be any simpler?! Since the IDE's build script can compile the classes for you, and since it also creates an archive file (EAR, WAR, or JAR) from your application, what's the point of redoing all of that? None. Except, of course, when you're using your own Ant script (i.e., in a free-form project), which means that the IDE doesn't compile classes nor create archive files unless you specifically provide Ant targets for this purpose. But even in that case, it makes more sense to compile and build everything in some local directory and, once everything is nicely wrapped up in an archive file (by the way, I miss the days when an EAR was the thing attached to my head, a WAR was a fight between countries, and a JAR contained nothing but milk), to move only that archive file to the server's autodeploy directory.

Once the archive file is in the server's autodeploy directory, all you've got to do is open a browser, type in the host, the server's port number, and the application's context (together with, optionally, a relative URL), and you're done. (In other words, you don't even need an Ant target for this. But then, you don't really need an Ant target to copy the archive file to the server's autodeploy directory either -- you could simply go into your filesystem, copy the archive file in your NetBeans project folder, and then paste it in your server's autodeploy folder. But then again, that's why we're using an IDE, to be able to do everything from one place with one click of one button or one menu item.) This is how Brian does it in his article:

  <target name="jboss-run-app" description="Launch application in browser">
     <nbbrowse url="${jboss.client.url}"/>
  </target>

  jboss.client.url=http://localhost:8080/FiboApp-WebModule/index.html

There are two weird things about JBoss, however. The first is that even though it deploys an archive file, you can't access the deployed application at jar.name (the full name of the archive, i.e., together with the extension), but only at the application name. (And I think Brian's jboss.client.url specifically names the application because he wasn't aware that ant.project.name concatenates to the same thing. This property isn't visibly exposed in any file anywhere and I found out about it from some NetBeans developers a week or two ago.) When you use Tomcat, for example, you can access the application in your browser using the full name of the archive (i.e., including the extension). Secondly, when Tomcat deploys an archive, it automatically unpacks it so that you can see exactly what has been deployed. Unfortunately, JBoss doesn't do this.

So, getting back to the point, since the server needs nothing more than an archive file, my Ant file is going to be much shorter, neater, and more compact than it would otherwise be. And, with both standard and free-form projects, compiling and building applications is something that I will do locally, using the IDE where possible, and only move the archive file (EAR, WAR, or JAR) to the server's autodeploy directory.

Wednesday Apr 20, 2005

NetBeans IDE 4.1, Ant, and Demi Moore

I've learnt quite a lot from Brian Leonard's article Integrating NetBeans with other J2EE Server Vendors. One relatively minor, but nonetheless useful, thing I've picked up from some of the Ant scripts attached to his article is the fact that they have big <echo> blocks. Take, for example, this target, which I referred to in a previous blog entry:
   <target name="webdoclet" depends="init, init-xdoclet" 
       description="Generate deployment descriptors (run actionform to generate forms first)">

        <echo>+---------------------------------------------------+</echo>
        <echo>|                                                   |</echo>
        <echo>| R U N N I N G   W E B D O C L E T                 |</echo>
        <echo>|                                                   |</echo>
        <echo>+---------------------------------------------------+</echo>

        <webdoclet destdir="${web.docbase.dir}/WEB-INF"            
                 excludedtags="@author"
                    addedtags="@xdoclet-generated at ${TODAY},@copyright The XDoclet Team,@author XDoclet"            
                      verbose="false">
            
            <fileset dir="${src.dir}">
                <include name="\*\*/\*Servlet.java"/>
            </fileset>

            <jbosswebxml version="4.0"/>

       </webdoclet>

   </target>

When you run this target, you get a really scannable Output window:

But don't stop there! You don't want to have to type that big block in every time do you? And copy-pasting can be tedious too. Let's create a macro instead:

  1. In the Source Editor, press Ctrl-J, and then S. The bottom of the Source Editor indicates that you are recording a macro:

  2. Now type the complete <echo> block into the Source Editor. (Maybe, instead of "W E B D O C L E T" write something like "N A M E L E S S", or something, so that you remember to change it to the actual name of the target when you use the macro later.)
  3. When it's all ready, press Ctrl-J, and then E. The macro stops recording and the Recorded Macro dialog box appears. Give the macro a name, like "Ant Comments Block".
  4. When you click Add, you're able to enter the exact key strokes that you will type to invoke the macro. Make sure that you don't choose a key combination that is used elsewhere (see the Keyboard Shortcuts card, in the IDE's Help menu, for a list of the IDE's most important shortcuts). You should type in a very obscure set of awkward key strokes here, such as Ctrl-F6-Shift-2-F9. But why be boring? How about this:

    Now, whenever you type Shift+demimoore in an XML file in the Source Editor, you will get your nice big <echo> block. (A short-named male equivalent is Shift+bradpitt.)

    But what do you do when it dawns on you that even though Demi Moore and Brad Pitt have conveniently short names, you would far rather invoke more proficient actors, such as Emily Watson or Juliette Lewis? (For the male equivalent, Jeremy Irons and Sean Penn are surely preferable to Brad Pitt. Come to think of it, Sean Penn has just as few letters in his name as Brad Pitt.) Go to Tools > Options, expand Editing, then Editor Settings, select the XML Editor node, click Key Bindings in the Properties list, click Sort by Name, and scroll down to the macro of your choice. (Note that all the macro names are prefaced with macro- in this list, so that you can find them together even though their names begin with different letters.)

In this way, you can integrate Demi Moore into NetBeans IDE 4.1.

Tuesday Apr 19, 2005

Monitor HTTP Requests on JBoss 4 from NetBeans IDE 4.1

So now that I can start JBoss and stop JBoss from the IDE, generate JBoss deployment descriptors from the IDE, deploy an application from the IDE to JBoss, and use the NetBeans IDE debugger to connect to JBoss and debug my application (as explained in previous blog entries), there's nothing more I can do to integrate JBoss with NetBeans IDE 4.1. Right? Wrong. There's also the cool HTTP Monitor which, according to the final section of "Chapter 6: Web Applications" in the NetBeans IDE Field Guide - Draft Chapters, is cool for the following reasons:

NetBeans IDE provides a built-in HTTP Monitor to help isolate problems with data flow
from JSP and servlet execution on a Web server. There is no need to add logic to your Web
application to trace HTTP requests and associated state information. The NetBeans IDE built-in
HTTP Monitor can do this for you.

When the IDE is configured with a Web container or a Web application is deployed with a
NetBeans HTTP Monitor servlet filter and filter mapping, the HTTP Monitor will automatically
record all HTTP requests made to the Web container. For each HTTP request that is processed
by the Web container, the HTTP Monitor not only records the request, it also records state
information maintained in the Web container.

By using the HTTP Monitor, you can analyze HTTP requests, and store HTTP GET and
HTTP POST requests for future analysis sessions. You can also edit these stored requests and
replay them. This is a powerful feature to help isolate data flow and state information passed
within an HTTP request to a Web container. HTTP requests are stored until you exit the IDE
unless you explicitly save them.
The HTTP Monitor is easily enabled if the server you're using is registered in NetBeans IDE 4.1. Only the Sun Java System Application Server and the Tomcat Web Server can be registered in IDE 4.1. JBoss can't. But does that mean that we can't use the HTTP Monitor with JBoss? No, it doesn't. The steps to set it up are reasonably simple (and are also described in the IDE's own help system):

  1. Right-click the project's Libraries node in the Projects window. Choose Add JAR/Folder and add the following JARs:

    netbeans-installation-dir/enterprise1/modules/ext/org-netbeans-modules-web-httpmonitor.jar
    netbeans-installation-dir/ide5/modules/org-netbeans-modules-schema2beans.jar
  2. Build the project. When you build a standard project, the JARs get moved to the build/web/WEB-INF/lib folder. This is very important to know because, when you build the project to JBoss's deployment directory, at the end of these instructions, you must include these JAR files. Knowing the exact location to which the IDE moves the JAR files allows you to create the appropriate Ant build script to copy them to JBoss.

  3. In the IDE, go to the web.xml file and double-click it. The cool (new in NetBeans IDE 4.1) web.xml Visual Editor opens in the Source Editor. Go to the Filters tab at the top of the editor, click Add Filter Element, and add the following values:

    • Filter Name: HTTPMonitorFilter
    • Filter Class: org.netbeans.modules.web.monitor.server.MonitorFilter

    Click OK, click on Add in the "Initialization Parameters" subsection, and add the following values:

    • Param Name: netbeans.monitor.ide
    • Param Value: name-of-host-that-runs-IDE:port-of-internal-HTTP-server

    To find out the port of the internal HTTP Server, go to the Runtime window, right-click the HTTP Server node, choose Properties, et voila, there it is. For me, it is set to 8086 (probably the default, at least for Windows).

    Click OK, click on the Filter Mappings header below, click Add, and add the following values:

    • Filter Name: HTTPMonitorFilter
    • URL Pattern: /\*
    • Dispatcher Types: REQUEST, FORWARD, INCLUDE, ERROR

    Click OK. You should now have the following in the web.xml Visual Editor:

    And when you click XML at the top of the editor, the following will be included in the web.xml file:

      <filter>
        <filter-name>HTTPMonitorFilter</filter-name>
        <filter-class>org.netbeans.modules.web.monitor.server.MonitorFilter</filter-class>
        <init-param>
          <param-name>netbeans.monitor.ide</param-name>
          <param-value>localhost:8086</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>HTTPMonitorFilter</filter-name>
        <url-pattern>/\*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
      </filter-mapping>
  4. Go to the Runtime window, right-click the HTTP Server, and click Start Server.

  5. Now build and deploy your application to JBoss. Remember that you need the JAR files that you picked up in step 1 to be included with the resources that you've copied to JBoss's deployment directory! When you run the application, the HTTP Monitor will start up in the IDE:

    Now you can do any and all of the following:

    • Analyze HTTP requests records.
    • Save HTTP request records.
    • Edit HTTP request records.
    • Refresh request records.
    • Sort HTTP request records.
    • Delete HTTP request records.
    • Replay HTTP request records.

    Two very important notes:

    • Whenever you restart the IDE, you should also restart the HTTP Server, if you want to use the HTTP Monitor with JBoss (or any other server other than the Tomcat Web Server). What I did, a few times, is exit the IDE, restart the IDE, build and deploy to JBoss, and then wonder: "Huh? Where's the HTTP Monitor?" The reason why it didn't appear was because I hadn't restarted the HTTP Server...
    • Since the HTTP Monitor is used to debug in the pre-production phase of your development cycle, remember that when you deploy the application to a production server, you should remove the JAR files from your project and remove the filter and filter mapping declarations from the web.xml file.

A good application to test all of this out on is the "Midnight Cookie" application, which is what you end up with at the end of the NetBeans IDE 4.1 Tutorial for Web Applications. In fact, the second part of that tutorial provides extensive information, including many screenshots, on the various things you can do with the HTTP Monitor.

Develop in NetBeans IDE 4.1, Deploy Anywhere

An unnamed developer, in an as-yet unpublished article, which I was lucky enough to read, really clarified a couple of things for me today. In a recent blog entry, it suddenly dawned on me that even though I had some cool little Ant scripts (hooked up to cool little NetBeans IDE menu items) for starting, debugging, stopping, testing, and deploying to a variety of servers (JBoss 4, Tomcat 4, and JRun 4), I couldn't really develop much in the IDE for these servers, because each has its own server-specific deployment descriptors (such as sun-web.xml, jboss-web.xml, jboss.xml, config.xml). At the end of that blog entry I had a brief Eureka moment, when I blogged the fact that I had just discovered the Migration Tool for the Sun Java System Application Server 8 Download.

However, thanks to this unnamed developer (unnamed because his article hasn't been officially released yet) my Eureka moment is even bigger. I hope I'm not stealing his thunder, but his article mentions the absolutely brilliant XDoclet, which can transform deployment descriptors from one server vendor into the deployment descriptors of another. I guess to many people that's not really news, because XDoclet's been around for a while. But, for me, the following is pretty revolutionary:

    <target name="Transform-JBoss-Web" depends="init,init-xdoclet" description="Generate web deployment descriptors">
     
       <webdoclet destdir="${build.dir.jboss}/WEB-INF" 
                excludedtags="@author" 
                addedtags="@xdoclet-generated at ${TODAY},@copyright The XDoclet Team,@author XDoclet" 
                verbose="false">
            
            <fileset dir="${src.root}">
                <include name="\*\*/\*Servlet.java"/>
            </fileset>

            <jbosswebxml version="4.0" />
            
        </webdoclet>
        
   </target>

Anyway, that's all I'm going to say, because otherwise the unnamed developer's article is not going to be as cool and educational as I suspect it will be.


Update 04/20/05: Click here to read the cool article referred to above.


Sunday Apr 17, 2005

Remote Debugging from NetBeans IDE 4.1 to JBoss

Yes, NetBeans IDE can follow you everywhere. The only thing it can't do is your laundry (believe me, I've tried). So even though you've deployed to servers that the IDE doesn't "officially" support, such as JBoss (or Tomcat 4 or JRun4), not only can you start them, stop them, and deploy to them from within the IDE (as explained in previous blog entries), but you can also use the NetBeans IDE debugger to step through the source code on the server.

Here's what I did to get it all working:

  1. Create a target to build the application to the server's deployment directory. (One disadvantage of an IDE is that when you're just using menu items to do things like 'Build', you don't need to know what's really going on. Now, with Ant, you have to know, because otherwise you can't tell Ant what you want it to do.) This is the script that I've been using:

     <target name="aaa_Build-To-JBoss" description="Build to JBoss">
    
         <mkdir dir="${build.dir.jboss}/WEB-INF/classes"/>
         <javac srcdir="${src.root}"
                   destdir="${build.dir.jboss}/WEB-INF/classes"
                   debug="on"
                   deprecation="${compile.deprecation}"
                   optimize="${compile.optimize}">
             <classpath>
                <path path="C:\\nb41\\netbeans\\enterprise1\\jakarta-tomcat-5.5.7\\common\\lib\\servlet-api.jar"/>
             </classpath>
         </javac>
    
         <copy  todir="${build.dir.jboss}/WEB-INF/classes">
          <fileset dir="${src.root}" excludes="${build.classes.excludes.jboss}"/>
         </copy>
     
         <copy todir="${build.web.dir.jboss}">
            <fileset dir="${web.root}" excludes="${build.web.excludes.jboss}" />
         </copy>
    
     </target>

    (You will need to copy more <filesets> if you have a more complex application with libraries, web services, etc. However, note that I've discovered a much more efficient way of doing this. Click here for details.)

    Note: What's very very very important in the target above is the debug setting. Without it, debug information is not generated and, even though the NetBeans IDE debugger will be happily attached to the server, it will not be able to do anything with your Java code. (I've hard-coded it above, but will change it to a property later.)

    Here are the properties referenced above:

    build.dir.jboss=C:/jboss/jboss-4.0.1sp1/server/default/deploy/${ant.project.name}.war
    build.classes.dir.jboss=${build.dir.jboss}/WEB-INF/classes
    build.classes.excludes.jboss=\*\*/\*.java,\*\*/\*.form
    build.web.dir.jboss=${build.dir.jboss}
    build.web.excludes.jboss=${build.classes.excludes.jboss}
    build.lib.dir.jboss=${build.dir.jboss}/WEB-INF/lib
    src.root=src/java
    web.root=web
    compile.deprecation="off"
    compile.optimize="on"

    Note: Make sure that you specify a ".war" extension for the build.dir.jboss property, as specified above. Without it (or, I guess, an extension such as ".ear"), JBoss doesn't deploy the application.

    To round off this step, go to JBoss's deployment directory (see build.dir.jboss above) and make sure that your application is really there (you could, of course, simply have copied your application to a directory with the project's name, suffixed with .war, within the deployment directory, but if you create a target to do it all for you, together with a menu item to invoke the target, all that manual copying and pasting becomes obsolete and you can rely on the security of knowing you're deploying correctly every time):

    If your application's there (also check that your compiled classes are there), you're good to go, because the server automatically deploys your application for you.

  2. Make sure that you like JBoss's port number. The default port number is 8080. This may conflict with other port numbers (especially if you have been playing with multiple servers). Therefore, go here in the JBoss installation directory and take a look:

    C:\\jboss\\jboss-4.0.1sp1\\server\\default\\deploy\\jbossweb-tomcat50.sar\\server.xml

    Just search for "8080" in the file and change it to something else. (Mine is set to 8090.)

  3. Now create a script to start JBoss in debug mode:

      <target name="RunJBoss-Debug-Mode">
        <exec executable="C:\\jboss\\jboss-4.0.1sp1\\bin\\run.bat">
          <env key="JAVA_OPTS" value="-Xrunjdwp:transport=dt_socket,server=y,address=12999,suspend=n" />
        </exec>
      </target>

    (If you don't know what's going on with the value of JAVA_OPTS above, you need to read up about the Java Platform Debugger Architecture - JPDA Connection and Invocation.)

    But don't stop there! Add a menu item (explained in previous blog entries) so that you can truly integrate JBoss into the IDE:

    When you run this target, you'll see this line near the top of the Output window:

    JAVA_OPTS: -Xrunjdwp:transport=dt_socket,server=y,address=12999,suspend=n -Dprogram.name=run.bat -Xms128m -Xmx512m
    Much further down, you'll see the server's port number:

    14:47:41,375 INFO  [Http11Protocol] Initializing Coyote HTTP/1.1 on http-0.0.0.0-8090
  4. Deploy the application, using the target below. All that this really means is that the IDE opens a browser, finds the port number, and displays the application called ${ant.project.name}, which is the IDE project's name in the project.xml file.

      <target name="aaa_Deploy-To-JBoss" description="Deploy to JBoss">
        <nbbrowse url="http://localhost:8090/${ant.project.name}"/>
      </target>
  5. In the IDE, choose Run > Attach Debugger. Set the following values:

    Click OK. You should now see the following in the IDE's Debugger Console:

    Attaching to localhost:12999
    User program running
  6. Set breakpoints in, for example, a Java class.
  7. Take a deep breath -- this is where it all comes together! Go back to the browser, refresh it, and do something to access the class. For example, I've been using a very simple test application that you can create using instructions provided here. When you build this application to the JBoss deployment directory, set breakpoints in NameHandler.java, and then click OK in the deployed index.jsp, you access response.jsp, which in turn makes use of NameHandler.java. When you access this file, or any file where the breakpoints have been set, the NetBeans IDE icon at the bottom of the screen will begin flashing (at least, this is true on Windows XP) and, when you go back to the IDE, you will see a green line on your breakpoint. Now use the debugger as you would do with any other application -- step into, over, set watches, etc. Click here for a nice introduction to the NetBeans IDE debugger.

The above instructions should be equally applicable to other servers, of course, such as Tomcat 4 and JRun4. You will need to tweak a few things here and there (such as specifying the deployment directory for the server of your choice and starting up the server correctly in debug mode), but everything here should basically work anywhere else too.

Deploy to JBoss4, Tomcat 4, JRun4... Debug from NetBeans IDE 4.1!

Yes, NetBeans IDE can follow you everywhere. The only thing it can't do is your laundry (believe me, I've tried). So even though you've deployed to servers that the IDE doesn't "officially" support (such as JBoss4, Tomcat 4 and JRun4), not only can you deploy to them from within the IDE (as explained in previous blog entries), but you can also use the NetBeans IDE debugger to step through the source code on the server.

Here's what I did to get it all working:

  1. Build the application to the server's deployment directory. (One disadvantage of an IDE is that when you're just using menu items to do things like 'Build', you don't need to know what's really going on. As a result, you don't know. Now, with Ant, you have to know, because otherwise you can't tell Ant what you want it to do.) This is the script that I've been using:
     <target name="aaa_Build-To-JBoss" description="Build to JBoss">
         <mkdir dir="${build.dir.jboss}/WEB-INF/classes"/>
         <javac srcdir="${src.root}"
                   destdir="${build.dir.jboss}/WEB-INF/classes"
                   debug="on"
                   deprecation="${compile.deprecation}"
                   optimize="${compile.optimize}">
             <classpath>
                <path path="C:\\nb41\\netbeans\\enterprise1\\jakarta-tomcat-5.5.7\\common\\lib\\servlet-api.jar"/>
             </classpath>
         </javac>
    
         <copy  todir="${build.dir.jboss}/WEB-INF/classes">
          <fileset dir="${src.root}" excludes="${build.classes.excludes.jboss}"/>
         </copy>
     
         <copy todir="${build.web.dir.jboss}">
            <fileset dir="${web.root}" excludes="${build.web.excludes.jboss}" />
         </copy>
     </target>

    What's very important is the debug setting. Without it, debug information is not generated and, even though the NetBeans IDE debugger will be happily attached to the server, it will not be able to do anything with your code. (I've hard-coded it above, but will change it to a property later.)

    Here are the properties referenced above:

    build.dir.jboss=C:/jboss/jboss-4.0.1sp1/server/default/deploy/${ant.project.name}
    build.classes.dir.jboss=${build.dir.jboss}/WEB-INF/classes
    build.classes.excludes.jboss=\*\*/\*.java,\*\*/\*.form
    build.web.dir.jboss=${build.dir.jboss}
    build.web.excludes.jboss=${build.classes.excludes.jboss}
    build.lib.dir.jboss=${build.dir.jboss}/WEB-INF/lib
    src.root=src/java web.root=web compile.deprecation="off" compile.optimize="on"

    To round off this step, go to JBoss's deployment directory and make sure that your application is really there. (If it's there, it's good to go, because the server automatically deploys it for you.

Friday Apr 15, 2005

Migrating Applications Between Servers

I occasionally teach English here in Prague. Just recently, I've been teaching the phrasal verb "to dawn on". Well, here's a great application of that verb: "It suddenly dawned on me that even though Ant-integration in NetBeans IDE 4.1 (and 4.0) enables you to integrate as many servers into the IDE as your Ant skills and server-knowledge allow (see previous blog entries), that does not mean that you can simply deploy any application wherever you want without going through a painful migration process." (Okay, so it's a rather long and unwieldy sentence. I guess I won't use it as an example in my next English class.) In this article, it appears that Ajit Sagar had a similar dawning, after thinking it would all be a piece of proverbial cake (and he's only talking about migrating from one version of a server to another):

...I couldn't have been more mistaken. The migration was a big deal. After working on a few of these projects, I can verify that the amount of moving parts in a machine composed of various portfolios, frameworks, third-party vendors, and a variety of stakeholders made the planning for such an initiative a formidable undertaking.

That's actually a pretty interesting article. Anyway, so it dawned on me that, on the lowest level, for example, the Sun Java System Application Server has a sun-application.xml file and JBoss has the jboss.xml file (and that all of these servers have one or more server-specific files that need to be migrated). Until this dawning of realisation, I had thought that the only question one would need to ask is whether a server supports a particular specification (e.g., J2EE 1.4) or not. So, even if you're dealing with two application servers that support J2EE 1.4, that does not mean that you're home and dry as soon as you've created Ant scripts and hooked them up to menus inside NetBeans IDE 4.1 (as I've been doing in my recent blog entries). For example, click here to see a recipe for frustration.

So you can imagine how happy I was to discover the Migration Tool for the Sun Java System Application Server 8 Download! Here's a nice summary of the various issues involved (taken from a 110-page document called "Moving from WebSphere Server 4.0 to the Sun™ ONE Application Server 7", which I found on the aforementioned Migration Tool's whitepaper site, and which, according to its summary, only "provides an overview"):

J2EE Application Migration Issues

The varying degrees of compliance to J2EE standards can make migrating applications from one application server to another a daunting task. Some of the challenges when migrating J2EE applications are:

  • Differences in interpretation and implementation of the J2EE API by the various application server vendors.

  • Difference in the J2EE specification level implemented by the source and target application servers.

  • Ambiguity about what J2EE technology-compliant means (usually, this means the application server has J2EE technology-compliant features, not code-level compatibility with the J2EE specification).

  • The number of vendor-supplied extensions to the J2EE standards in use, which differ in deployment methods and reduce portability of Java code. Differences in clustering, load balancing, and failover implementations among application servers are sparsely documented, creating an even bigger challenge to the migration process.

  • Lack of knowledge about the implementation details of a given J2EE application.

Wednesday Apr 13, 2005

Remote Debugging with NetBeans IDE 4.1 and its Bundled Servers

I've been trying to understand remote debugging with NetBeans IDE 4.1, and how this can be achieved for non-standard servers (such as JBoss, Tomcat 4 and JRun4). For the servers that are "officially" supported (i.e., anything can be integrated via Ant, as explained in previous blog entries), the procedure is as follows. I will use this procedure as the basis for understanding how to do it with the others. (The second part of my blog entry from yesterday, about debugging with JRun4, was incorrect, or at least incomplete, and I'm going to have to update it.)
  1. Create and deploy a web application. (For purposes of this procedure, I created the web application described in the NetBeans IDE 4.1 Quick Start Guide for Web Applications. I then deployed the application to both bundled servers.)

  2. In the IDE, go to the Runtime window (Ctrl-5), expand the Servers node, right-click the node for the server, and click Start/Stop Server.

  3. Click Start Server (Debug). This starts the server in debug mode.

  4. In the Output window at the bottom of the screen, you'll see something like this (you'll see the first when starting the Tomcat Web Server in debug mode, and the second for the Sun Java System Application Server in debug mode):

    Listening for transport dt_shmem at address: tomcat_shared_memory_id

    Listening for transport dt_shmem at address: localhost4848

    (To change to a socket connection with a port number, stop the server in the Runtime window, right-click it, choose Properties, and change the Debug settings at the bottom of the Properties dialog box.)

  5. Select Run > Attach Debugger from the main menu.

  6. Choose SharedMemoryAttach in the Connector field and type tomcat_shared_memory_id or localhost4848 in the Name field. (If you're using a socket connection with a port number, choose SocketAttach instead.) You'll see something like this (you'll see the first when attaching to the Tomcat Web Server in debug mode, and the second for attaching to the Sun Java System Application Server in debug mode):

    Attaching to tomcat_shared_memory_id
    User program running
    Attaching to localhost4848
    User program running
  7. Set breakpoints. For example, set them in namehandler.java, if you're using the document mentioned in step 1 above.

  8. In your browser, do something to access the file containing the breakpoints. For example, go to the following URL, if you're using the document mentioned in step 1 above (use the first for the Tomcat Web Server, and the second for the Sun Java System Application Server, assuming you're using the default port numbers):

    http://localhost:8084/HelloWeb/response.jsp
    http://localhost:8080/HelloWeb/response.jsp
  9. In the IDE, you can now step through your code. When using the Sun Java System Application Server, you'll see the following interesting dialog box displayed in the IDE:

Now that I've got this working, I'll start working out how it all works (and if it works) for JBoss, Tomcat 4, and JRun4. Especially in the latter case, I think, there'll be problems (browsing the Internet, I found a few people claiming that debugging isn't supported by JRun4).


Update 04/20/05: Yes, it really works for JBoss, Tomcat 4, and JRun4. And it's pretty similar to how it works for the bundled servers. For details, click here.


Tuesday Apr 12, 2005

Integrating JRun 4.0 with NetBeans IDE 4.1

Yesterday I came across an article by Drew Falkman called IDE Wars: Has NetBeans 4.1 Eclipsed Eclipse?. It is very cool, full of praise for NetBeans IDE 4.1, but in the third part of his story I read the following:

"NetBeans is tightly tied into either TomCat (5 or 5.5) and Sun's J2EE application server. I found no discernable way to integrate with JRun (which I use), and a quick search at their Web site turned up virtually no results or plug-ins or anything which could help me—or any other developer who has opted for a non-Sun backed J2EE application server. With all the great features in this IDE, this might be the Achilles heel."

Well, in previous blog entries, I've shown how JBoss and Tomcat 4 can be integrated with the IDE. Since Drew misses JRun integration in the IDE, let's work through it and see how easy it all is. Before going further, I came across something else (also by Drew Falkman): On this page there is a list of IDE's and how JRun can integrate with them. Interestingly, the Eclipse 2.01 story stretches across 13 pages (admittedly, many of them are filled with screenshots). There's got to be an easier way of doing things with Ant. And there is! So, here's all that needs to be done:

  1. Download and install JRun 4. If you're using JDK 1.5, make sure you also install the JRun 4 Updater 5. (I think the JDK 1.5 issue was fixed in Updater 4, but getting the very latest updater is probably a good idea anyway.)
  2. Integrate the JRun Launcher into the IDE by creating the following Ant target in the IDE's Source Editor (or anywhere else):

      <target name="ShowJRunLauncher">
        <exec executable="C:\\JRun4\\bin\\jrun"/>
      </target>
    Note: I added this target to the IDE-wide-targets Ant file that I've been building over the last few days (see previous blog entries). Then I added it as a shortcut to the new "External Servers" menu that I created in yesterday's blog entry:

  3. Click the JRun Launcher menu item and the following handy little tool appears:

  4. Select the default server (its port number is 8100), and click Start.

  5. In NetBeans IDE 4.1, create your application. (While working on this procedure, I created the free-form project that is shipped with the IDE and described in the second section of the Importing Existing Web Applications into NetBeans IDE 4.1 document.)
  6. Build your application to the JRun deployment folder, as shown below:

      <target name="-Compile-Classes-To-JRun" description="Compile classes to JRun">
    
        <mkdir dir="${build.dir.jrun}/WEB-INF/classes"/>
    
        <javac srcdir="${src.root}"
              destdir="${build.dir.jrun}/WEB-INF/classes"
                debug="${compile.debug}"
          deprecation="${compile.deprecation}"
             optimize="${compile.optimize}"/>
    
        <copy  todir="${build.dir.jrun}/WEB-INF/classes">
          <fileset dir="${src.root}" excludes="${build.classes.excludes.jrun}"/>
        </copy>
     
      </target>
      <target name="-Copy-Web-Files-To-JRun" description="Copy web files to JRun">
    
        <mkdir dir="${build.dir.jrun}/>
        
        <copy todir="${build.web.dir.jrun}">
          <fileset dir="${web.root}" excludes="${build.web.excludes.jrun}" />
        </copy>
     
      </target>
      <target name="aaa_Build-To-JRun" depends="-Compile-Classes-To-JRun,-Compile-Web-Files-To-JRun"/>
    

    (By the way, Ant targets that are prefaced with "-" cannot be run independently and are greyed-out in the Projects/Files windows. Personally, I preface the targets that I need most with aaa_ so that they end up at the top of the list in the Projects/Files windows.)

    Update: I've discovered a much more efficient way of doing this! Click here for details.

    These are the properties I used (the port.number.jrun property is used in the next target):

    #This property is the key to everything, because 
    #C:/JRun4/servers/default is the JRun default server's 
    #deployment directory and ant.project.name is the 
    #name of the project, as specified in the project.xml file 
    #when you create the project:
    
        build.dir.jrun=C:/JRun4/servers/default/${ant.project.name}
    
    #Where the Java sources and web files are built to, and what is 
    #excluded from it, within build.dir.jrun:
    
        build.classes.dir.jrun=${build.dir.jrun}/WEB-INF/classes
        build.classes.excludes.jrun=\*\*/\*.java,\*\*/\*.form
        build.web.dir.jrun=${build.dir.jrun}
        build.web.excludes.jrun=${build.classes.excludes.jrun}
    
    #Compilation options:
    
        compile.debug="true"
        compile.deprecation="false"
        compile.optimize="true"
    
    #Only these properties should ever need to be changed:
    
        port.number.jrun=8100
        src.root=path-to-my-src-folder
        web.root=path-to-my-web-folder

    Note: I added the targets to the project-specific-targets Ant file (and the properties to the related properties file) that I've been building over the last few days. This means I can import the targets into any new or existing web application. This also means I won't accidently delete them when I delete the project.

  7. Then simply deploy the application (we're using the port.number.jrun property defined above):

      <target name="aaa_Deploy-To-JRun" description="Deploy to JRun">
        <nbbrowse url="http://localhost:${port.number.jrun}/${ant.project.name}"/>
      </target>

    Note: Again, this Ant target is part of my project-specific-targets Ant file (see previous blog entries) so that I can re-use it in each project that needs it (and protect it from destruction).

  8. Finally, I can add contextual menus to each of my free-form IDE projects (not to standard IDE projects), so that I can right-click a project node and choose the target I need.

    (This is explained below in the blog entry "Customized Contextual Menu for Deploying from NetBeans IDE 4.1".)

This way, the JRun libraries are not included in my project, instead of that I've used Ant to access all the required executables, libraries, and files. This might be a disadvantage, I don't know. (Including the libraries shouldn't be difficult, for example, read How to setup a basic Struts project using NetBeans IDE 4.0.) The Integrating JRUN server with Eclipse 2.01 document goes on to explain how you can use JRun for debugging. Well, this is also possible from NetBeans IDE 4.1. What you need to do is the following, if you're using shared memory (for socket connections, the procedure is similar):

  1. Add this to java.args in JRun's jvm.config file:

    -Xdebug -Xrunjdwp:transport=dt_shmem,server=y,suspend=n

  2. Click the JRun Launcher menu item defined in the previous section, stop the default server and start it again. Using the change to the java.args setting, the default server now starts in debug mode. You should now see the following in the JRun Launcher window at the bottom of the IDE:

    Listening for transport dt_shmem at address: javadebug
    Starting Macromedia JRun 4.0 (Build 92909), default server

  3. In the IDE, choose Run > Attach Debugger. Choose the shared memory connector in the Connector field and make sure that you specify "javadebug" in the Name field.

So, unless I've misunderstood something, this is all that's needed to integrate JRun with NetBeans IDE 4.1. To me, the coolest parts of the whole integration are the following:

  • You can call the JRun Launcher from the IDE, by creating an Ant script and linking it as a shortcut to a menu item in the toolbar. The JRun Launcher is really nice (I haven't found anything similar in Tomcat or JBoss). By integrating it into the IDE, it's almost as if the JRun Launcher is part of the IDE, because it is just as accessable as any other IDE tool, like the Library Manager or Server Manager. And you can view its output in the JRun Launcher window in the IDE.
  • Ant integration makes it easy to build an application from the IDE (one click on a menu item or toolbar button, or via a keyboard shortcut) to JRun's deployment directory. Once the application is there, JRun automatically deploys it and you can access it via an Ant script that simply launches a browser and points to the JRun server's port number.

In short, Ant integration with NetBeans IDE 4.1 (and everything in this blog entry should be possible in NetBeans IDE 4.0 too) has yet again proved its usefulness...


Update 04/20/05:


Monday Apr 11, 2005

Adding Menus to NetBeans IDE 4.1

Until a few minutes ago, I thought that a shortcut to an Ant target can only be added as a menu item to one of the IDE's default menus, such as "File", or "Build", or "Tools". However, I've just discovered that you can create your own menus, and specify where in the menu bar you want to place them, so that when you create a shortcut, you can add it to your own menu (instead of one of the IDE's default menus).

And there are two ways of doing this. The "official" way is to go to Tools > Options, then IDE Configuration > Look and Feel > Menu Bar. And then right-click the Menu Bar node and choose Add Menu. You can also add submenus, by right-clicking the node of the menu and choosing Add > Menu. (And you can also add separators.) And, when you right-click a node, you can choose Change Order, so that you can reorganize the items within the node. (The "unofficial" way of doing this is to go the IDE's user directory, and then to dev/config/Menu. In this folder, you can add as many menus and menu items as you like, as folders and subfolders, then restart the IDE, so that the IDE can load the new menus.)

Once I had created a new menu called "External Servers", with the submenus "JBoss" and "Tomcat 4", I right-clicked my IDE-wide targets (for running and stopping JBoss and Tomcat 4, as well as one for testing JBoss) in the Projects window, and added them to my new menus. This is how it looks in the Options window:

And this is what my cool new menu items look like in the IDE:

Learning about Build Targets in NetBeans IDE 4.1

I realized that having a single menu item for two different actions (deploying to JBoss and deploying to Tomcat 4) is a bit counter-intuitive. Each time I needed to change servers, I had to change properties so that the target would work for the appropriate server. So, I decided to create separate deployment targets. This meant that I also had to create separate targets for building the application -- if I want to deploy to JBoss, I want to build my application to a JBoss-specific directory and if I want to deploy to Tomcat 4, I want to build my application to a Tomcat-4 specific directory. So, this is my build target for Tomcat 4:

 <target name="aaa_Build-To-Tomcat4" description="Build to Tomcat4">
       <copy todir="${build.classes.dir.tomcat4}">
            <fileset dir="${src.root}" excludes="${build.classes.excludes.tomcat4}"/>
       </copy>
       <copy todir="${build.web.dir.tomcat4}">
            <fileset dir="${web.root}" excludes="${build.web.excludes.tomcat4}" />
       </copy>
 </target>
And my deploy target is still as follows:

  <target name="aaa_Deploy-To-Tomcat4" description="Deploy to Tomcat 4">
    <nbbrowse url="http://localhost:${port.number.tomcat4}/${ant.project.name}"/>
  </target>

And they use the following properties:

#The Tomcat 4 directory where everything is copied to:
 build.dir.tomcat4=c:/Program Files/Apache Group/Tomcat 4.1/webapps/${ant.project.name}

#The Java classes, where they go, and what to exclude:
 src.root=src/java
 build.classes.dir.tomcat4=${build.dir.tomcat4}/WEB-INF/classes
 build.classes.excludes.tomcat4=\*\*/\*.java,\*\*/\*.form

#The web files, where they go, and what to exclude:
 web.root=web
 build.web.dir.tomcat4=${build.dir.tomcat4}
 build.web.excludes.tomcat4=${build.classes.excludes.tomcat4}

#Port number:
 port.number.tomcat4=8085
The key to the whole puzzle was discovering that ant.project.name gets the project's name (which is set in project.xml). What is also pretty cool is that the IDE can generate a build script for you, which means that you can see how it is structured, so that you can create one yourself, even if you are a complete novice in Ant, like me...

Thursday Apr 07, 2005

Customized Contextual Menu for Deploying from NetBeans IDE 4.1

After creating a property-determined Ant target that deploys a NetBeans IDE project to Tomcat 4 or JBoss (see yesterday's blog entry), I wanted to be able to access the target from a project's contextual menu. This is only possible in a free-form project. So I created a free-form project from the build-impl.xml file that the IDE creates for you when you create a standard project. This way, I've got the best of both worlds -- all the standard targets generated by the IDE together with the possibility of extending the project even further, giving it more freedom, thanks to the facilities offered by the free-form project. So here is my contextual menu:

I guess a better name for the contextual menu would be something like "Deploy to External Server", but what if I were to forget which servers are made available in the properties file? At least this way I know what's there.

Tomcat 4, JBoss, and Ant in the NetBeans IDE

So now I have an Ant properties file with the following content:

# Tomcat 4
#port.number=8085
#build.web.dir=c:/Program Files/Apache Group/Tomcat 4.1/webapps/${application.name}
#application.name=WebApplication1

# JBoss
port.number=8082
build.web.dir=C:/jboss/jboss-4.0.1sp1/server/default/deploy/${war.name}
application.name=WebApplication1
war.name=WebApplication1.war
And my Ant script contains one target:

<target name="aaa_Deploy-To-Tomcat4-or-JBoss" description="Deploy to Tomcat 4 or JBoss">
  <nbbrowse url="http://localhost:${port.number}/${application.name}"/>
</target>

When I import (1) the Ant script containing this target and (2) the file defining the target's properties into a NetBeans IDE project's build.xml file (or whatever the local Ant build file is called), I only have to change the handful of properties in the external Ant file's properties file to be able to deploy to either Tomcat 4 or JBoss, after building the project to the build.web.dir applicable to the server in question. (Of course, I also have targets that start and stop Tomcat 4 and JBoss, but these are IDE-wide targets.) This is how I import the Ant script and properties file (they're both in a folder called "IDETargets", which is a different folder to where my IDE projects are stored -- by storing my re-usable targets in a separate folder I'm protecting them from my occasional over-zealous deletions):

<import file="../../IDETargets/ProjectAntTargets/project-specific-targets.xml"/>
<property file="../../IDETargets/ProjectAntTargets/nbproject/project-specific-targets.properties"/>

Here are the 1000 words in a picture:

The cool thing about this is that I now have a separate Ant script that contains all the information I need for deploying to Tomcat 4 or JBoss. Whenever I create a new web application, all I need to do is import the external Ant script and properties file into the new web application's own Ant script, tweak the properties in the external Ant script's properties file, and that's all. No deployment-related information is defined within an individual NetBeans IDE project, and so nothing is lost (and everything is re-usable) when I delete/lose/break an individual NetBeans IDE project.

Wednesday Apr 06, 2005

Structuring Ant Targets in the NetBeans IDE

I've created one build script for IDE-wide targets (for running and stopping Tomcat 4, for accessing the Tomcat users file for Tomcat 5.5, and for easy access to Star Office) and a separate build script for project-specific targets. I'm keeping these two build scripts separate so that (1) I know where to look for my targets and (2) I only need to import the project-specific build script into any project-level build script that might need it.

So, for example, in the illustration below, I only need to import project-specific-targets.xml into a project's build.xml file, because the IDE-wide targets are irrelevant on project-level. The aaa_DeployToTomcat4 task is quite useful because the IDE does not officially support Tomcat 4, but thanks to Ant-integration anything can be integrated into the IDE. (I've prefaced the deployment target for Tomcat 4 with "aaa_" so that it ends up at the top of the list in the build.xml files that import it):

This is what aaa_DeployToTomcat4 looks like:

<target name="aaa_DeployToTomcat4" description="Deploy to Tomcat 4">
    <exec executable="C:\\Program Files\\mozilla.org\\Mozilla\\mozilla.exe">
	<arg value="http://localhost:8085/${project.name}/${client.urlPart}"/>
    </exec>
</target>

(When I installed Tomcat 4, I set the port number to 8085, which is easy to remember because it's just after the IDE's bundled Tomcat's port number 8084, and because Tomcat's default port number is 8080 which is the same as the Sun Java System Application Server.)

And, by the way, this is how I start Tomcat 4 (RunTomcat4 in ide-wide-targets.xml):

<target name="RunTomcat4">
    <exec executable="c:\\Program Files\\Apache Group\\Tomcat 4.1\\bin\\startup.bat">
        <env key="CATALINA_HOME" value="c:\\Program Files\\Apache Group\\Tomcat 4.1"/>
        <env key="CATALINA_BASE" value="c:\\Program Files\\Apache Group\\Tomcat 4.1"/>
    </exec>
</target>
So, to be able to re-use aaa_DeployToTomcat4, I do the following in WebApplication1:

  1. Add the following to build.xml:

    <import file="../ProjectAntTargets/project-specific-targets.xml"/>
  2. Change the first and add the second property below in the nbproject/project.properties file:
    • build.web.dir=c:/Program Files/Apache Group/Tomcat 4.1/webapps/${project.name}
    • project.name=WebApplication1

  3. Right-click the project node, choose Properties, click Run, and type the starting page in the Relative URL field. (This field sets the client.urlPart property in the nbproject/project.properties file.)
Finally, you must make sure that the properties set in nbproject/project.properties are available to aaa_DeployToTomcat4, so add this to the top of the aaa_DeployToTomcat4 target:

<import file="../WebApplication1/nbproject/project.properties"/>
And then you can create shortcuts and deploy to Tomcat 4 using the reusable aaa_DeployToTomcat4 target. (And when I delete WebApplication1, as I am bound to do sooner or later, I'll not destroy aaa_DeployToTomcat4, because it's in a separate build script.) There's probably better ways of doing this. For example, maybe the project.properties file should be shared as well, but I think it's all pretty cool, however you look at it.

About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2005 »
SunMonTueWedThuFriSat
     
1
2
8
9
10
14
16
18
22
23
29
       
Today