Friday, May 17, 2013

one more null check with Optional

Instead of
    if (tipDocument.isPresent()) {
      return tipDocument.get();
    }
    return null;
use
return tipDocument.orNull();

Monday, April 22, 2013

How not to check for null

There are some clever tricks how to deal with null values. Usage of guava's Optional is one of them. But this is not one of them:
    final Optional<MilestoneDocument> documentOfVersion = findDocumentOfVersion(documentType, documentVersion);
    if (documentOfVersion == null) {
      throw new IllegalStateException();
    }
    if (documentOfVersion.isPresent()) {
      return documentOfVersion.get();
    }

Tuesday, February 19, 2013

user friendly search on windows

Windows with its cmd.exe seems not to be user friendly environment for developer. But this may be changed easily, you need only to install few programs we miss from normal systems. See http://gnuwin32.sourceforge.net and download coreutils, findutils, sed, awk, grep etc. and put them to PATH. As find.exe confilicts with windows file.exe I always rename it to gfind.exe . You have to be careful with quoting - only double quote is welcomed. Also paths may be tricki, remember to replace / with \. Eg. xargs needs extra backslash to interpret one properly.

Let's find all inserts in sql files.

find . -name '*.sql' | xargs grep insert 
It is the win32 version:
gfind . -name "*.sql" | sed s!/!\\\\!g | xargs grep insert

Summary: having in mind few simple rules you may make your system much easier to talk to.

Monday, February 11, 2013

picking up python

Recently I dived into jython, which is now scripting layer of application I' maintaining. Coming from Java/Scala I have some notices:
  • indentation matters
  • it actually does not matter that much, as I indent my code :>
  • method's first argument is always self
  • this point may have some exceptions, but for me a thumb rule is :%s/()/(self)/ in my vim :>
  • there is no null, but None
  • even if it's still jvm
  • None starts with capital letter, just like False, True and some others...
  • this one really surprised me
  • you do not write new to create new object
  • just call constructor, but
  • you have to return explicitly
  • which hurts when you're used to scala's brevity

Sunday, October 7, 2012

strange exception under JSF+JSP

Since we combined JSP with JSF 1.2 on websphere community edition (wasc 2.1.1.4) (same for apache geronimo/apache tomcat), i often see mysteriously looking exception: A literal value was specified for attribute actionListener (see below for stack). This looks like we cannot use #{...} expressions used by faces but only ${...} used by JSP. This is the exception itself:

Caused by: org.apache.jasper.JasperException: /portal/activity/ActivityResultInfo.jsp(377,8) A literal value was specified for attribute actionListener that is defined as a deferred method with a return type of void. JSP.2.3.4 does not permit literal values in this case
 at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
 at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
 at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:148)
 at org.apache.jasper.compiler.Validator$ValidateVisitor.checkXmlAttributes(Validator.java:1119)
 at org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:846)
 at org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1530)
 at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)
 at org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2411)
 at org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:865)
 ...
Fortunately we have not only found the problem but also a cure. Assuming web.xml for server is located in C:\Tools\WASC 2.1.1.4\var\catalina\conf, make sure it contains following entries:
  
        jsp
        org.apache.jasper.servlet.JspServlet
 
        modificationTestInterval
        0
    
        
            development
            true
        
        
            fork
            false
        
        
            xpoweredBy
            false
        
        
            engineOptionsClass
            org.apache.geronimo.jasper.JspServletOptions
    
    
        scratchdir
        c:/Tools/WASC 2.1.1.4/var/catalina/worker1/

    
    
        keepgenerated
        true
    
        3
    
keepgenerated = true is very important. Now, you can get rid of problem undeploying app, stopping your app server, cleaning scratch dir and redeploying app back. Then faces should run normally.

Friday, June 29, 2012

Do NEVER let user type in country name

It's really easier to maintain full list of countries in DB than end up with such (growing day by day) list for Great Britain only (authentic data from production):
CENTRE LONDON 
UNITED KINGDOM
U?K
NORTHERN IRELAND
WEST MIDS
CENTRE LONDON
WEST YORKSHIRE
ENGLAQND
UK 
?UK
GB,UNITED KINGDOM
GB
ENGLAND
N.IRELAND
MIDDLESEX
CORNWALL
GREAT BRITAIN
U.K.
WALES
NIRELAND

Friday, May 18, 2012

using Spring RestTemplate with parameters

I had to use HTTP today to get some data of remote service.
Usually I rather write a servlet on server side, so my first idea was to use simply java.net.URL to perform this task.
First you create URL, then openConnection, then open stream... and so on. Btw. how to issue POST request?
I just thought that it could be useful to use some more specialized API, but is it sensible to include e.g. Apache HttpClient into project just to issue a few simple requests?
And all code around the URL...

Why there is nothing like JdbcTemplate from Spring to operate on Http?
But wait... Let's look perhaps there is something?
Well smart guys from Spring Source already made it - the RestTemplate class.
Tada!
 Now my operation can look like this:
String pong = new RestTemplate().getForObject(address + PING, String.class);
Validate.isTrue(PONG.equals(pong));

And perhaps you may want to use POST with parameters via RestTemplate?
 HttpHeaders  headers = new HttpHeaders();
 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
 HttpEntity req = new HttpEntity<>(urlEncodeYourParams(), headers);
 RestTemplate rest = new RestTemplate();
 ResponseEntity result = rest.postForEntity(address, req, String.class);
 System.out.println( result.getBody() );

Really nice.