Friday, 17 December 2010

JBoss stops with "Listening for transport dt_socket at address: 8787" message - change your debug startup settings

Hopefully someone out there finds this helpful.
I was trying to start Jboss in debug mode, so I went into
{JBOSS]/bin/run.bat and uncommented this:
rem JPDA options. Uncomment and modify as appropriate to enable remote
debugging.
set JAVA_OPTS=%JAVA_OPTS% -Xdebug
-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y

I then started up JBoss manually and on the screen it seemed to hang
at this message:
Listening for transport dt_socket at address: 8787

I had a look at the debug settings that IntelliJ recommends to use in
"Run -> Edit Configurations" and noticed that it was slightly
different:
-Xdebug -Xrunjdwp:transport=dt_socket,address=3599,suspend=n,server=y
notice the difference, aside from the port?? "suspend" has a value of
"n" instead of "y".
Turns out that "suspend=y" means it will not run until a debugger
attaches itself to the process. In most cases, you will probably want
to use "suspend=n" instead. I think "suspend=y" is mainly useful if
you're trying to track down things that occur on startup of the
webapp. If the part you're interested in will only happen after a user
action, it's best to use "suspend=n".

Useful reference:
http://download.oracle.com/javase/1.5.0/docs/guide/jpda/conninv.html

Thursday, 16 December 2010

Maven: "mvn archetype:generate" gives you 358 archetypes to choose from - too much of a good thing??

Just typed

maven archetype:generate

and I get a long long long list that goes up to...


349: remote -> nexus-plugin-archetype (-)
350: remote -> spring-osgi-bundle-archetype (Spring OSGi Maven2 Archetype)
351: remote -> spring-ws-archetype (Spring Web Services Maven2 Archetype.)
352: remote -> trails-archetype (-)
353: remote -> trails-secure-archetype (-)
354: remote -> tynamo-archetype (-)
355: remote -> wicket-scala-archetype (Basic setup for a project that
combines Scala and Wicket,
depending on the Wicket-Scala project. Includes an example Specs
test.)
356: remote -> wikbook.archetype (-)
357: remote -> circumflex-archetype (-)
358: remote -> javg-minimal-archetype (-)
Choose a number: 97:


358 archetypes??? At least it means a lot of projects have adopted
maven. But how usable is this?

Shouldn't we have something like a menu instead?

Thursday, 21 October 2010

GTKPod troubles in Fedora 11

NOTE: this happened a while ago, but I never solved this problem. I
ended up using another program, I think.

=======================

Just when I thought Fedora was good enough for normal use, (Fedora 11)
here comes a use case to stop me in my tracks.

Plugged in the iPod. Got mounted as a HD.

Ran GTKPod. No iPod recognised. Hmm... how to make it recognise the
iPod. See Help..

"...if the iPod cannot be mounted then gtkpod is NOT going to do it
for you! Thus, before firing up gtkpod make sure you can see the
filesystem of your iPod at its desginated mount point, eg. /mnt/ipod."

Ruh roh. Warning Warning.

"The result of this is that the ipod will be located on a device node
and this can be mounted manually using the command (performed as
root):

mount /dev/sdc2 /mnt/ipod"

Tried running it:

sudo mount /dev/sdc2 /mnt/ipod
mount: mount point /mnt/ipod does not exist

FEK.

FARK.

FUUUUUCK.

What the hell do I do now?

Google it, google it.

Create the mount manually using:

sudo mkdir /mnt/ipod

Okay! Seems to have mounted it.

ls -l /mnt/ipod/
total 2295312
(SNIP)

Back to GTKPod. Seems to have found my model #
xA003 - 60Gb, Video, 1st Gen

Ruh roh.

"Warning: Extended info will not be used"

Seems to be doing something. Hashing all my tracks. WTF? Do you need
to do this now?? I just want you to list them all.

Hmm.. "Duplicate detection. The following 3 duplicate tracks have been
removed."

What? "'Malcolm Gladwell Outliers 02': identical to 'Malcom Gladwell
Outliers 01'"

Okay, seems to have finished.

Now I want to get all the tracks by "2 Many DJs" onto my computer.
Should be easy right? In Sharepod, I just type in the search term, it
finds them, I select all of them then export.

But here, it has 3 panes, 2 of them for sorting and sub-sorting. I
select Artist "2 Many DJs", then "All" in 2nd tab. Then I get a dialog
box:

"Export selected entry of which sort tab"

And a select box has "1 and 2". Is it so hard to recognise which tabs
are selected and present the names in the select box instead of just 1
and 2?

Click OK.

"Filename format" field is just waay too confusing. A bit of polish
and simpler tooltips here would be good. I wonder if this thing will
work.

Click OK.

WTF is going on?? "Overwriting external media" - how come the
filenames are all ending in "..mp3"?? What the hell??

Fucking bullshit, now its hanging. No display update. No nothing. I
don't know WTF is going on!

SHIT. Linux FAIL yet again. Okay, Linux APP FAIL, to be accurate.

SHIT SHIT SHIT.

I hope killing the GTKPod process doesnt fuck up my iPod.

Okay, tried again. It didn't like having %o as the first format when
it said it didn't have Extended info

%a/%A/%T - %a - %t.m4a;%a/%A/%T - %a - %t.mp3;%a/%A/%T - %t.wav

works now.

Or so i thought.

Still nothing on the HD!

SHIT.

Monday, 9 August 2010

Unable to run Vignette Portal on JDK6 - error: " java.lang.NoSuchMethodError: javax.xml.bind.annotation.XmlAccessorType.value()Ljavax/xml/bind/annotation/AccessType;"

PROBLEM:

I was running Vignette Portal Application Server on tomcat 6, using
JDK5u21, and decided to start using JDK6u20. The Portal wouldn't start
and was getting this error:


Jul 14, 2010 10:57:01 AM org.apache.catalina.core.ApplicationContext log
SEVERE: com.vignette.portal.website.internal.StartupProtectionFilter:
system startup failure detected, unable to process request.
javax.naming.NamingException: Could not initialize instance of
com.vignette.portal.portlet.management.internal.PortletManagementSystem
as an error occured during invocation. [Root exception is java.
lang.NoSuchMethodError:
javax.xml.bind.annotation.XmlAccessorType.value()Ljavax/xml/bind/annotation/AccessType;]
at com.vignette.portal.naming.internal.portal.LocalLookup.create(LocalLookup.java:130)
at com.vignette.portal.naming.internal.portal.SingletonLocalLookup.<init>(SingletonLocalLookup.java:31)
at com.vignette.portal.naming.internal.portal.ServiceLifecycleManager.loadService(ServiceLifecycleManager.java:220)
at com.vignette.portal.naming.internal.portal.ServiceLifecycleManager.initializeServiceSet(ServiceLifecycleManager.java:168)
at com.vignette.portal.naming.internal.portal.ServiceLifecycleManager.lookup(ServiceLifecycleManager.java:142)
at com.vignette.portal.naming.internal.portal.PortalInitialContextSPIImpl.lookup(PortalInitialContextSPIImpl.java:44)
at com.vignette.portal.naming.PortalInitialContext.lookup(PortalInitialContext.java:86)
at com.epicentric.system.SystemManager$StartupThread.run(SystemManager.java:240)
Caused by: java.lang.NoSuchMethodError:
javax.xml.bind.annotation.XmlAccessorType.value()Ljavax/xml/bind/annotation/AccessType;
at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.getAccessType(ClassInfoImpl.java:339)
at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.getProperties(ClassInfoImpl.java:228)
at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.getProperties(RuntimeClassInfoImpl.java:87)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:127)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:49)
at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:41)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:189)
at com.sun.xml.bind.v2.model.impl.RegistryInfoImpl.<init>(RegistryInfoImpl.java:51)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.addRegistry(ModelBuilder.java:232)
at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:201)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:327)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:198)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.PortletApplicationFactory.buildPortletApplication(PortletApplicationFactory.java:153)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.PortletApplicationManager.addApplication(PortletApplicationManager.java:154)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.PortletApplicationManager.access$000(PortletApplicationManager.java:46)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.PortletApplicationManager$PortalAgentImpl.portletApplicationStarted(PortletApplicationManager.java:315)
at com.vignette.portal.portlet.jsrcontainer.internal.registry.PortletApplicationRegistry.registerPortal(PortletApplicationRegistry.java:118)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.PortletApplicationManager.init(PortletApplicationManager.java:77)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.PortletContainerImpl.init(PortletContainerImpl.java:44)
at com.vignette.portal.portlet.management.internal.implementation.provider.jsr.deployment.JsrPortletApplicationDeployer.<init>(JsrPortletApplicationDeployer.java:37)
at com.vignette.portal.portlet.management.internal.implementation.provider.jsr.deployment.JsrPortletApplicationDeployer.getInstance(JsrPortletApplicationDeployer.java:31)
at com.vignette.portal.portlet.management.internal.implementation.provider.jsr.JsrPortletApplicationManagerSpiImpl.initialize(JsrPortletApplicationManagerSpiImpl.java:88)
at com.vignette.portal.portlet.management.internal.PortletManagementSystem.init(PortletManagementSystem.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)


Googling around, I found this:

http://forums.sun.com/thread.jspa?threadID=5320481

"The actual problem is that jaxb classes like AccessType etc were
renamed to XmlAccessType in the latest jaxb-release. SunOne happens to
use these classes and consequently fails because those classes will
not be available. For the issue to be resolved, place old jaxb related
jars in SunInstallDir\AppServer\lib\endorsed and restart."

"I was facing similar problems with Tomcat.....when I was trying to
install VAP 7.4 on tomcat. What I have done to solve the problem is
copied jaxb-api.jar from
Tomcat-install-directory/webapps/portal/WEB-INF/lib to
Tomcat/common/endorsed.........restart and you are done."


Aargh. Too difficult. Back to JDK 5. :(

Tuesday, 13 July 2010

Rejuvenating rechargable batteries using MH-C204W charger

I bought a Maha MH-C204W charger and one of its big selling points for me is the ability to rejuvenate rechargable batteries that haven't been used in a while. A common problem with rechargeable batteries is that they don't seem to hold enough of a charge if they don't get used frequently. If you Google on "Maha MH-C204W", you'll see it has quite a good reputation with getting these batteries to be quite useable again.

However, when I first started using the charger I was getting behaviour that was not really as described in the 1-page 'manual' for the unit. I put in these 6-yr old Sanyo 2300 Ni-MH batteries to see if they could be made usable again. What follows are my emails to Maha, and the quite helpful responses I got. Hopefully this will be of use to someone experiencing the same issues.

I've reversed the contents of the email thread, so we can start at the beginnning. =)

=========================================

> -----Original Message-----
> Sent 7/5/2010 5:30:45 AM
> To: xxxxxxxxxxxxx@mahaenergy.com
> Subject: Maha/PowerEx Tech Support Request
>
> I have a MH-C204W charger, and just inserted 4 AA batteries to recharge.
> On the lower end there are 2 lights, and after charging for 2 hours, only
> the right one is green. The indicator on the left is not lit at all. The
> manual states "Note the two indicators may not turn green at the same time
> due to minor difference in battery status in each bank." What is the
> expected behaviour of the unit? Is each light supposed to be lit as you
> put the batteries into each half of the unit? (red at first, then green
> after charging)
>
>

=========================================

On Tue, Jul 6, 2010 at 3:50 AM, XXXXXXXXXX (MAHA ENERGY COI)
wrote:
> Hi XXXXXXXXXX,
>
>
> Thank you for contacting Maha. Here is a brief explanation to what each of
> the four LED lights mean:
>
> 1.Solid red (Charging)
> 2.Green (Charging complete)
> 3.Flashing red (Battery fault)
> 4.No light (Battery or charger fault)
>
> To determine whether the charger or the batteries are defective, please
> insert a pair of known "good" battery inside the slot in question. The LED
> should light up as solid red if the slot is working properly. If it gives
> you no signal/light, please provide me with your shipping address so I can
> have this defective unit replaced for you. Thank you and I look forward to
> hearing from you.
>
>
> Regards,
>
>
> xxxxxxxxxx

=========================================

-----Original Message-----

Sent: Friday, July 09, 2010 3:39 AM
To: xxxxxxxxx(MAHA ENERGY COI)
Subject: Re: Maha/PowerEx Tech Support Request

Hi XXXX,

It looks like some of my old batteries are at fault. I've inserted 2
sets of recent NiMh batteries and they are charging as expected with
the lights first showing as red for both pairs, and then green.

However, I'm trying to rejuvenate them so following the instructions,
I've charged them til both lights were green, then took them out to
cool down, then put them back and pressed the button between the
lights.

The instructions say the lights should then flash yellow. Now in some
cases what I'm seeing is that only one of the lights will flash yellow
and the other one remains green. What does this mean?

thanks,

xxxxxxxxxxx

=========================================

From MAHA:

Thank you for the follow-up. To condition both set of batteries, first place two batteries in the middle while leaving the two outer slots empty. After both of the batteries has been firmly secured, place the other two batteries in the two outer slots. Press and hold the conditioning button until you see both LED lights flashes yellow.


Regards,

xxxxxxxxxxx

=========================================

Monday, 12 July 2010

Fun with portlets - Vignette Error: "The provided content type, application/octet-stream, is not a valid response content type." (FIXED)

PROBLEM:

I had a portlet (written using Spring MVC) where I had to download a
CSV file, so in the code, I was making this call

response.setContentType("application/vnd.ms-excel");

But I kept getting the error below from Vignette.

===============================

General Error

The provided content type, application/octet-stream, is not a valid
response content type. Please check the valid response content types
by invoking PortletRequest.getResponseContentTypes().

Please contact your System Administrator for assistance.

class java.lang.IllegalArgumentException

================================

I tried using "text/csv" and "application/octet-stream" and same response.

SOLUTION:

This was caused by a missing config in portlet.xml

The portlet I was working on had this config:

<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>help</portlet-mode>
</supports>

and to fix the above error, I had to add this:

<supports>
<mime-type>application/vnd.ms-excel</mime-type>
<portlet-mode>view</portlet-mode>
</supports>

Friday, 18 June 2010

"java.lang.IllegalArgumentException: unknown format type at" when using 'format' in displaytag ()

I spent about an hour stuck on this problem, so hopefully this it
helps someone avoid that. =)

We've started using the displaytag library on our JSP pages, and I was
moving a table to use this, and it makes the page much more concise
and readable, but I was getting an error when I started using the
format attribute in <display:column>

MY ORIGINAL CODE WAS:

<display:column property="expiryDate" title="Expiry Date"
format="{0,expiryDate,dd/MM/yyyy}" group="2" sortable="true"
headerClass="sortable" />
<display:column property="endDate" title="End Date"
format="{0,endDate,dd/MM/yyyy}" group="3" sortable="true"
headerClass="sortable" />

GETTING ERROR:

Caused by: java.lang.IllegalArgumentException: unknown format type at
at java.text.MessageFormat.makeFormat(MessageFormat.java:1433)
at java.text.MessageFormat.applyPattern(MessageFormat.java:450)
at java.text.MessageFormat.<init>(MessageFormat.java:368)
at org.displaytag.decorator.MessageFormatColumnDecorator.<init>(MessageFormatColumnDecorator.java:52)
at org.displaytag.tags.ColumnTag.addHeaderToTable(ColumnTag.java:722)
at org.displaytag.tags.ColumnTag.doEndTag(ColumnTag.java:622)

At first I thought it was something related to the Locale that I had,
that maybe the JDK was defaulting to US Locale and maybe I should be
setting it to Australia. But I realised this wasn't the case because
the example war file with example-format.jsp had exactly this date
format and it didn't set the locale at all and was displaying fine on
my Tomcat instance.

Started playing around with the date itself then changed it to "date"
instead of the name of the property and it worked!!

SHOULD BE:

<display:column property="expiryDate" title="Expiry Date"
format="{0,date,dd/MM/yyyy}" group="2" sortable="true"
headerClass="sortable" />
<display:column property="endDate" title="End Date"
format="{0,date,dd/MM/yyyy}" group="3" sortable="true"
headerClass="sortable" />

THE LESSON:

When using "format" atribute in <display:column> of displaytag,
remember: "date" should *always* be used, since in the format
attribute it is a hardcoded value, not something to match to the
property name.

NOTE: Googling the above error message reveals it's actually a JDK
bug, as the error message should be reporting the POSITION of the
unknown format type, but at the moment MessageFormat class just has
this:

default:
maxOffset = oldMaxOffset;
throw new IllegalArgumentException("unknown format type at ");

See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6481179

Saturday, 8 May 2010

Spring error message - "can't parse argument number"

PROBLEM:
The story:
I want to display an error message that contains two dates which are derived from the exception returned by a remote web service that I'm calling from the webapp.

I'm almost there, since this error seems to relate to the display of the message, and the log also shows lines where it is going wrong in the JSP (the one with "form:errors")

2010-05-08 15:28:21,237 DEBUG
[org.springframework.context.support.ResourceBundleMessageSource] -
<Creating MessageFormat for pattern [New bulletin cannot be created
until conflicting bulletins from {} to {} are recalled.] and locale 'en'>
2010-05-08 15:28:21,362 ERROR
[org.springframework.web.servlet.tags.form.ErrorsTag] - <can't parse
argument number >
java.lang.IllegalArgumentException: can't parse argument number
       at java.text.MessageFormat.makeFormat(MessageFormat.java:1330)
       at java.text.MessageFormat.applyPattern(MessageFormat.java:450)
       at java.text.MessageFormat.<init>(MessageFormat.java:368)
       at org.springframework.context.support.MessageSourceSupport.createMessageFormat(MessageSourceSupport.java:118)
       at org.springframework.context.support.ResourceBundleMessageSource.getMessageFormat(ResourceBundleMessageSource.java:277)
       at org.springframework.context.support.ResourceBundleMessageSource.resolveCode(ResourceBundleMessageSource.java:184)
       at org.springframework.context.support.AbstractMessageSource.getMessageInternal(AbstractMessageSource.java:205)

SOLUTION:
The error is occurring because the error message I'm using from messages.properties is:
admin.bulletin.previousBulletin.notRecalled = New bulletin cannot be created until conflicting bulletins from {} to {} are recalled.

when it should be:
admin.bulletin.previousBulletin.notRecalled = New bulletin cannot be created until conflicting bulletins from {0} to {1} are recalled.

Error in webapp - javax/xml/soap/Detail violates loader constraints

added this to my pom.xml

<dependency>
<groupId>javax.xml.soap</groupId>
<artifactId>saaj-api</artifactId>
<version>1.3</version>
</dependency>

because i could not get the SOAPFaultException.Detail value

and got this when exception was being handled

2010-05-08 16:22:41,039 ERROR
[org.springframework.web.portlet.DispatcherPortlet] - <Could not
complete request>
javax.portlet.PortletException: Error occured during request
processing: Class javax/xml/soap/Detail violates loader constraints
at org.springframework.web.portlet.DispatcherPortlet.doActionService(DispatcherPortlet.java:715)
at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:480)
at org.springframework.web.portlet.FrameworkPortlet.processAction(FrameworkPortlet.java:462)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.FilterChainImpl.doFilter(FilterChainImpl.java:204)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.management.FilterManagerImpl.processFilter(FilterManagerImpl.java:67)
at com.vignette.portal.portlet.jsrcontainer.internal.standardcontainer.invocation.ProcessActionCommand.execute(ProcessActionCommand.java:62)
at com.vignette.portal.portlet.jsrcontainer.PortletCommandServlet.service(PortletCommandServlet.java:170)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)


because I should have set dependency scope to "provided"

<dependency>
<groupId>javax.xml.soap</groupId>
<artifactId>saaj-api</artifactId>
<version>1.3</version>
<scope>provided</scope>
</dependency>

Friday, 7 May 2010

Exotic error message of the week (Spring transactions) - "Application exception overridden by commit exception"

The @Transactional annotation in Spring makes it easy to make things
uh, transactional, right? So why did I get this stackTrace when I
threw an expected exception?

The web service I was testing returned this response:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<env:Fault xmlns:fault="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>fault:CO10001</faultcode>
<faultstring>An unknown error occurred</faultstring>
<faultactor>AdminService</faultactor>
<detail>
<java:string xmlns:java="java.io">Transaction rolled back
because it has been marked as rollback-only</java:string>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>


And the log file contained this:


ERROR [Fri May 7 18:29:46 EST 2010:] [[ACTIVE] ExecuteThread: '0' for
queue: 'weblogic.kernel.Default (self-tuning)'] [string] [367]
org.springframework.transaction.interceptor.TransactionInterceptor :
Application exception overridden by commit exception
mycompany.exception.Exception: Bulletin cannot be created because
of active bulletins that were created between 28/04/2010 and
06/05/2010
at mycompany.domain.service.spring.SpringAdminDomainService.checkForExistingBulletins(SpringAdminDomainService.java:441)
at mycompany.domain.service.spring.SpringAdminDomainService.createBulletin(SpringAdminDomainService.java:384)
at mycompany.domain.service.spring.SpringAdminDomainService.manageBulletin(SpringAdminDomainService.java:87)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy391.manageBulletin(Unknown Source)
at mycompany.application.facade.spring.SpringAdminFacade.manageBulletin(SpringAdminFacade.java:183)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy392.manageBulletin(Unknown Source)
at mycompany.package.service.ws.jws.JwsAdminService.manageBulletin(JwsAdminService.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at weblogic.wsee.component.pojo.JavaClassComponent.invoke(JavaClassComponent.java:99)
at weblogic.wsee.ws.dispatch.server.ComponentHandler.handleRequest(ComponentHandler.java:64)
at weblogic.wsee.handler.HandlerIterator.handleRequest(HandlerIterator.java:137)
at weblogic.wsee.ws.dispatch.server.ServerDispatcher.dispatch(ServerDispatcher.java:109)
at weblogic.wsee.ws.WsSkel.invoke(WsSkel.java:80)
at weblogic.wsee.server.servlet.SoapProcessor.handlePost(SoapProcessor.java:66)
at weblogic.wsee.server.servlet.SoapProcessor.process(SoapProcessor.java:44)
at weblogic.wsee.server.servlet.BaseWSServlet$AuthorizedInvoke.run(BaseWSServlet.java:257)
at weblogic.wsee.server.servlet.BaseWSServlet.service(BaseWSServlet.java:156)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:226)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:124)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at com.jamonapi.JAMonFilter.doFilter(JAMonFilter.java:57)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3393)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2140)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2046)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1366)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:200)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:172)
DEBUG [Fri May 7 18:29:46 EST 2010:] [[ACTIVE] ExecuteThread: '0' for
queue: 'weblogic.kernel.Default (self-tuning)'] [string] [146]
mycompany.package.service.ws.jws.JwsAdminService : Raising
SOAPFaultException:
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}CO10001
faultString: An unknown error occurred
faultActor: AdminService
exception: org.springframework.transaction.UnexpectedRollbackException:
Transaction rolled back because it has been marked as rollback-only
ERROR [Fri May 7 18:29:46 EST 2010:] [[ACTIVE] ExecuteThread: '0' for
queue: 'weblogic.kernel.Default (self-tuning)'] [string] [152]
mycompany.package.service.ws.jws.JwsAdminService : unexpected
exception
org.springframework.transaction.UnexpectedRollbackException:
Transaction rolled back because it has been marked as rollback-only
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:695)


Googling on "Application exception overridden by commit exception"
told us that it happens when an exception is thrown but the class is
not marked to rollback on that exception, so it continues and tries to
do a commit. Which isn't the case in my class since I had
rollbackOn=Throwable.class -- so rolling back on ALL exceptions,
including custom checked exceptions.


But then I looked into my classes and my hierarchy is like
Facade ---> Service class
Now what happens is that BOTH are annotated with @Transactional
I think if this is the cause, but I've removed the ones in the
lower-layer class (Service) and left it only in Facade class
(after testing)


That did the trick!!


The lesson for the day:


Multiple levels of @Transactional is not good. Set your transaction
boundaries in the uppermost layer where it's relevant, and that's it.


The service now returns:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<env:Fault xmlns:fault="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>fault:OPC10608</faultcode>
<faultstring>Bulletins exist that must be recalled</faultstring>
<faultactor>AdminService</faultactor>
<detail>
<java:string xmlns:java="java.io">Bulletin cannot be
created because of active bulletins that were created between
28/04/2010 and 06/05/2010</java:string>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>


Which is what I want.


Hope this helps someone out there!

Wednesday, 7 April 2010

Repairing OSX boot volume with Disk Utility after Software Upgrade gone bad (iMac not booting up)

About a week ago I upgraded OSX and ended up getting the White Screen
Of Death(TM), leaving me unable to boot up from the boot volume
"Macintosh HD". Luckily I have bootable OSX clone partitions on
external drives and was still able to use the computer. That's what I
get for upgrading iTunes and then deciding to get all the other
upgrades in Software Upgrade.

I still wasn't sure about how Time Machine would behave so I rang
Apple Support, since I I still have AppleCare until January 2011. The
very helpful Susette from Apple Support in Singapore was able to
restore my machine to working condition with the help of Disk Utility,
following these steps.

Of course, YMMV, and I give no guarantees that this will fix *your*
system. This is just what fixed my problem.

1. Boot the iMac from OSX Install Disk 1.

2. Select "English" as the language, then run Disk Utility.

3. The volume "Macintosh HD" should be listed in the available
volumes. If it doesn't display, then you might have bigger problems as
the hard drive itself may be physically damaged if the system can't
recognise it (this is the problem I had previously, requiring a visit
from Apple Support and replacement of my hard drive).

Select "Macintosh HD", then click on "Repair Disk"

4. If that finishes and displays a green message with "OK", then
select "Repair Disk Permissions"

5. That finished successfully and I quit Disk Utility, rebooted, and
all was working fine. Yay!

Thursday, 4 March 2010

Setting up WS-Security with Rampart module in Apache Axis web services framework

NOTE: This is from a work document I wrote that I published to Blogger via Google Docs. I'll edit it later, remove Appendices, make it more blog-y and nicer looking, but the info should be useful to someone out there.

Setting up WS-Security with Rampart module in Axis2, for authentication using Password Digest

Instructions

 

These instructions assume that the user is using Axis2 and is packaging their web service into an .aar package

This has been tested using Axis2 1.4.1 - 1.5.1 on JDK 5.

1. Download these:

Apache Axis2 1.4.1 (or latest version)

Apache Rampart 1.4 (or latest version) - security module for Axis2

Bouncycastle Java Cryptography Extensions (JCE) provider for your Java version
http://www.bouncycastle.org/latest_releases.html


2. Install Bouncycastle in JVM, or copy it to Axis webapp's /WEB-INF/lib/

Bouncycastle library is a Rampart dependency, so we need to include the Bouncycastle JCE provider in either the webapp's /WEB-INF/lib or install it in the JVM

2.1 Adding bouncycastle as a security provider in JVM

2.1.1 Add the bcprov-jdk15-***.jar to your service's / client's classpath.
Don't get the file that ends in "-ext.jar" because these ones contain patented, non-free code that is not needed by Rampart.

bcprov-jdk15 is specified by Rampart in its dependency listing but bcprov-jdk16 should also work,  

2.1.2 Add the following line to  file which can be found in JRE's lib/security/java.security directory as the last line.

security.provider.X=org.bouncycastle.jce.provider.BouncyCastleProvider

- "X" is the next unused number available for the listed security provider)

Also see: http://www.bouncycastle.org/documentation.html


3.1 To modify an existing axis2 webapp: 

Copy the *-codegen-*.jar files from Axis installation /lib into your existing webapp's /WEB-INF/lib directory.


3.2 To create a new axis2.war webapp:

You can use the Ant build.xml provided in the Axis2 installation /webapp directory to create axis2.war, provided you make one change: delete the line <exclude name="axis2-codegen*.jar"/> near the end of the file.

Then open a console to the Axis2 webapp directory and run ant.

After the build.xml runs, you can find the created axis2.war Web application in the Axis2 installation /dist directory


4. Copy from Rampart  /lib  to Axis2 webapp /WEB-INF/lib

opensaml-1.1.jar
rampart-core-1.4.jar
rampart-policy-1.4.jar
rampart-trust-1.4.jar
wss4j-1.5.4.jar
xmlsec-1.4.1.jar


5. Rampart needs the library backport-util-concurrent-3.1.jar. It's no longer present in Axis2 1.5 and higher, so for these versions you'll need to get it from:

http://backport-jsr166.sourceforge.net/

or

Axis2 1.4.1  /lib

And copy the jar file to  /WEB-INF/lib of your Axis2 webapp

In case of any further dependency issues with Rampart, see: http://ws.apache.org/rampart/dependencies.html


6. Copy from Rampart /modules to Axis2 webapp /WEB-INF/modules

rahas{version}.mar
rampart-{version}.mar

ie,

rahas-1.4.mar
rampart-1.4.mar

Then add these filenames to /WEB-INF/modules/modules.list , one per line


7. Create a password callback handler that will be used by Rampart to handle authentication. The class must implement the interface javax.security.auth.callback.CallbackHandler.

If multiple services in different code bases or .aar will be using the same authentication functionality, it is recommended that the callback handler be set up in its own jar file then copied to the Axis2 webapp's /WEB-INF/lib.
 

See Appendix for structure of callback handler.



8. Update the services.xml for each web service and add the following xml fragments between the <service> </service> tags.

The following are the WS-Policy to use for authentication using password plaintext and password digest.

 

The <module> and <ramp:RampartConfig> elements must be present when using Rampart, and are only relevant when using the Axis2 framework.


8.1 WS-Policy using PlainText password - username and password will be sent in soap headers, and password sent in plaintext

<module ref="rampart"/>

<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
        "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
      <wsp:ExactlyOne>
        <wsp:All>
          <sp:SupportingTokens
              xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
            <wsp:Policy>
              <sp:UsernameToken sp:IncludeToken=
                  "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"/>
            </wsp:Policy>
          </sp:SupportingTokens>

          <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
            <ramp:passwordCallbackClass>[REPLACE THIS WITH OUR PASSWORD CALLBACK CLASS, ie, security.package.PWCallBackHandler]</ramp:passwordCallbackClass>
          </ramp:RampartConfig>

        </wsp:All>
      </wsp:ExactlyOne>
</wsp:Policy>



8.2  WS-Policy using PasswordDigest

<module ref="rampart"/>

<wsp:Policy wsu:Id="UsernameToken" xmlns:wsu=
    "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:SupportingTokens
          xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
        <wsp:Policy>
          <sp:UsernameToken sp:IncludeToken=
              "http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">

            <wsp:Policy>
              <sp:HashPassword/>
            </wsp:Policy>

          </sp:UsernameToken>

        </wsp:Policy>
      </sp:SupportingTokens>

      <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
        <ramp:passwordCallbackClass>[REPLACE THIS WITH OUR PASSWORD CALLBACK CLASS, ie, security.package.PWCallBackHandler]</ramp:passwordCallbackClass>
      </ramp:RampartConfig>

    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>


9. Test that everything is working by configuring plaintext authentication. Plaintext authentication is easier to test with a tool like SoapUI because you can simply cut and paste XML and enter the login details in the header.

 

Testing of password digest authentication will require code of some kind to generate the various elements and calculate the digest before sending the client request.
 

 

Appendix A.

 

About Password Digest authentication


In the case where the communicating parties - the requester and the service - uses an insecure transport channel they should take steps to protect the passwords being exposed to others. Here the requester creates a digest of the actual password concatenated with a set of random bytes (nonce) and another value that is dependent on the creation time (created).


This digest is computed as follows :

digest = Base64_encode(SHA-1(nonce+created+password))

This is the base 64 encoded, SHA-1 digest of the concatenation of the nonce, created and password values.

The requester will send the username, nonce, created, and the digest values in within
the UsernameToken to the service.

 

To authenticate the request the service will compute
the digest value using the password bound to the received usename and will compare the
received digest value and the computed digest value.

 

An example UsernameToken that uses a digest of the password is shown in following figure:

<soapenv:Header>
     <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-26752749">
         <wsse:Username>libuser</wsse:Username>
         <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">/Wt/2yDdZwa8a5qd7U70hrp29/w=</wsse:Password>
         <wsse:Nonce>4ZQz5ytME/RXfChuKJ03iA==</wsse:Nonce>
         <wsu:Created>2009-03-17T11:20:57.467Z</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>
 </soapenv:Header>

If password in the username token is digested, the password callback handler only needs to provide the password for the client, to allow Rampart to verify it with the password received with the username token.
 

 

Appendix B


Password Callback handler implementation
 

The general structure of the server-side class will be like this:

public class PWCBHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
            String username = pwcb.getIdentifer();
            String password = pwcb.getPassword();

            int usage = pwcb.getUsage();
 

/**

Usage is WSPasswordCallback.USERNAME_TOKEN for a digested password, and WSPasswordCallback.USERNAME_TOKEN_UNKNOWN for a plaintext password or a password of unknown type.

 

*/


            // used when plaintext password in message
            if (usage == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {

/**

Verify username and password with existing authentication service
 

eg, authService.authenticate(username, password); 

If authentication fails, you should throw an UnsupportedCallbackException

If password digest is mandatory, then this section should either be
removed or just throw an UnsupportedCallbackException so that requests using plaintext password will fail.

*/
                             
            // when hashed password in message
            } else if (pwcb.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {

    

/**                       
In actual app, this should be replaced by code that will get the password for given username and specify it in pwcb.setPassword()


eg, pwcb.setPassword(authService.getPassword(id));

 

Rampart will take care of calculating the digest and comparing it with the digest sent in the request.

 

This assumes we have a way of retrieving passwords in plaintext.

 

If the auth system only returns password hashes, then client should use also use password hashIn such cases, the client should use same hash method as the auth system, so if the password is only available as an md5 hash, then the client should also generate an md5 hash of the password before calculating the digest.

 

*/


            }
        }
    }
}

Appendix C

 

References:

Web Services Security, UsernameToken Profile 1.0
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf
Contains explanation for design of password digest.

Java Web services: Axis2 WS-Security basics
http://www.ibm.com/developerworks/webservices/library/j-jws4/index.html


Password Callback Handlers Explained
http://wso2.org/library/3733


UsernameToken Authentication with Rampart
http://wso2.org/library/240#digest

The sample code for this article is incomplete and does not contain examples for password digest.
 

 

Appendix D

 

Examples of various authentication requests and error responses

 

1. Plaintext – simple XML request

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

    <soapenv:Header>
       <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                 soapenv:mustUnderstand="1">

        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                    wsu:Id="UsernameToken-1815911473">
                          <wsse:Username>client</wsse:Username>
                       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">apache</wsse:Password>
         </wsse:UsernameToken>
       </wsse:Security>
    </soapenv:Header>
 

   <soapenv:Body/>
</soapenv:Envelope>
 


2.  Password Digest - Bad Request with correct format but incorrect values.
 

Request:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

    <soapenv:Header>

         <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
            <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-26752749">
               <wsse:Username>libuser</wsse:Username>
               <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">wOaGIASh06nYuDs6RejYky0nsec=</wsse:Password>
               <wsse:Nonce>ole1X/60hjUqbUt3P2ak6w==</wsse:Nonce>
               <wsu:Created>2009-10-28T06:14:55.092Z</wsu:Created>
            </wsse:UsernameToken>
         </wsse:Security>

    </soapenv:Header>

   <soapenv:Body/>
</soapenv:Envelope>

Response:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <faultcode>wsse:InvalidSecurity</faultcode>
         <faultstring>The security token could not be authenticated or authorized</faultstring>
         <detail/>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

 

3. Password Digest - Bad Request with incorrect format, plaintext password
 

Request:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

    <soapenv:Header>

             <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                 soapenv:mustUnderstand="1">

               <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                    wsu:Id="UsernameToken-1815911473">
                 <wsse:Username>client</wsse:Username>
                 <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">apache</wsse:Password>
              </wsse:UsernameToken>
            </wsse:Security>

    </soapenv:Header>
   <soapenv:Body/>
</soapenv:Envelope>


Response:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <faultcode>wsse:InvalidSecurity</faultcode>
         <faultstring>The security token could not be authenticated or authorized</faultstring>
         <detail/>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>


4. Password Digest - Bad Request, incomplete format, password digest is required, but plaintext is sent instead of digest, and without nonce and createdtime
 

Request:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

    <soapenv:Header>

             <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                 soapenv:mustUnderstand="1">

               <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                    wsu:Id="UsernameToken-1815911473">
                 <wsse:Username>client</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">plaintext password</wsse:Password>
              </wsse:UsernameToken>
            </wsse:Security>
    </soapenv:Header>
   <soapenv:Body/>
</soapenv:Envelope>

Response:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <faultcode>wsse:InvalidSecurity</faultcode>
         <faultstring>An invalid security token was provided (Bad UsernameToken Values)</faultstring>
         <detail/>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>