Wednesday, February 25, 2009

Getting JAX-WS to work with WebLogic 9.2

I spent several hours at work today troubleshooting problems related to getting JAX-WS (as included with Apache CXF) working in a Java web application running under BEA (Oracle) WebLogic 9.2.  This post contains a summary of the errors I encountered, and their resolutions -- hopefully this will save someone some of the troubleshooting time that I spent today.

Background

Some brief background: I was building some new SOAP web service integrations into one of our internal Java applications, which runs on WebLogic server.  This application was the client side of the integration.  I used Spring, Apache CXF, and JAX-WS to build the integrations.

I first coded the SOAP integrations into a simple stand-alone Java application, and that worked fine.  However, when I plugged my code and the CXF .jar files into the "real" application running on my local WebLogic server, I ran into a couple of errors.

Error #1: "java.lang.NoSuchMethodError: javax.jws.WebMethod.exclude"

Upon running my application under WebLogic 9.2, I got this error in the WebLogic server log file:

org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'internalBeanName': Instantiation of bean failed;
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public java.lang.Object org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create()]
threw exception; nested exception is java.lang.NoSuchMethodError: javax.jws.WebMethod.exclude()Z

This error turned out to be caused by the fact that in addition to the javax.jws.WebMethod class included in the geronimo-ws-metadata_2.0_spec-1.1.2.jar file included in the distribution of CXF that I downloaded, another (apparently older) implementation of that class is also included in the weblogic.jar file included with WebLogic 9.2.  WebLogic by default assigned priority to classes from its own weblogic.jar file over classes included with my application; as a result, WebLogic tried to use the older implementation of the javax.jws.WebMethod class, which does not include the exclude() method, and the NoSuchMethodError occurred when the other JAX-WS code tried to access that method.

To fix this, I modified my weblogic.xml and weblogic-application.xml files, to instruct WebLogic to give priority to the JAX-WS implementation in my own supplied .jar files rather than its own JAX-WS implementation. 

In my weblogic.xml, I added:

<container-descriptor>
  <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>

For more on this weblogic.xml change, see documentation on a similar issue affecting Apache Axis.

In my weblogic-application.xml, I added:

<prefer-application-packages>
    <package-name>org.apache.xerces.*</package-name>
    <package-name>javax.jws.*</package-name>
</prefer-application-packages>

For more on this weblogic-application.xml change, see the WebLogic configuration documentation in the CXF documentation.

Error #2: "Your JAXP provider [...] does not support XML Schema"

Having resolved the NoSuchMethodError, I re-deployed my application, and got this error upon running the app:

org.springframework.beans.factory.BeanDefinitionStoreException: Parser configuration exception parsing XML from class path resource [mySpringContext.xml]; nested exception is javax.xml.parsers.ParserConfigurationException: Unable to validate using XSD: Your JAXP provider [org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@nnnnnnn] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? Upgrade to Apache Xerces (or Java 1.5) for full XSD support.

The problem here was that there was an an old (2003) xerces.jar file present in my Java project, which contained an old JAXP provider class which did not support XSD. 

To fix this, I deleted the old xerces.jar file, and redeployed the project.  (I also needed to delete WebLogic's cache, located on my machine at \bea\user_projects\domains\mydomain\servers\myserver\tmp, to completely get rid of the old cached xerces.jar file.)

Wednesday, February 11, 2009

Still Key Jammin', 19 years later!

I was just re-reading a piece of code that I'd written earlier today which attempts to detect duplicate customer records in a particular database table, when I came across a misspelling in a comment: I'd misspelled the word "duplicate" as "dupliate."  I corrected the typo, and continued reading, when I came across another instance of the same misspelling: "dupliate" instead of "duplicate." 

Curious now, I did a search of the source file for other instances of the misspelled word "dupliate"; to my surprise, I found a LOT of instances of that misspelling (all in my own hand-entered comments, so not due to intellisense or copy-paste)!  At this point, I suspected that the problem was due to some factor beyond simple human error, so as an experiment, I tried just typing the word "duplicate" several times in a row (and paying attention to be sure that I actually was hitting the C key).  This was the output:

dupliate dupliate dupliate dupliate dupliate duplicate dupliate

The problem was reproducible almost every time.  I briefly experimented further:

  • The problem WAS reproducible in text editors other than my IDE (Eclipse). 
  • The problem was NOT reproducible when I typed slowly and deliberately, being sure to hit each individual key one at a time.
  • The problem was NOT reproducible using my machine's built-in keyboard (an IBM/Lenovo Thinkpad T60 laptop); only when using the external keyboard (a "standard" qwerty / U.S. layout black Dell-branded PS/2 keyboard, part number 04N454).

I discovered that the specific problem was that while the L and I keys on the keyboard were being pressed, presses of the C key would be dropped/ignored.  I found that every other letter key on the keyboard worked with L and I held down; just not C!

So what was happening here was that in typing "duplicate," I apparently was typing the C (with my left hand) before I'd let go of the L and I keys (with my right hand) -- or at least before the L and I keys had "popped back up" -- and consequently, the C key press was getting dropped.

Now that I'd realized what was going on, I remembered that this is a typical hardware limitation of keyboards: certain keys cannot be pressed in combination with one another.  I hadn't thought about this in years and years -- since back when I used to play 2-player games on the PC that would have both players using the keyboard on the same PC simultaneously.  The old (1990) PC game Star Control actually came with a utility called "Key Jamming" for working around this very issue: The utility would allow you to experimentally hold down various key combinations, and tell you which ones the PC could "see," to allow you to customize the game's keyboard controls on your machine's keyboard such that players in a two-player game wouldn't end up "locking out" one another.

It's unfortunate that the Dell 04N454 keyboard has this particular limitation.  I'm not sure what I can do to work around it, though, short of just needing to have extra awareness of my spelling (particularly in non-spell-checked environments such as IDEs) -- or else looking into using a different keyboard which isn't affected by this particular limitation!

Sunday, February 08, 2009

Wii Overheating and Powering Off due to Stuck Fan

The past few weeks, my family has been having a problem with our Nintendo Wii game system at home: After being on and used to play games for an hour or two, the Wii would just shut itself off without warning.  The outer case of the Wii would be hot to the touch after the shut-off.  The obvious diagnosis was that the Wii was overheating, and powering itself off as a safety measure to avoid damaging the processor or other internal components due to the very high temperature.  A Nintendo customer service article on the Wii provides support for this: "The system will shut down if it cannot vent properly to prevent overheating."

After the self-shutoff, the power light of the Wii on the front of its case would be off (not red or yellow, as is normally the case when the Wii is plugged in but powered off).  After the Wii had a few minutes to cool down while powered off, we could get it to power on again by removing and then re-plugging the power cord, but this was obviously only a temporary workaround, since it did nothing to address the root cause of the overheating.

The vents on the back and bottom of the Wii appeared to be clear -- not clogged with dust or otherwise blocked.  However, I couldn't feel any air movement at all when putting my fingers near the vent at the back of the Wii while it was running.  My suspicion was that Wii's internal fan might be jammed with built-up dust, or not running properly for some other reason.  I couldn't determine whether or not this was the case by trying to peer through the vents in the back of the Wii, though.

Reading further on the nintendo.com support site, Nintendo does offer an official repair service, but my Wii (according to the site, after entering my Wii's serial number) is out of warranty; Nintendo wanted US $75 to cover shipping and repair of the out-of-warranty Wii.  I wasn't terribly excited about the prospect of paying such a steep fee to have my not-yet-2-year-old Wii repaired.

I searched around some more, and came across a great article, including pictures, on how to disassemble a Wii, by Ken Hanscom.  Armed with this (thanks Ken!), and with the knowledge that my Wii was out of warranty anyway and therefore there was no warranty to be voided, I decided to set about disassembling my own Wii to be able to get at the fan, and try to diagnose and fix the problem myself.

Tri-wing screwI did need to pick up one additional tool before starting the disassembly -- a "tri-wing" screwdriver, which previously I'd never heard of before.  The Wii and some other consumer electronics devices use tri-wing screws (shown at right) apparently as an attempted security measure to prevent customers from removing the screws and taking apart the devices, as most people don't own one of these screwdrivers, and most hardware stores don't carry them.  However, I was able to pick up a tri-wing screwdriver easily on eBay (searching on tri wing wii) for a grand total of $1.88 including shipping -- almost certainly my most inexpensive online purchase ever that involved something being shipped to me!

Following Ken's instructions, I was able to get the Wii disassembled without too much trouble.  I did run into a couple of problems along the way, though.  First, my micro-size Philips-head screwdriver was having problems getting a grip on the very first set of screws, on the outer Gamecube controller panel of the Wii; however, I ended up being able to use the flathead end of my micro-screwdriver to get those out.

I also ran into a problem with the very last screw to be removed, one of the two tri-wing screws on the bottom of the Wii, in the front panel.  The screw was pretty well stuck in its socket, and I unfortunately managed to strip the screw head using the tri-wing screwdriver, such that I wasn't able to get a grip on the screw with any of my screwdrivers (or with my needle-nose pliers).  Finally, though, as I took a break to put my son Eli to bed, my wife Missy took a turn with the project, and discovered that the casing of the Wii would come apart without actually having to remove that particular screw.  So we were able to complete the disassembly without ever actually getting that screw out.

Wii_parts_bagAs I went along, I ended up putting the screws from each step of the process with their own small plastic bag, to avoid any possibility of getting them confused with one another when I went to reassemble the Wii later.  I also labeled each bag with instructions on where each screw in the bag came from.  This did turn out to make it easy to get the Wii back together at the end of the project.

Finally, the Wii was opened up!  A front/side view:

Wii_naked_front_side

A rear view:

 Wii_naked_rear

The Wii's internal fan is visible at the bottom of the latter image.  The fan actually turned out to be very clean -- no visible built-up dust or grime at all.  However, when I tried turning the fan blade with my finger, the fan was "stuck"; it wouldn't move at all.  When I applied a bit more pressure, though, I could feel the fan suddenly become unstuck, and from that point on, it turned very freely -- even just blowing on the fan would get it spinning easily.

I'm not sure how the fan had gotten stuck in the first place, but apparently, the stuck fan had been the problem!  I tested the Wii by putting the cover back on (although not putting all the screws back in just yet), powering it back up, and playing Rock Band 2 with Missy for about an hour; at the end of our session, the Wii outer cover was still cool to the touch.  (Previously, when the Wii was experiencing the overheating issue, playing for any length of time over a few minutes would cause the Wii's cover to become at least warm to the touch, if not hot.)  We were also to feel some slight air movement at the vent at the back of the Wii while it was on, and we could, listening closely, hear the fan spinning.

I'll certainly keep an eye on the Wii's behavior over the coming days and weeks, but for now, the problem appears to be solved -- and without needing to send the Wii off for repairs for several days/weeks, or pay $75 to Nintendo!  I even managed to learn a few things, and pick up a cool new tool (the tri-wing screwdriver), in the process.

If you have an out-of-warranty Wii that you suspect of having a fan problem similar to the one I've described in this post, I would suggest, as a first step before you consider disassembling it, that you power off the Wii, unplug it, and then use a very narrow screwdriver or similarly-shaped tool to reach through the vent at the back of the Wii and check, by gentle touch using your tool, whether the fan appears to be "stuck" as mine was; and if so, if you are able dislodge it by means of applying gentle pressure.  It would be an easy troubleshooting measure to try, before going to the time and effort of disassembling the Wii.

Tuesday, February 03, 2009

How to prevent a web site from stealing the focus in Firefox

At work, for a while now, I've had my Firefox 3 browser homepage set to a particular page in our internal Confluence wiki.  This page is specially designed to be a "start page," consisting solely of a series of links to commonly-used internal applications and documentation, plus a few search fields allowing common searches to be performed (of the wiki; of the employees database; of the Internet via Google).  I also have the New Tab Homepage Firefox add-on installed, so this homepage appears when I open a new tab in Firefox.

This setup works great, with one glaring exception: The page takes a couple of seconds to load, and Confluence automatically sets the focus to the first search field on the page when it completes loading.  The result of this is whenever I opened a new browser window or browser tab and started typing a URL in the address bar to manually navigate to a page (which I actually do fairly frequently), typically halfway through my typing in the address bar, the web page would steal the focus, and the second half of the URL I was typing would appear in the search field on the page instead of in the address bar.

This problem isn't necessarily limited to a Confluence page set as a browser homepage; it could potentially occur with any web page that is coded to set the focus to a particular UI element on the page, such as the Google homepage.  Here's what might happen if I opened up a new browser window with the homepage set to Google, and started trying to type "http://localhost/" in the address bar as the page loaded:

browserStealFocus

Note that half of the "http://localhost" text appears in the address bar, but (in this example) after the "a" was typed the script web page made a call to the Javascript focus() method to set the focus to the search field, and Firefox honored this; as a result, the remainder of the typing appears in the search field -- the Google page managed to steal the focus.

I went about searching for a solution to this problem, and ended up finding one in a post on Kam-Hung Soh's blog.  Kam-Hung's post has instructions on how to disable a particular Javascript method for a particular web site. 

I followed the instructions, and added the following to my Firefox user.js file:

user_pref("capability.policy.policynames", "noinputfocus");
user_pref("capability.policy.noinputfocus.sites", "www.google.com");
user_pref("capability.policy.noinputfocus.HTMLInputElement.focus", "noAccess");

(In my case, I used the URL of my team's internal Confluence wiki site instead of "www.google.com").

After doing this, I was all set!  I no longer had my focus stolen after opening a new browser window or a new tab. (Thanks, Kam-Hung!)

Obviously, these instructions are Firefox-specific, and therefore aren't helpful for addressing this issue in other browsers.  However, when I tried to reproduce the issue in Internet Explorer 7, I was unable to do so -- in cases where I had started typing in the address bar as IE7 loaded the page, the web page never gained the focus.  Perhaps IE has some intelligent logic where it will ignore focus() calls made by the web page in the case where the user has already started typing something in the address bar?  It would be really nice to see all browsers implement such a feature, to avoid the need for workarounds such as the one described in this post.

Update 2/4/2009: I took a look, and there is in fact a bug in the Firefox Bugzilla database for this issue. It was initially reported back in 2002, though, so I'm not super optimistic about the bug being fixed in the near future. :-)