HtmlUnit Javascript Engine – Do you need it?

The Rhino engine used by HtmlUnit is great but can be slow. If you are worried about performance you can ask yourself whether you really need it. You can always enable it if you need it.

These are the settings I am currently using which is quick enough for me a the moment.


public class HtmlUnitWebClient extends WebClient {

    public HtmlUnitWebClient() {

super(BrowserVersion.CHROME);
super.setIncorrectnessListener(new IncorrectnessListenerImpl() {
@Override
public void notify(String arg0, Object arg1) {
//do nothing
}
});

final SilentCssErrorHandler eh = new SilentCssErrorHandler();
super.setCssErrorHandler(eh);
super.getOptions().setThrowExceptionOnScriptError(false);
super.getOptions().setThrowExceptionOnFailingStatusCode(false);
super.getOptions().setUseInsecureSSL(true);
       super.getOptions().setCssEnabled(false);
       super.getOptions().setPopupBlockerEnabled(false);
       super.getOptions().setRedirectEnabled(true);
      super.getOptions().setJavaScriptEnabled(false);
      super.setJavaScriptTimeout(3600);
super.getOptions().setTimeout(9000);
setCookieManager(new CookieManager() {
protected int getPort(final URL url) {
final int r = super.getPort(url);
return r != -1 ? r : 80;
}
});

}

}

Using the Spring Container for new instances

One of the most common mistakes when using  Spring IOC is using the new()  to create a new instance. If you instantiate a bean this way it won’t be picked up the Spring container and you lose all the magic that comes with IOC.

  1. When you create the class make sure you use the prototype scope
    @Component
    @Scope(value=”prototype”)
    Class MyClass {
    ……..
  2. Autowire the context into the bean
    @Autowired
    private ApplicationContext context;
  3. Instantiate the bean in your code
    MyNewClass myObject = context.getBean(MyNewClass.class)

And you’re done. The fact that we’re still creating beans using factories can easily be forgotten when we are using annotations. However you can still do things the old way.

 

HtmlUnit and Ajax Calls

By default HtmlUnit 2.13  does not wait for asynchronous  java scripts call to finish when loading a page. This can cause difficulties if you need to use the updated DOM of the new page after it has been manipulated by the javascript.

The FAQ gives some clues how it can be done. I found setting the ajax controller during initialising of the WebClient
         setAjaxController(new NicelyResynchronizingAjaxController());
 didn’t work for me. Elsewhere on the web there are suggestions that changing the Browser type to FIREFOX_3.6 might do the trick – in my case it didn’t.

However I was reading the FAQ incorrectly.  The call
         webClient.waitForBackgroundJavaScript(10000)
should be done inline not during initialization.  So we get something like

submit.click();
waitForBackgroundJavaScript(20000);
currentPage = (HtmlPage) getCurrentWindow().getEnclosedPage();

 

WCS started before Endeca Problems

When reboot it is possible that WCS comes up before Endeca
This comes up in the logs

[9/5/13 14:20:21:220 BST] 00000108 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[Store

s Request Servlet]: java.lang.NoClassDefFoundError: com.ibm.commerce.likeminds.filter.LikeMindsFilter (initialization failure)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
at java.lang.Class.forNameImpl(Native Method)
at java.lang.Class.forName(Class.java:172)
at java.beans.Beans.instantiate(Beans.java:184)

Just need to start Endeca by the console and bounce WCS.

Unique Identifier for a server

In order to get a unique machine identifier I have used

hostName = InetAddress.getLocalHost().getHostName();
return Math.abs(Long.valueOf(hostName.hashCode()));

Which works but it a bit clumsy.  Should really look for a better way.

A trivial way of acheiving the same things would be to get the IP address and removed the dots so 133.231.212.123 = 133231212123.

Otherwise it is possible to to convert it to a decimal http://www.mkyong.com/java/java-convert-ip-address-to-decimal-number/