Thursday, March 8, 2012

JBoss AS 7 - How to set the context root for an EJB3 WebService

Apologies to anyone who read one of my other blog posts and thought this one would be something interesting for anyone other than the very specific few who want this particular answer.  I tried to warn you with the title of the post.  For those of you who are reading because the JBoss Docs are, as ever, disorganized and littered with gaping holes, into which you are supposed to pour your guesses, past experience, head scratches, and frustrated, perplexed gazes, read on...

This is a simple answer that came from another week long session of searching, reading between the lines of the many attempts to document JBoss 7, and a little bit of guessing.  This particular topic applies to JBoss AS version 7 or 7.1.

Previous versions of JBoss used a file named jboss.xml to set these things.  JBoss AS 7.x uses a different file named jboss-webservices.xml instead.  And, the new file doesn't go in the same place as the old file.

If you have a contextual backdrop of general JBoss knowledge, the information you need is reasonably complete here:  https://community.jboss.org/wiki/JBossWS4MigrationGuide  Otherwise, you probably need some of that context too.

Context:
Building an EAR for deployment in JBoss 7, which contains an EJB3 jar file as a module, using maven to build the jar and the ear file, gives you, by default, a really UGLY context path for the EJB WebService endpoint that shows the entire name of the jar artifact.  For instance, if your EJB maven project had an artifactId of WeatherServices-FIVE-DAY-FORECAST-EJB, and its version was 1.0.0-SNAPSHOT, then the jar artifact name would probably be WeatherService-FIVE-DAY-FORECAST-EJB-1.0.0-SNAPSHOT.jar.  Thats ok since maven gives us all a healthy shove towards naming jar artifacts in a way that makes it VERY hard to screw up and use the wrong version of some library.

Then you might have Maven build an ear file, using the maven-ear-plugin to include the EJB jar file using an ejbModule directive as follows

<plugin>
  <artifactid>maven-ear-plugin</artifactid>
  <configuration>
    <version>6</version>
    <modules>
      <ejbmodule>
        <groupid>org.example.weather.services</groupid>
        <artifactid>WeatherServices-FIVE-DAY-FORECAST-EJB</artifactid>
      </ejbmodule>
    </modules>
  </configuration>
</plugin>

Then when you deploy that ear to JBoss AS 7, you get an endpoint address something like

http://yourserver:8080/WeatherService-FIVE-DAY-FORECAST-EJB-1.0.0-SNAPSHOT/WeatherService/WeatherService

Suppose what you wanted was more like this:

http://yourserver:8080/forecast5/WeatherService/WeatherService

After days of googling and guessing (hopefully fewer days if you find this first), you figure out that you need the file called jboss-webservices.xml in the EJB jar's META-INF directory, and it has to have contents like the following:

<?xml version="1.0" encoding="UTF-8"?>
<webservices version="1.0" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns="http://www.jboss.com/xml/ns/javaee" 
       xsi:schemalocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss_webservices_1_0.xsd">
    <context-root>forecast5</context-root>
</webservices>

The things that were not clear from the documentation, which took some trial and error, were:
  1. Does jboss-webservices.xml go in the EJB jar file's META-INF? (yes), or the ear file's META-INF? (no).
  2. Is there a way to specify the context root for an ejbModule in the maven plugin, like you can for a webModule? No. And if you've found a way, please post it in a comment.
  3. Is there an alternative to the @WebContext jboss specific annotation in the EJB @Stateless class for a JAX-WS service?  Apparently not.  The port-component tag in jboss-webservices.xml is supposedly intended only to configure JAX-RPC services.  See: https://community.jboss.org/thread/195876

Thursday, March 1, 2012

Samsung Galaxy S2 AWOL on Windows 7 x64

For weeks now, I've been transferring files to and from my Samsung Galaxy S II via Bluetooth.  Bluetooth is sometimes convenient, for a hands free speakerphone or headphones, or other things like that, but for file transfer, it just isn't capable of the necessary speed.  So, I finally got to a point where I needed to transfer several larger files to the phone, and Bluetooth wasn't up to the task.  But my phone wouldn't connect via USB, and nothing I tried would make it connect either.  Then after several hours of searching through forums and reading numerous guesses about why Windows 7 won't see the phone's USB devices or load the right drivers, and trying the many pedestrian, junior-wizard-wannabe, ineffective solutions, I finally, almost accidentally, tripped over the obscure bits of information to get it working.  Most of the stuff in the middle here is just editorial context so this article might match more of the keywords people might be using to search for this information, so if you just want the answer, skip ahead to the numbered, step-by-step stuff at the bottom.

The particular version of the SG2 is the SGH-T989 / T-Mobile version, but that probably doesn't matter.  I'd like to rant for a few paragraphs (ok, maybe a few _pages_) about the boneheadedness of each cell service provider having their own, slightly different, version of essentially the same Samsung phone, which makes it VERY annoying to choose accessories that will actually fit one or another version, but I'll leave that for another day.

I was a bit skeptical about some of the information I found at first.  Some of the instructions looked like something that would to appear in 2600 magazine (http://en.wikipedia.org/wiki/2600:_The_Hacker_Quarterly) describing how to take over operator control and phrack the local telco to get free long distance.  But, that was back in the day when that sort of thing would have been a superlative geeky achievement.  There's a bit below that starts with "Enter the following symbols and numbers:" followed by a super double secret special code that only Samsung/Android uber-hackers would have any way of knowing.  That had me wondering what post-land-line, 1-900 equivalent, $10 per minute nonsense I was about to be lured into calling.  Then it occurred to me that as long as I didn't type 911 or hit the connect button, it would probably be safe enough to proceed with caution.

The forum messages where I found part of the solution said that the troubles occur "when the phone is upgraded to Android 2.3.4 and above," but I would amend that to say that the troubles could occur if the Android version _is_ 2.3.4 or above, even if the phone came out of the box with that version already on it.

The problem is that Windows 7 does not recognize that the phones has been connected via USB.  And, as the forum messages stated (more or less), even if the correct device drivers are installed on the computer, Windows 7 can't figure out what the device is and completely fails to figure out that the USB connected device actually needs to use those drivers.

The symptoms that might help you decide whether this solution holds promise for you are:
  • The Windows Device Manager shows "unknown device"
  • The Windows Device Manager shows "Bluetooth Peripheral Device"
  • Device install dialog shows "No Driver Found" for a Bluetooth Peripheral Device
  • Device install dialog shows red X beside a few devices.
  • Using the USB Utilities / USB Mass Storage Device "Connect storage to PC" function does not work.
  • Using the "USB Debugging" development feature does not work.
  • (More symptoms added later if it happens to me again so I can see the messages, errors, device names, etc.)
The things you could have tried that didn't solve the problem might include:
  • Installing the Samsung USB device driver
  • Installing the Samsung KIES sync application
  • Enabling "USB debugging" on the phone settings under Applications - Development
  • Enabling "Allow mock locations" on the phone settings under Applications - Development
  • Attempting to use the "Connect storage to PC" feature on the phone settings under "Wireless and network" - "USB utilities".
  • Finding the device in Windows Device Manager and clicking the "Update driver" button on the Driver tab in the device's properties dialog.
So, here's the magic solution.  (It's weird.  It's aggravating that it's hidden.  There's only a 95% chance that it will work.  73% of all statistics are made up on the spot.)
  1. Open the phone dialer as if to make voice call.
  2. Enter the following symbols and numbers:   *#7284#
  3. Wonder with amazement how that would result in a settings dialog appearing on the screen.
  4. Find the USB section (there should only be 2 sections, UART, and USB).
  5. If the USB option is set to MODEM, tap PDA
  6. If the USB option is set to PDA already, tap MODEM, and then tap PDA
  7. Watch the screen on the Windows 7 PC to see if the Device Installed notifications show up.
  8. Open Windows (File) Explorer on the Windows 7 PC to see if the Removable Disk devices show up now.  Note, you still probably won't be able to access files on those devices, but if they show up, that's a good sign.  If you click one of the Removable Disk drives letters in Windows at this point, it will probably show a prompt to "Please insert a disk into Removable Disk (E:)" (or whatever drive letter it is mapped to.)
Now if you're running KIES to sync the phone data to the PC, you probably don't need to do anything else besides start the KIES application, but if you want to access files on those "Removable Device" drive letters that showed up, there's one more thing you have to do.
  1. Go into the settings and choose "Wireless and network", then choose "USB Utilities"
  2. Tap the "Connect storage to PC" button (for training purposes)
  3. Notice that for some aggravating but unknown reason, you get a message stating the obvious "Attention - USB is connected. Remove the cable"
  4. Tap OK and do as it says... unplug the USB cable.
  5. Now, tap the "Connect storage to PC" button again and it should show a message saying "USB utilities - Connect USB cable to use mass storage"
  6. Plug the cable back in and the android robot icon should show up with a message saying "USB connected"... but wait... there's more.
  7. Tap the "Connect USB storage" button
  8. Finally, the phone should display a message that says "USB storage in use" and the Removable Disk drives on the Windows 7 PC should now allow access to the files.  (Note: There are two removable drives if you have a micro SD card installed, but if there is no SD card in the phone, there may be only one Removable Disk showing in Windows).

I would put a link and reference to the original forum post where I found this information, but even that information had been echoed from somewhere else, so instead of tracking down the original sources of this magic helpful information, I'll just leave that for you to find in your favorite web search engine if you really feel like doing that.

Please leave comments if any of this is unclear or if you have additional tips to share (or even if this fixed it for you and you just want to say thanks).  I have comment moderation turned on, so don't worry if your comment doesn't show up immediately.  I'll get to it and publish it usually within a few days.