Friday September 30, 2005
Why Plug-in Module Development in NetBeans 5.0 Sucks..
...for technical writers. Normally, when you're writing help topics, you try to decide what the tasks are that the user will want to do. And then you create a help topic for each task. And then you write the steps for each help topic. You try and make things as simple as possible, with as few steps as possible—but enough steps to make the task taskworthy. Everything should always be clear, concise, and correct. However, plug-in module development in NetBeans 5.0 is so "good", that many of the most crucial tasks consist of only one step. This is really annoying, if you're a technical writer. (Also because you feel a little bit obsolete.) Writing tasks with one step is kind of weird (some writers cheat and break one step into two, which also looks weird).
For example, here are some topics I'd like to write for plug-in modules:
- Create an NBM File
- Install a Module
- Reload a Module
And here are some of my topics for applications built on top of the NetBeans Platform:
- Build a ZIP Distribution
- Build a JNLP Application
- Run a JNLP Application
But, firstly, here's all you need to do to create an NBM file (an NBM file is a binary of your plug-in, which can be installed via the Update Center):
And then stuff happens in the background and two seconds later you have an NBM file (which you can immediately install via the Update Center):
Secondly, here's what you do to run a JNLP application (read Deploying Software with JNLP and Java Web Start for details on JNLP):
And then lots of stuff happens in the background, and six seconds later your JNLP application is run:
So do you see the problem? One step! All of the tasks listed above consist of one tiny little step. So, if you see topics that take three steps to do what should really be done in one, providing silly instructions like this...
- Open the Projects window (Ctrl-Shift-1).
- Right-click the module project node.
- Choose Create NBM.
...instead of this...
- Open the Projects window (Ctrl-Shift-1), right-click the module project node, and choose Create NBM.
...then you'll know that I tried, I really tried...
Sep 30 2005, 12:49:14 AM PDT Permalink
The Sound of NetBeans IDE 5.0 Beta
"My Favorite Things in NetBeans IDE 5.0 Beta"
WebLogic, JBoss, enhanced Tomcat Server;
JSF, Struts; drag-'n-drop tags with fervor;
plug-in development fitted with wings
—these are a few of my favorite things.
Chorus: When the build breaks,
when the plans slip,
when I find a quirk,
I simply remember my favorite things
—and then I get back to work!
"The Platform's improved!" (Please note I am citing.)
SQL editor—syntax highlighting;
shortcuts in menus; refactorings
—these are a few of my favorite things.
Matisse GUI Builder! New docs—full of gumption!
A great Options window! Web service consumption!
A fantastic community—all queens and kings!
These are a few of my favorite things!
With thanks to Maria.
Sep 29 2005, 12:19:35 AM PDT Permalink
How Wizards Work (Part 2): Different Types
When I was about 12, I used to be a big fan of the 'Choose Your Own Adventure' books. They had titles like: "Prisoner of the Ant People" and "The Magic of the Unicorn". On page 1, the scene would be set—for example, you'd wake up smothered by vampires drinking your blood. What do you do? And then the book would helpfully give you some options: "Run around screaming? Turn to page 27." "Cut them off with the Sword of Destiny? Turn to page 8." "Curse them under your breath? Turn to page 92." And then you'd obediently turn to the appointed page and walk into a snake pit or find yourself parachuting behind enemy lines in wartime France or find (yet another) Sword of Destiny.
NetBeans IDE 5.0 allows you to do the very same thing. (No, not parachute behind enemy lines in wartime France.) But, it's almost just as exciting—'Write Your Own Wizard' means, essentially, 'Create Your Own Adventure'. You could do it the simple way—the user must work through a page, click Next, work through the next page, click Next, work through the next page, click Next, work through the final page, and then click Finish. But life often isn't that simple. Martin Krauskopf (the creater of the Wizard wizard in NetBeans IDE 5.0) sent me a few wizards that illustrate the point really well. Here's an example of a simple wizard (click to enlarge):
Here you can see that you can choose either 'Tea', 'Coffee', or 'Water'. But only if you choose 'Tea' or 'Coffee' does it make sense to go to the next page, which lets you say 'Yes' or 'No' to sugar. For this reason, the first page implements the WizardDescriptor.FinishablePanel interface. By implementing this interface, you allow the Finish button to be enabled if 'Water' is selected:
public boolean isFinishPanel() {
return getDrinkType() == MenuVisualPanel1.WATER;
}
This is the only method required by the WizardDescriptor.FinishablePanel interface (in addition to those required by its superinterface, WizardDescriptor.Panel). However, the isValid() method must also be set to true, which is set to true by default. So, WizardDescriptor.FinishablePanel enables you to end your adventure prematurely. There are many more pages that you could work through, potentially, but why should you? You chose water and it doesn't make sense to specify whether or not you want sugar.
However, a cool thing about NetBeans is that each step in the wizard consists of two components (kind of like how each web page in Wicket consists of two components): a Java class that implements WizardDescriptor.Panel (for example, WizardDescriptor.FinishablePanel, described above) and a Java class that implements JPanel. According to this document, "The WizardDescriptor.Panel subclass should reference the JPanel subclass, instantiate and return an instance of that class the first time its java.awt.Component getComponent() method is called. This is the safest, performant and also the preferred way to construct wizard steps." So, when you use the Wizard wizard, this method is automatically generated for you in the WizardDescriptor.Panel subclass (which, in this case, was called MenuWizardPanel1, which is a name that correlates with the name of the visual panel instantiated below, although the names don't have to be similar at all):
public Component getComponent() {
if (component == null) {
component = new MenuVisualPanel1();
}
return component;
}
Similarly, the getDrinkType() method that is called in the isFinishPanel() method interacts with the visual component:
private int getDrinkType() {
return ((MenuVisualPanel1) component).getDrinkType();
}
However, note that irrespective of your choice, you have the same number of pages. If there were a third page, you wouldn't be able to skip the second. (And even if you choose 'Water', the Next button is always enabled. Hmmm. Must be some way to disable the Next button.) Why can't you skip pages? What happened to 'Choose Your Own Adventure?' How adventurous does NetBeans let you be if you can't let the user skip around from page to page? Good questions. And the answer is... the WizardDescriptor.Iterator interface. Here, for example, is what you could implement; thanks again to Martin for this wizard (click to enlarge):
Here you can see that only if you choose 'Drink' will Next take you to the Drink page (and only if you choose Food will 'Next' bring you to the Food page). In terms of the Wizard wizard, and the NetBeans APIs, the above scenario is completely different to the previous one. In fact, when you use the Wizard wizard, the first panel forces you to specify which wizard you want (click to enlarge):
Above, if you choose 'Simple', you cannot let the user diverge from the given number of steps (i.e, although it is possible to let the user prematurely finish the wizard, using WizardDescriptor.FinishablePanel, you cannot let the user skip a page). If you choose 'Variable', you can let the user branch off as much as you allow. This means that in the second scenario there's a lot more work for you than in the first. In 'Number of Steps' above, you specify the number of steps—i.e., for each step you'll get two files, a Java class that implements WizardDescriptor.Panel and a Java class that implements JPanel. The interaction between these two was briefly outlined above (i.e., instantiation via the getComponent method and calling methods on the visual component from the WizardDescriptor.Panel class).
There's actually a lot more to say about wizards—here's just a few off the top of my head:
- The readSettings() and storeSettings() methods take care of the state.
- Iteration for 'Variable' wizards is via the generated WizardDescriptor.Iterator subclass; for 'Simple' wizards, you just need to invoke the wizard and the iteration is linear, so you don't need to provide an iterator.
- There's a lot going on with change listeners.
The above are some of the things I need to look into before writing a tutorial on all of this...
Update: There are more parts to this series... Part 1, Part 3, Part 4, and Part 5.
Sep 28 2005, 05:29:44 AM PDT Permalink
New: SQL Editor in NetBeans IDE 5.0
One area that's improved significantly in NetBeans IDE 5.0 is the SQL Editor. In fact, there never was an SQL Editor before. In NetBeans IDE 4.1 -- and the releases before that -- you had a very small space where you could type SQL commands for sending to the database (click to enlarge):
In the screenshot above, you really need to look for the space for typing SQL commands, it's very small. In NetBeans IDE 5.0, you have a proper editor to use (click to enlarge):
What makes it a "proper" editor? Well, syntax highlighting, for example. And when you right-click in the editor, you get a pop-up menu with some cut/copy/paste menu items. And, one really cool side effect of having an editor is that you can (in not more than a few minutes) extend it. For example, here's a new action that I added to the SQL Editor's pop-up menu:

Not bad, huh? Editors are really cool, because you can extend them. How? How can you extend them? How can a menu item such as the one above be added to an editor? Read the NetBeans Source Editor Extension Module Tutorial for details.
Sep 27 2005, 06:11:22 AM PDT Permalink
Playing Chess with NetBeans (Part 4)
I've been making progress on the chess game (click to enlarge):
The only remaining problem since the last instalment of this pseudo-series (click here for details) is the generation of the FEN string. A FEN string describes the position of all the pieces and non-pieces (i.e., empty squares) on the board. A FEN string looks like this:
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
The above line is the starting position -- the lower-case letters are for the 'black' pieces and the upper-case letters are for the 'white' pieces. So, the first 8 characters show that the back row (row 8) contains the rook, knight, bishop, queen, king, bishop, knight, rook. The next 8 characters show that all the black pawns are on the next row (row 7). Row 6, 5, 4, and 3 are all empty -- each empty square gets one point, so each of these rows have 8 points. Then, in row 2 all the white pawns (upper-case P) and all the white pieces (upper-case RNBQKBNR) are all present. Next, you can see a 'w', which means it's white's move (after that you see 'KQkq-0' which is about castling and pawn promotion, both of which I'm not even going to think about yet) and the '1' at the end means that we're in move 1.
The FEN string needs to be generated automatically whenenever I make a new move in the game, because the web service that I'm playing against only understands FEN strings. (Since the web service is stateless, it requires me to re-describe the board each time I communicate with the web service.) So, this means that if I send the above FEN string to the web service, the web service is able to process it and return its own move. Currently, I'm able to generate the above string at the start of the game, i.e., prior to any moves being made. Obviously that's not very useful, since whenever a move is made, the FEN string should be recreated. However, it's a start, and I'm quite proud of it. Here's the code that makes it all happen:
private void createFenButtonActionPerformed(java.awt.event.ActionEvent evt) {
StringBuilder sb = new StringBuilder(80);
int emptySqNo = 0;
for (int sqIndex = 0; sqIndex < 64; sqIndex++) {
JPanel square = (JPanel)chessBoard.getComponent(sqIndex);
JLabel squareLabel = (JLabel)square.getComponent(0);
String squareIcon = (String)squareLabel.getIcon().toString();
//System.out.println("Icon on square " + sqIndex + " is: " + squareIcon);
if (sqIndex % 8 == 0 && sqIndex > 0) {
if (emptySqNo != 0) {
sb.append(emptySqNo);
emptySqNo = 0;
}
sb.append('/');
}
if (squareIcon.startsWith("javax")) {
emptySqNo++;
}
else {
if (squareIcon == "BlackRook.gif" ) {
symbol = "r";
} else if (squareIcon == "BlackKnight.gif" ) {
symbol = "n";
} else if (squareIcon == "BlackBishop.gif" ) {
symbol = "b";
} else if (squareIcon == "BlackQueen.gif" ) {
symbol = "q";
} else if (squareIcon == "BlackKing.gif" ) {
symbol = "k";
} else if (squareIcon == "BlackPawn.gif" ) {
symbol = "p";
} else if (squareIcon == "WhiteRook.gif" ) {
symbol = "R";
} else if (squareIcon == "WhiteKnight.gif" ) {
symbol = "N";
} else if (squareIcon == "WhiteBishop.gif" ) {
symbol = "B";
} else if (squareIcon == "WhiteQueen.gif" ) {
symbol = "Q";
} else if (squareIcon == "WhiteKing.gif" ) {
symbol = "K";
} else if (squareIcon == "WhitePawn.gif" ) {
symbol = "P";
}
sb.append(symbol);
}
}
sb.append(" " + opponent_color + " ");
sb.append("KQkq - 0 ");
sb.append(completed_move_no);
String s = sb.toString();
mySouthField.setText(s);
System.out.println("FEN string: " + sb);
}
What's kind of cool is the StringBuilder. I didn't know about it until Valentin Iliescu, who created the chess web service for which I'm trying to create a client, told me about it. He also provided the basis of the code above. (The search depth, move number, and the opponent's color are set elsewhere in the code, when you click the buttons at the top of the application.) Now, when I click 'Create FEN' (which is only there for test purposes, because eventually this will all happen under the cover) in my application, I see the following in the Output window:
The next thing I need to work on is changing the square's icon when making a move. And also check (again) whether I understand the FEN string correctly -- because there's quite a few little weird things going on in there. I can see that this code is going to contain a lot of if statements...
Sep 26 2005, 06:01:46 AM PDT Permalink
How Wizards Work (Part 1): Introduction
Wizards can be used for three things:
- To create a project template. This type of wizard is made available by the New Project wizard after registration in the layer.xml file (e.g., Web Application wizard).
- To create a file template. This type of wizard is made available by the New File wizard after registration in the layer.xml file:
- the template can consist of a single file (e.g., New Servlet wizard)
- the template can consist of multiple files (e.g., New Web Service wizard)
- To define properties. This type of wizard is made available by an action registered in the layer.xml file (e.g., Add Server Instance wizard).
In NetBeans IDE 5.0, you can use wizards to generate code for creating wizards that generate code... Here's the Wizard wizard:
Resources:
- Howto Implement Wizards Steps
- Optimization of java.awt.Component's initialization
- All classes in Dialogs API
- Javadoc for Dialogs API
- Wizard GuideBook
- NetBeans Architecture Answers for Dialogs API module
Update: There are more parts to this series... Part 2, Part 3, Part 4, and Part 5.
Sep 25 2005, 05:18:28 AM PDT Permalink
Identity Crisis Tutorial for NetBeans IDE 5.0
identity crisis
n.
- A psychosocial state or condition of disorientation and role confusion occurring especially in adolescents as a result of conflicting internal and external experiences, pressures, and expectations and often producing acute anxiety.
- An analogous state of confusion occurring in a social structure, such as an institution or a corporation.
Time for an update to the dictionary definition—some files also suffer from the debilitating side-effects of this condition. Why? Because NetBeans IDE doesn't recognize them, doesn't treat them as equals, which results in 'acute anxiety'. Poor little files. But...
... you can make a difference! Read all about it in the new draft (and therefore incomplete) tutorial: NetBeans DataLoader Module Tutorial.
Sep 23 2005, 09:53:50 AM PDT Permalink
Tooltips Like Never Seen Before
In Drag-and-Drop JSP and HTML Code Snippets in NetBeans IDE, I showed the cool new panel that lets you drag-and-drop HTML and JSP snippets into the Source Editor. One thing I didn't mention is something else that's kind of cool about this panel -- the tooltips. For example, when your mouse hovers over the 'Link' button, the tooltip shows you the code that you'll get when you do your drag-and-drop thing:
Okay, so there's nothing too amazing about that. But how about this -- hover over the 'Table' button and check out this cool tooltip:
But this one really takes the cake -- hover over 'DB Report' if you want to see the largest tooltip known to mankind (or, at least, known to me):

Sep 22 2005, 09:25:08 AM PDT Permalink
Designing and Testing a Window Component
One recent cool thing about designing your own windows (either in order to extend the IDE or as part of your own application on top of the NetBeans Platform) is that you can use the GUI Builder to do so. And, once you realize that you can (a) create an NBM file whenever you want and (b) install that NBM file into the current IDE whenever you want, you've got a very powerful testing facility. For example, below I'm adding GUI components to the default (i.e., blank) window that the Window Component wizard creates for me. You can see that I've installed my half-finished product -- since I specified that I want the window to be docked in the Navigator, that's where it is. So, meanwhile, I continue extending my window component in the design view of the GUI Builder (using Matisse, also known as the 'Free Design' layout) and whenever I want to see the result I create an NBM file, install it via the Update Center, and immediately see the result (click to enlarge):
Of course, use the above technique at your own risk -- bear in mind that if your module is really screwy, you could completely destroy the current instance of the IDE, including the work you're currently engaged in. Therefore, it's probably better to choose 'Install/Reload in Target Platform' (instead of 'Create NBM'). But, then again, that would mean that a whole new instance of the IDE has to start up. Plus, it's just plain cool to see my half-finished product in action in the IDE while I'm simultaneously still working on it within the same IDE instance.
Sep 21 2005, 06:22:21 AM PDT Permalink
The Message Handler: A Web Service's Secret Weapon
One underhighlighted area in the NetBeans IDE 4.1 helpset was that of 'message handlers'. What's really cool about message handlers is that they allow you to inject lumps of 'ancillary' functionality into web services and their clients. For example, you don't really want a logger to be part of your main body of code do you? If, instead of implementing a logger within your main Java classes constituting the web service client implementation, you implement it in a message handler, you've not only 'modulerized' your functionality, but you've also got yourself a reusable piece of functionality. That same logger could be used by a variety of different clients (or web services). (By the way -- did you know that the New Message Handler wizard in NetBeans IDE 4.1 (and 5.0) contains default code that provides logger functionality out of the box? In other words, when you complete this wizard, you have a logger. It's as simple as that. Then, of course, you can extend the logger however you like.)
Similarly, what do you do when you're wondering about the performance of your web service? (Or, better still, someone else's web service prior to beginning to consume it? Best to find out sooner rather than later that the web service you're consuming is a lemon.) Sure, use some kind of profiler (and, of course, the IDE's built-in test client). But, alternatively, why not use a message handler? Set the time at which the client calls the web service and then set the time at which it receives a response. Subtract the one time from the other and there's an indication of the web service's performance. Since a message handler is basically a filter, with a bunch of methods that are called at certain points in the process, you've got a great little setup for auditing the web service's performance. The code for this? What's it look like? It's really not very hard -- and documented in the new 'Inserting Message Handlers' section (all new web service topics in 5.0 -- and changed topics -- in this area are highlighted below):
Why not take a look -- and give those wacky web services out there a quick performance audit!
Sep 20 2005, 09:55:43 AM PDT Permalink
NetBeans IDE 5.0: What's On The Menu?
Check out what I only just discovered... when you look at these menu bars, the first from 4.1 and the second from the upcoming 5.0, you see that there are two new menus:
So, there's two new menus, "Go To" and "Source". It's a small thing, I guess, but it improves usability a lot when many of the IDE's secret-ish keyboard shortcuts are suddenly exposed as menu items:
Many of the above menu items I'd only seen in pop-up menus (and in the Keyboard Shortuts card). Like, if you don't know about Ctrl-D and Ctrl-T, you'd really be doing yourself a big favor by trying them out.
Sep 19 2005, 09:57:36 AM PDT Permalink
NetBeans RCP Sample in NetBeans IDE 5.0 Dev Builds
In current NetBeans IDE 5.0 Dev builds, you'll find the FeedReader sample in the New Project wizard (click to enlarge):
It's very important to realize, though, that the FeedReader sample, the FeedReader Tutorial and, in fact, NetBeans IDE 5.0 itself, are all in a pre-Beta phase. Therefore, when using any of these, you will come across bugs of various kinds -- so don't be surprised when all kinds of weird things start happening. In particular, the code used in the FeedReader sample needs to be closely checked, so -- until that happens -- there's likely to be a lot of outright bugs as well as 'things that work but could be coded better'. Similarly, the tutorial suffers from this problem too.
If you decide that you don't like the FeedReader sample for some reason, you can treat it just as you would treat any other module you don't like... by uninstalling it from the cool new Module Manager (click to enlarge):
Sep 16 2005, 10:57:47 AM PDT Permalink
Deploying JAX-RPC Web Services to Tomcat
To deploy a web service in NetBeans IDE 5.0 to Tomcat:
- Copy all JAR files from $NB_HOME/ide6/ext/jaxrpc16 to:
- $NB_HOME\enterprise2\jakarta-tomcat-5.5.7\common\lib
- $NB_HOME\enterprise2\jakarta-tomcat-5.5.7\server\lib
- $NB_HOME\enterprise2\jakarta-tomcat-5.5.7\shared\lib
Of course, only one of the above is needed, but since I don't know for sure which one, I copied the JAR files to all the lib folders I could find in $NB_HOME\enterprise2\jakarta-tomcat-5.5.7.
Note: If you are going to deploy to the bundled Tomcat, see issue 59943 and take the specified steps.
- Create web application (Ctrl-Shift-N). In the Project Properties dialog box, set Tomcat as your target server and add JAX-RPC 1.6 to your compile-time libraries. (Not 100% sure whether the latter part is correct, since the -pre-init target below enables the web service to be compiled.)
- Add these targets to your build.xml:
<target name="-pre-init"> <property name="j2ee.platform.wscompile.classpath" value="${libs.jaxrpc16.classpath}"/> <property name="tomcat.home" value="full_path_to_$NB_HOME\enterprise2\jakarta-tomcat-5.5.7"/> </target>Make sure to set the value applicable to your environment for tomcat.home in the target above.
<target name="run-deploy" depends="init,compile,compile-jsps,-do-compile-single-jsp,dist"> <property name="raw.war.name" value="${dist.dir}/raw-${war.name}"/> <copy file="${dist.war}" tofile="${raw.war.name}"/> <delete file="${dist.war}"/> <taskdef name="wsdeploy" classname="com.sun.xml.rpc.tools.ant.Wsdeploy" classpath="${wscompile.classpath}"/> <wsdeploy inWarFile="${raw.war.name}" outWarFile="${dist.war}" fork="true" classpath="${wscompile.classpath}:${build.classes.dir.real}:${javac.classpath}" keep="true" verbose="true" source="1.1.2"/> <delete file="${raw.war.name}"/> <copy file="${dist.war}" todir="${tomcat.home}/webapps"/> </target><target name="run-display-browser" if="do.display.browser" depends="run-deploy"> <nbbrowse url="http://my-host:my-port-number/${ant.project.name}/${client.urlPart}"/> </target>Make sure to set the value applicable to your environment for my-host and my-port-number in the target above.
- Create an XML file in WEB-INF. Call it jaxrpc-ri.xml with this content:
<?xml version="1.0" encoding="UTF-8"?> <webServices xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/dd" version="1.0" targetNamespaceBase="http://java.sun.com/xml/ns/jax-rpc/wsi/wsdl" typeNamespaceBase="http://java.sun.com/xml/ns/jax-rpc/wsi/types" urlPatternBase="/webservice"> <endpoint name="MyTomcatWS" displayName="TomcatService" description="Tomcat Web Service endpoint" interface="mypackage.mysubpackage.myclassSEI" implementation="mypackage.mysubpackage.myclassImpl"/> <endpointMapping endpointName="MyTomcatWS" urlPattern="/MyTomcatWS"/> </webServices>Make sure to set the value applicable to your environment for interface and implementation in the target above.
Take the url-pattern from the file above (here it is MyTomcatWS) and put it in the project's Relative URL edit box (in the Run Panel, in the Project Properties dialog box).
- Use Web Service wizard to create the web service files and then develop them further. I found later that I had to delete the existing servlet mappings that the IDE created in the web.xml for the web service. If I didn't do this, there was some kind of conflict with Tomcat and deployment didn't work because Tomcat didn't recognize the web service as a servlet.
- Build the web service.
- Start the server. (The server will not start automatically. In the Runtime window, start the server manually.)
- Run the project. I found that it didn't work, then I stopped the bundled server, restarted it, checked the Output window to see whether Tomcat correctly deployed the application (and then I discovered what I described above in step 5), right-clicked the application's node in the Runtime window (within 'Web Applications' under Tomcat's server node) to open it in a browser, and then I manually typed in the url-pattern specified in the jaxrpc-ri.xml file. Then, the world made sense again and I saw the following (click to enlarge both screenshots):
The process above may seem complicated, but many of its steps are due to my own ignorance -- there's a lot of overkill in these steps and as soon as I find out which parts are unnecessary, I'll blog about it and prune where necessary. Thanks to Lukas -- he's the first person (maybe in the whole world) to have developed and deployed a JAX-RPC web service from NetBeans to Tomcat. It's really very cool that this is at all possible, since Tomcat isn't a J2EE 1.4 server (i.e., it's not an application server, but a web server).
Sep 15 2005, 10:45:21 AM PDT Permalink
FeedReader in Stereo
The NetBeans FeedReader Tutorial is now available in stereo -- i.e., as an HTML file and as a PDF file. The coolest thing about this is that they're generated from the same source -- the first time that we've done this for any NetBeans doc. One other doc where we did do this was the massive J2EE 1.4 Tutorial for NetBeans IDE, but there we used WebWorks, for which we don't have a license anymore. For FeedReader, all that was used was FrameMaker, together with CSS for styling the HTML file. This has proved, so far (knock on wood), to be an effective and cost-efficient solution (i.e., no expensive WebWorks license needed). There are still quite a few issues to fix, notably the following:
- Need to bundle the CSS with the HTML.
- Junk in HTML thanks to FrameMaker.
- Need to switch the code font back to courier (plus tab problem).
- Need to fix/add/check:
- screenshots (maybe add them during post-processing)
- code (in FrameMaker)
- Need to check result in different browsers.
- Strangeness in the username/password on HTML page because of CSS.
Aside from the above formatting/editorial issues, the main area I need to work on in the tutorial is to work on the explanatory parts. One or two people have indicated that more explanations of why things happen needs to be given. That's something I'll be working on in the coming days. Also, a lot more screenshots need to be added, because currently there's a bit too much text.
In the meantime, if anyone has a few minutes to spare, it would be good if you could check out the tutorial and pass on any issues you find.
Sep 14 2005, 10:54:37 AM PDT Permalink
Migrating a Web Service Client to JBoss or Tomcat
Let's say you've created a web service client and deployed it to the Sun Java System Application Server. But now you realize that you can also deploy it to JBoss and Tomcat. What do you do? Simply change the target server in the Project Properties dialog box? Not good enough -- the client type you used when creating the web service client probably resulted in J2EE container-generated stubs. Neither JBoss (see http://jira.jboss.com/jira/browse/JBWS-381) nor Tomcat support the creation of these stubs -- so you need to make sure that the stubs are created by the IDE. In addition, you should regenerate the calls to the web service, because these are generated differently, depending on the client type you're using. But it's less complex than you might think. It takes four steps:
- In project.xml, change jsr-109_client to jaxrpc_static_client.
- Close and reopen the project. This regenerates build-impl.xml, using the changed project.xml.
- Clean and build the project. During the build, the changed build-impl.xml causes the build to create stubs.
- Delete the operation(s) that the IDE created for you and recreate it/them (Web Service Client Resources > Call Web Service Operation).
Now you've re-implemented the web service client so that the stubs are created by the IDE. Go see for yourself -- this is what the client's package looks like for J2EE Container-generated client types:

And this is the same package after I took the steps above:

Do you see that there are a lot more files in the second picture than the first? That's because in the second scenario, the IDE does for you what the server does for you in the first scenario. And, unfortunately, right now, the only server -- as far as I know, anyway -- that creates stubs correctly, according to the JSR-109 specification, is the Sun Java System Application Server. For JBoss, see http://jira.jboss.com/jira/browse/JBWS-381. (Note that I haven't tried WebLogic and WebSphere yet though.)
Sep 13 2005, 12:14:20 AM PDT Permalink













