Total Pageviews

Wednesday, February 15, 2012

Howto dynamically change webservice endpoint URL with Metro

A really cool feature of Metro (and maybe other webservice stacks) is the possibility to change the webservice endpoint URL at runtime.
In general, you typically generate the code via JAX-WS maven plugin (or ant task), specifying the endpoint URL in the generation properties. This is a fast and reliable way to generate webservices. The downside is, that it seems you can't change the endpoint URL at runtime ...
Well, you can. And it is pretty simple.
The example in this posting is taken from the Metro FAQ.

You can use BindingProvider.ENDPOINT_ADDRESS_PROPERTY to set the endpoint address in your client application code.

Sample:

 //Create service and proxy from the generated Service class.   
  HelloService service = new HelloService();   
  HelloPort proxy = service.getHelloPort();   
  ((BindingProvider)proxy).getRequestContext().  
       put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://new/endpointaddress");   
     
  proxy.sayHello("Hello World!");   

With the property key

BindingProvider.ENDPOINT_ADDRESS_PROPERTY
you can also get the currently used endpoint url at runtime. This may be helpful for debugging purposes.
Sample:

 LOG.info("Using endpoint URL: "  
        + ((BindingProvider)proxy).getRequestContext().get(  
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY));  

Friday, February 10, 2012

Updating GlassFish 3.1 under RHEL 6 on a 64 Bit machine

Don't be surprised when you have problems updating GlassFish 3.1 on a RedHat Enterprise Linux 6 64 Bit machine. This will not work out of the box (officially Oracle only supports GlassFish on RedHat 4 and 5 not on version 6). But there is a way to get it to work.
You will get this error when executing the pkg command:

 [glassfish@MYMACHINE glassfish3]$ pkg list -u  
 Traceback (most recent call last):  
  File "/opt/glassfish/glassfish3/pkg/bin/client.py", line 61, in ?  
   import pkg.actions as actions  
  File "/opt/glassfish/glassfish3/pkg/vendor-packages/pkg/actions/__init__.py", line 59, in ?  
   globals(), locals(), [modname])  
  File "/opt/glassfish/glassfish3/pkg/vendor-packages/pkg/actions/link.py", line 36, in ?  
   import generic  
  File "/opt/glassfish/glassfish3/pkg/vendor-packages/pkg/actions/generic.py", line 45, in ?  
   import pkg.variant as variant  
  File "/opt/glassfish/glassfish3/pkg/vendor-packages/pkg/variant.py", line 28, in ?  
   from pkg.misc import EmptyI  
  File "/opt/glassfish/glassfish3/pkg/vendor-packages/pkg/misc.py", line 49, in ?  
   import zlib  
 ImportError: libz.so.1: cannot open shared object file: No such file or directory  
 ---------------------------------------------------------------  
 There was an error running  
   
 /opt/glassfish/glassfish3/pkg/bin/../python2.4-minimal/bin/python  
   
 You are running on a 64 bit Linux distribution and the 32 bit Linux  
 compatibility libraries do not appear to be installed. In order to use  
 the Update Center tools you must install the 32 bit compatibility libraries.  
   
 On Ubuntu (and possibly other Debian based systems) please install the  
 ia32-libs package. On RedHat 4 (and other RPM based systems), you may  
 need to add multiple 'compat' runtime library packages. Please see the  
 Update Center Release Notes for more information.  
   
   

The solution is to install the following packages using yum

yum install compat-db.i686 zlib.i686 libidn.i686 krb5-libs.i686

The trick is to find out about the correct names of the packages. It's easy on Debian based systems but quiet difficult on RPM based systems.
If you are using CentOS take a closer look at this blog post.

Monday, February 06, 2012

Deep cloning of java objects

I was in need of deep cloning a map with all its keys and values.
All the map implementations in standard Java only do shallow cloning of the map. They don't clone the keys and values. But that was exactly what I want to realize.
I found out about the cloning library which does the job very easy and extremely fast. This library can clone nearly any java object.
A cloning expression is just a two-liner.
Very useful!
On this stackoverflow question you can find more deep cloning libraries.

Thursday, February 02, 2012

Don't use commons lang < 2.4 with HtmlUnit

In case you have a project which has a dependency to Apache commons-lang and you plan to use the latest HtmlUnit (as of writing this post this is HtmlUnit 2.9) you should take care of the version of commons-lang.

HtmlUnit is using a method (startsWithIgnoreCase) from commons-lang that was introduced in commons-lang 2.4.
So any commons-lang version below 2.4 will produce runtime exceptions when using HtmlUnit. The stacktrace may be similar to this one:

 java.lang.NoClassDefFoundError: Could not initialize class  
 com.gargoylesoftware.htmlunit.WebClient  
     at net.sourceforge.jwebunit.htmlunit.HtmlUnitTestingEngineImpl.createWebClient(HtmlUnitTestingEngineImpl.java:804)  
     at net.sourceforge.jwebunit.htmlunit.HtmlUnitTestingEngineImpl.initWebClient(HtmlUnitTestingEngineImpl.java:813)  
   
 also :  
   
 java.lang.NoSuchMethodError:  
 org.apache.commons.lang.StringUtils.startsWithIgnoreCase(Ljava/lang/String;Ljava/lang/String;)Z  
     at com.gargoylesoftware.htmlunit.util.URLCreator$URLCreatorStandard.toUrlUnsafeClassic(URLCreator.java:66)  
     at com.gargoylesoftware.htmlunit.util.UrlUtils.toUrlUnsafe(UrlUtils.java:193)  
     at com.gargoylesoftware.htmlunit.util.UrlUtils.toUrlSafe(UrlUtils.java:171)  
     at com.gargoylesoftware.htmlunit.WebClient.<clinit>(WebClient.java:162)  
     at net.sourceforge.jwebunit.htmlunit.HtmlUnitTestingEngineImpl.createWebClient(HtmlUnitTestingEngineImpl.java:804)  
     at net.sourceforge.jwebunit.htmlunit.HtmlUnitTestingEngineImpl.initWebClient(HtmlUnitTestingEngineImpl.java:813)  
   
   
   

In case you use Maven as your build tool you can check the dependencies using the command:

mvn dependency:tree

To avoid this error you can declare version 2.6 of commons-lang in your project.