Pages

Thursday, December 1, 2016

What is a Java Lambda Expression?

A lambda expression is a shortcut notation for an anonymous class implementation of an interface.


Which Interface? Where is the Type Definition...?

A lambda expression is used in the context of a target method signature. For example the following method signature

     public String doSomething(String s, MyInterface mi){...}

could be invoked with the following code using an anonymous class:

     doSomething("hello", new MyInterface(){
          public void myMethod() { 
               System.out.println("goodbye");}
          });

it can also be invoked with the following lambda expression:

     doSomething("hello", ()->{ System.out.println("goodbye");});



The target method doSomething is expecting two parameters - a String and an instance of MyInterface. The String value is clearly "hello", but the other is not so obvious. What happens here is the compiler sees that an instance of MyInterface needs to be somehow created from this expression and passed as the second parameter:

     ()->{ System.out.println("goodbye");}

To understand how this takes place we need to look at MyInterface

     interface MyInterface {
          public void myMethod();
     }


So what's so special about that interface?

The key characteristic of this interface is that it contains exactly one method definition. This makes it a functional interface, and it could be annotated with @FunctionalInterface for clarity although this is not necessary. Lamba expressions only work with functional interfaces.

Since the compiler needs to create an instance of MyInterface which it can pass to doSomething, it needs an implementation of myMethod.


Where is the compiler going to find an implementation of myMethod?

This is where the lambda expression comes into the picture. A lambda is a shortened syntax for an anonymous class definition, but since the interface contains only one method definition, the compiler can easily fill in the blanks. The left side of the lambda expression is a placeholder for the interface method signature parameters. Without this left side, the implementation would have no point of reference for these parameters.

For example if we change the signature to

     interface MyInterface {
          public void myMethod(int myNum);
     }

Then our lambda would look like this

     (i)->{ System.out.println("goodbye");}

Note that the simple implementation doesn't use the int value (which is ok).


Recap

Take an anonymous class implementation, strike out the unnecessary syntax which the compiler can figure out because there's only one method in the interface, then add a -> 

     doSomething("hello", new MyInterface(){
          public void myMethod()->
               System.out.println("goodbye");}
          });

What's left is a lambda expression!

Tuesday, November 10, 2015

Making HTML readonly Attribute Look Like Disabled

A quick entry in case anybody else runs into this scenario. I have a form with some text boxes which need to display as disabled, but the values aren't being submitted with the form. As it turns out, this is native behavior for the 'disabled' attribute.

The workaround is to use the 'readonly' attribute instead, but the problem with that is it doesn't render with a grayed out background. After fiddling for a while I came up with the following script:


dojo.ready(function(){
    dojo.query("[readonly]").forEach(function(node, index, arr){   
 dojo.attr(node.parentNode,"style", "background-color: #efefef !important");   
    });
 });

Maybe someone else will find this useful.

Thursday, April 30, 2015

Adding a Log4j Console to a Web Application

There's a popular open source jsp that allows changing the log4j levels for a web application called log4jAdmin.jsp that I've been wanting to use for troubleshooting, but using it poses a problem. Typically, deployable artifacts are built by an automated process and are not altered as they make their way through the different environments (development/integration/quality assurance/production). I definitely don't want a log4j administration console finding its way into a production environment as this would allow end users to access it.

So the ideal situation would be to add the jsp to the application after it has been deployed. I could have the system administrators add the file to the WebSphere installedApps directory, but this isn't recommended (and they would likely not agree to do this anyways).

A proper alternative is to use WebSphere's deployment process. Instead of updating an application using the default option, look further below on the page:



The contents of the zip should mirror the exploded folder structure in installedApps. In this case the zip contains a single JSP:



Any number of files can be injected into a deployed application using this technique, but in this particular instance I use it to manage Log4j log levels.

Thursday, February 26, 2015

Error Running wsadmin.sh

I've been making extensive use of wsadmin.sh as part of scripted WebSphere application installs to virtual machines, and today a script which I had written a long time ago started to throw the following error:

com.ibm.websphere.management.exception.AdminException: ADMA0043E: /tmp/app9215861615159415312.ear does not exist for installation.

I didn't find any conclusive solution to the error on the web although some suggested there was a mismatch in the location of the temp folder. I changed the websphere variable (Environment > Websphere variables) from

WAS_TEMP_DIR = ${USER_INSTALL_ROOT}/temp

to

WAS_TEMP_DIR = /tmp

Restarted the server and the problem went away. I have no idea why this worked before, but I guess it's fixed now.

Thursday, July 31, 2014

Error Messages using the WEF JAXB Plugin

I just resolved an issue related to my plugin for WEF which generates JAXB code for easy conversion to/from IXML and I thought I'd write it up before I forget.

The error message looks something like this:

java.lang.ClassCastException: javax.xml.bind.JAXBElement incompatible with com.dsixe.jaxbgen....

This seems to be caused by a variance in the schema generated by the SQL Call builder where the topmost wrapper element is not annotated as root element by JAXB. The problem is solved by using code which looks like this:


javax.xml.bind.JAXBElement jaxbElement = (javax.xml.bind.JAXBElement)Transform.convertToObject(available, "http://com/dsixe/Roles", com.dsixe.jaxbgen.rolesTransformSchema.RowSetType.class);

com.dsixe.jaxbgen.rolesTransformSchema.RowSetType iAvailable = (com.dsixe.jaxbgen.rolesTransformSchema.RowSetType) jaxbElement.getValue(); 
We need to initially cast to JAXBElement and then use getValue() to retrieve the object. One more line of code fixes the problem.

Friday, April 18, 2014

Defaulting WEF Builder Input Groups as Expanded

A little used WEF feature is the comments builder input which appears on all builder editors. The input always displays at the very top under the collapsed group header "Properties" along with the builder enable/disable input. The primary reason it is little used is because the "Properties" group is collapsed by default and therefore not immediately visible. This can be easily changed through these steps:

1) Extract the Base.bdef file from \WebContent\WEB-INF\builders\corebuilders.zip
2) Copy the file to \WebContent\WEB-INF\builders\com\bowstreet\core
3) Edit the highlighted element from true to false



Restart your eclipse workspace and the comments builder input should now be visible by default.


Remember to restart this process when you upgrade to a new version of WEF since this effectively overrides the designer's defaults.

Tuesday, March 4, 2014

REST vs SOAP

For some reason people who work in technology seem to have well defined opinions about matters and will often go to great lengths to defend those opinions. Think about the unix vi editor (I dislike), windows vs unix, windows vs apple. These topics will often lead to flame wars. Today I'm going to weigh in on web service transports and hope I don't light up a wildfire.

Early Binding vs Late Binding

I'm a supporter of the SOAP protocol for most cases unless the service is to be consumed by a javascript application. I've been thinking about why it is that I have this preference and I think I know exactly why. It comes down to early (or design time) binding of an external component vs late (or runtime) binding. This concept has been around since the early days of computer science, the idea being that a sub component can declare ahead of time what kind of operation signatures it supports so that these can be confirmed by the compiler. If a piece of code which has been bound at compile time fails at run time then we immediately know there is a conflict in versions. A similar concept is found in strongly typed languages. I can think of a few examples of this:
  • java interfaces
  • C/C++ header files
  • WSDL - web service definition language
The bad part of using SOAP is that it requires additional overhead, but in simple cases this is little more that a message envelope.

The other side of the argument is run time binding where we find out about the operation signatures when the code is actually executed. Now this isn't as bad as one thinks because the component owner will always provide details about the shape of the data and what is expected so the consumer that write appropriate code. The bad part of this is that the service provider can change anything at any time without notifying the consumers, resulting in an error when the consumer attempts to invoke an operation. There is a similar concept in weakly typed languages:
  • javascript
  • visual basic
  • assembly language

How to Choose?

The short answer is that this whole argument is moot if the software is well designed and written. All the valuable business logic should reside in java bean POJOs and then combined with a runtime container such as an enterprise service bus (ESB) or a service component architecture (SCA). The container manages exposing the POJO business logic using any number of transport protocols and can be configured at time of deployment. If an ESB or SCA is not available, then a similar result can be attained by coding a thin delegate using JAX-RS or JAX-WS.

Why do I prefer early binding? I don't like doing emergency production troubleshooting and with early binding I can eliminate one more point of failure.