Category Archives: java

Unit testing Java exception handling using JMockIt

How do you test that a method caught an exception? What if that catch did not have a side effect, it just logged output, or simply swallowed the exception?

Context
We have a method in a class that was written with a try catch and we need to unit test it. There are many ways this task can occur, such as the need to test legacy code or the need to write a test before a refactoring of such code.

We won’t go into the anti-pattern aspects or what constitutes proper handling of an exception here.

Error hiding is an anti-pattern in computer programming. Due to the pervasive use of checked-exceptions in Java, we must always address what to do with exceptions. Error hiding is when a catch clause does not property handle an exception.
 

In a catch block there are three common ways of handling an exception:

try{
   ... stuff ...
}catch(X){
   // 1. do something here
   // 2. maybe throw X or something else
   // 3. skip the above and do nothing
}

How are these tested?

Thrown exception
When the method reacts by throwing an exception we can test using the standard JUnit @Test(expected=SomeException.class), or for fine-grained verification, the test itself has a try catch block where we can assert the exception details.

Swallowed exception
If a method does nothing in the catch block, which is also called “swallowing” the exception, should it even be a test issue? Yes. The method is just tested normally. One of the tests must force the exception, of course. We do this since in future the method may be changed to handle the exception differently. One of the test assertions that can be made is that the forced exception is not thrown from the method.

Exception handler pointcut
Testing that an exception in the method under test was actually caught is possible, but only with Aspect Oriented Programming (AOP). One example language is AspectJ which supports the pointcut:

handler(TypePattern)
Picks out each exception handler join point whose signature matches TypePattern.
 

Behavior in catch
It gets more interesting when the catch block has ‘behavior’. This behavior has side effects. If these side effects are only local to the method, such as setting a flag false, then normal testing is adequate. If this behavior has side effects at the class or with collaborating objects, then this requires more complex testing.

It can get murky with this kind of testing. What is important is that one does not test the implementation (but sometimes that is crucial), only the interactions and requirements of the target “Unit” under test. What constitutes a “unit” is very important.

“Typically, a unit of behavior is embodied in a single class, but it’s also fine to consider a whole set of strongly-related classes as a single unit for the purposes of unit testing (as is usually the case when we have a central public class with one or more helper classes, possibly package-private); in general, individual methods should not be regarded as separate units on their own.” — Rogerio in JMockit Tutorial

.

Example
The method being tested invokes a method on a collaborating object and that object throws an exception. In the catch block, the exception is logged using the logging utility collaborator . Though not part of an explicit API, that logging may be critical to the use of a system. For example, an enterprise log monitoring system expects this logging for support or security concerns. A simple class Shop is shown in figure 1,

Figure 1, the class to test

public class Shop {
    private ShoppingSvc svc;
    
    /**
     * Get product name.
     * @param id the unique product id
     * @return the product name
     */
    public String getProduct(int id){
        String name = "";
        try {
            name = svc.getProductName(id);
        } catch (Exception e) {
            Logger.getAnonymousLogger()
			.log(Level.SEVERE, 
			"{result:\"failure\",id:\""+ id + "\"}");
        }
        
        return name;
    }
    
}

JMockit Use
JMockit supports two type of testing: behavior and state-based (or “Faking”).
Using the state based approach we create a mock for the getProductName(String) method of the collaborating (or dependent) class, ShoppingSvc. With JMockit this is easily done as an inline MockUp object with the target method mocked to throw an exception.

Listing 2, mocking

new MockUp<ShoppingSvc>() {
    @Mock
    public String getProductName(int id) throws IOException{
		throw new IOException("Forced exception for testing");
    }
};

JMockit’s behavior based support is then used to test the catch clause handling. As in other mocking frameworks, a record-replay-verify phases are used. Since the side effect of the exception handler here is the use of the logging dependency and we are not testing the logger, we ‘behaviorally’ mock the Logger class.

We can do this in the test method signature, @Mocked final Logger mockLogger. This mocks every method in the logger class. Then we set an expectation on the log method being used in the exception handler, then verify the method was actually invoked.

The full test class is shown in figure 3 below and the sample code is in a repo on GitHub:https://github.com/josefbetancourt/examples-jmockit-exceptions.

An alternative to using both state and behavior mocking is to just specify the exception throwing with the expectations. The article “Mocking exception using JMockit” shows how to do this. Of course, the JMockit Tutorial has all the details.

Listing 3, the full test class

@RunWith(JMockit.class)
public class ShopTest{
    /**
     * 
     * @param mockLogger Logger object that will be behaviorally mocked.
     */
    @Test
    public void shouldLogAtLevelSevere(@Mocked final Logger mockLogger)
    {
        /**
         * state-based mock of collaborator ShoppingSvc
         */
        new MockUp<ShoppingSvc>() {
            @Mock
            public String getProductName(int id) throws IOException{
                throw new IOException("Forced exception for testing");
            }
            
        };
        
        // the SUT  
        final Shop shop = new Shop();

        // what we expect to be invoked
        new Expectations() {{
            mockLogger.log(Level.SEVERE,anyString); 
        }};
        
        shop.getProduct(123); // actual invocation
        
        // verify that we did invoke the expected method of collaborator
        new Verifications(){{
            mockLogger.log(Level.SEVERE, anyString);  // we logged at level SEVERE
        }};
    }
}

Alternatives?
Just write better code so that you don’t need unit tests? This is mentioned in Functional Tests over Unit Tests

Test using a scripting language like Groovy? See Short on Time? Switch to Groovy for Unit Testing

Software
– JUnit: 4.12
– JMockit: 1.18
– JDK: 1.8
– Eclipse: Mars
– Maven: 3

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

SvnKit E170001: Negotiate authentication failed: ‘No valid credentials provided’

In a new project, attempts to programmatically access our Subversion server using SvnKit fails with an E170001 error. But, only on one Windows 7 workstation.

After a lot of searching on web for answers finally found something that helped. I had to add system property: svnkit.http.methods=Basic,Digest,Negotiate,NTLM

So, using SvnCli, which I used to debug this, you add the property using the “-D” switch to the command line.

java -Dsvnkit.http.methods=Basic,Digest,Negotiate,NTLM -cp "SvnCli\*" org.tmatesoft.svn.cli.SVN --username *** --password *** list

I also had to add this property to the Tomcat app server.

Solution?
While this does fix the problem in this instance, since only one workstation is effected, it is probably hiding an underlying configuration setup issue.

I wonder what percentage of the nation’s GDP is spent on configuration and its issues.

Original stacktrace:

Mar 18, 2015 11:40:31 AM org.tmatesoft.svn.core.internal.util.DefaultSVNDebugLogger log
SEVERE: CLI: svn: E170001: Negotiate authentication failed: 'No valid credentials provided'
org.tmatesoft.svn.core.SVNException: svn: E170001: Negotiate authentication failed: 'No valid credentials provided'
        at org.tmatesoft.svn.cli.AbstractSVNCommandEnvironment.handleWarning(AbstractSVNCommandEnvironment.java:401)
        at org.tmatesoft.svn.cli.svn.SVNListCommand.run(SVNListCommand.java:95)
        at org.tmatesoft.svn.cli.AbstractSVNCommandEnvironment.run(AbstractSVNCommandEnvironment.java:142)
        at org.tmatesoft.svn.cli.AbstractSVNLauncher.run(AbstractSVNLauncher.java:79)
        at org.tmatesoft.svn.cli.svn.SVN.main(SVN.java:26)
        at org.tmatesoft.svn.cli.SVN.main(SVN.java:22)
svn: E170001: Negotiate authentication failed: 'No valid credentials provided'

Environment

  • Java 1.7
  • SvnKit 1.8.8
  • Tomcat 7

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Use JAXB to export Subversion log to Java

In a previous blog post I obtained the subversion XML log output. Now I need to convert that into Java objects in order to provide some special reporting requirements. Below I just present the unmarshal code.

Updates
Dec 3, 2014: cloned code into a github repository

As mentioned before, by using a high-level Java API to Subversion, like SVNKit, we can generate logs and have those already unmarshaled into objects. This is the recommended approach.

Let’s continue with the “brute force” way of accessing the output XML log output.

In listing one the Unmarshal class is a utility that hides the JAXB unmarshal code. The actual use of JAXB is a few lines, but this class provides methods that accepts various sources. For example using a file path:
Log theLog = new Unmarshal().path(“src/test/resources/log.xml”);

Unmarshal.java
package com.octodecillion.svn;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

import org.xml.sax.SAXException;

import com.google.common.base.Preconditions;
import com.google.common.io.CharSource;
import com.google.common.io.Resources;

/**
 * @author jbetancourt
 */
public class Unmarshal {
    /** */
    public Log path(String path) throws JAXBException, SAXException,
            IOException {
        Preconditions.checkNotNull(path, "'path' param is null");
        return url(new File(path).toURI().toURL());
    }

    /**  */
    public Log url(String url) throws JAXBException, SAXException, IOException {
        Preconditions.checkNotNull(url, "'url' param is null");
        CharSource charSrc = Resources.asCharSource(new URL(url),
                Charset.defaultCharset());
        return unmarshall(charSrc);
    }

    /**  */
    public Log url(URL url) throws JAXBException, SAXException, IOException {
        Preconditions.checkNotNull(url, "'url' param is null");
        CharSource charSrc = Resources.asCharSource(url,
                Charset.defaultCharset());
        return unmarshall(charSrc);
    }

    /** */
    public Log string(String xml) throws JAXBException, SAXException,
            IOException {
        Preconditions.checkNotNull(xml, "'xml' param is null");
        return unmarshall(CharSource.wrap(xml));
    }

    /** */
    public Log unmarshall(CharSource in) throws JAXBException, SAXException,
            IOException {
        Preconditions.checkNotNull(in, "'in' param is null");
        JAXBContext jaxbContext = JAXBContext.newInstance(Log.class);
        Log theLog = null;
        
        try(Reader reader = in.openStream()){
            StreamSource source = new StreamSource(reader);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            JAXBElement<Log> jxbElement = unmarshaller.unmarshal(source, Log.class);
            theLog = jxbElement.getValue();
        }
        
        return theLog;
    }
}
Listing 1, Unmarshal class

The Classes tree that captures the SVN log output XML
The log is in this format:

<log>
  <logentry revision="20950">
	<author>jbetancourt</author>
	<date>2014-11-10T20:12:11.910891Z</date>
	<paths>
		<path text-mods="false" kind="file" action="D" prop-mods="false">/2014/Acme/branches/rabbit-trap/www/images/beep.png
		</path>
	</paths>
	<msg>initial commit</msg>
   </logentry>
   <logentry revision="20948">
.....
</log>

Listing 0, example log contents

To use JAXB we create annotated classes to match the log XML.

These are simple use of JAXB. I’m sure there are better approaches. Note, the getter/setters
were not put in. Does a JAXB processor need these? Can’t it just use reflection?

The toString() in these classes return a JSON marshaling of the object. This is helpful for unit testing and debug.

Log.java
package com.octodecillion.svn;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author j.betancourt
 */
@XmlRootElement
public class Log {
	@XmlElement(name = "logentry")
	List<LogEntry> entries;

        @Override
	public String toString() {
		StringBuilder bld = new StringBuilder();
		for(LogEntry entry : entries){
			bld.append(entry.toString());
		}
		
		return bld.toString();
	}	
	
}

Listing 2, Log class

LogEntry.java
package com.octodecillion.svn;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

import com.google.common.base.Joiner;

/**
 * @author j.betancourt
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class LogEntry {
	@XmlAttribute
	String revision;
	String author;
	String date;
	@XmlElementWrapper(name="paths")
	@XmlElement(name="path")
	List<Path>paths;
	String msg;

        // getter/setters not shown 

	@Override
	public String toString() {
        	StringBuilder bld = new StringBuilder("[");		
		bld.append(Joiner.on(",").join(this.paths)).append("]");		
		return String.format("{revision:%s,author:%s,date:%s,paths:%s,msg:%s}", this.revision,this.author,this.date,bld.toString(),this.msg);
	}
}
Listing 3, LogEntry class

Path.java
package com.octodecillion.svn;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

/**
 * @author j.betancourt
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Path {
	@XmlValue
	String value;
	@XmlAttribute(name = "text-mods")
	String textmods;
	@XmlAttribute(name="kind")
	String kind;
	
	@XmlAttribute(name="action")
	String action;
	@XmlAttribute(name="prop-mods")
	String propmods;

	@Override
	public String toString() {
	   return String.format("{value:%s,kind:%s,action:%s,textmods:%s,propmods:%s}", 
             value.replaceAll("\\n+",""),kind,action,textmods,propmods);
	}
}
Listing 4, Path class

A JUnit 4 test

package com.octodecillion.svn;

import java.io.IOException;

import javax.xml.bind.JAXBException;

import org.junit.Assert;
import org.junit.Test;
import org.xml.sax.SAXException;

/**
 * @author j.betancourt
 */
public class UnMarshallTest {

	@Test
	public final void test() throws Exception {
		Log theLog = new Unmarshal().path("src/test/resources/log.xml");
		String actual = toSingleLine(theLog.toString());
		String expected1 = "{revision:20950,author:jbetancourt,date:2014-11-10T20:12:11.910891Z,paths:[{value:/2014/Acme/branches/rabbit-trap/www/images/beep.png,kind:file,action:D,textmods:false,propmods:false}],msg:initialcommit}{revision:20948,author:jbetancourt,date:2014-11-10T19:55:58.629641Z,paths:[{value:/2014/Acme/branches/rabbit-trap/www/images/desert.png,kind:file,action:D,textmods:false,propmods:false}],msg:changedicontint}{revision:20942,author:jbetancourt,date:2014-11-10T15:30:08.770266Z,paths:[{value:/2014/Acme/branches/rabbit-trap/www/scripts/acme/traps/rocket.js,kind:file,action:M,textmods:true,propmods:false},{value:/2014/Acme/branches/rabbit-trap/www/scripts/acme/traps/sled.js,kind:file,action:M,textmods:true,propmods:false}],msg:Added'usestrict'.}{revision:20941,author:rsmith,date:2014-11-10T15:20:41.707766Z,paths:[{value:/2014/Acme/branches/rabbit-trap/www/ads/umbrella/promo.html,kind:file,action:M,textmods:true,propmods:false},{value:/2014/Acme/branches/rabbit-trap/www/ads/images/umbrella.jpg,kind:file,action:A,textmods:true,propmods:true}],msg:promotionMerge}";
		String expected = toSingleLine(expected1);
		Assert.assertEquals("Created wrong object structure", expected, actual);
	}

	/**  */
	String toSingleLine(String s) {
		String s1 = s.replaceAll("\\n+", "");
		return s1.replaceAll("\\s+", "");
	}

}

Listing 5, JUnit test

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.octodecillion</groupId>
  <artifactId>svnunmarshal</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>SvnUnMarshal</name>
  <description>Example of how to use JAXB to unmarshal svn log</description>
  <!-- 
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
              <source>1.7</source>
              <target>1.7</target>
            </configuration>
        </plugin>       
    </plugins>
  </build>
   -->
  <dependencies>
    <dependency>
        <groupId>org.tmatesoft.svnkit</groupId>
        <artifactId>svnkit</artifactId>
        <version>1.8.5</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>xmlunit</groupId>
        <artifactId>xmlunit</artifactId>
        <version>1.5</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-exec</artifactId>
        <version>1.3</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.jmockit</groupId>
        <artifactId>jmockit</artifactId>
        <version>1.13</version>
        <scope>test</scope>
    </dependency>
  </dependencies>
</project>
Listing 6, Maven POM

Further reading

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Run svn command from Java using Commons exec

In a project I will need to marshal a Subversion log into Java. First step was getting Java to talk to a subversion repository. There are many options for doing this. Two of these are using a SVN API like SVNKit or invoking the command line svn executable.

Lets say you decide on the second option, invoking the svn binary, how would you do it? Easiest way is to use the Apache Commons Exec library. In listing below I use Exec and the Guava API in a Java 1.7 source level. Of course, this is not a ‘reusable’ solution, for example, the arguments to the two implemented commands are fixed. But, that is all I need right now.

Example use: new Command().log(“some/repo/somewhere”);

Expand.java
package com.octodecillion.svn;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Properties;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.PumpStreamHandler;

import com.google.common.base.Preconditions;
import com.google.common.io.Resources;

/**
 * Invoke SVN commands from Java.
 * Just log and list for now.
 * <p>
 * Requires the command line SVN executable.
 * These are specified in svn.properties file in class path.
 *
 * Note: Thread safety has not been tested.
 *
 * @author j.betancourt
 *
 */
public class Command {

    /**
     * Constructor.
     * @throws IOException
     */
    public Command() throws IOException {
        try(BufferedReader is = 
             (Resources.asCharSource(Resources.getResource("svn.properties"),
			Charset.defaultCharset())).openBufferedStream()
            ){

            Properties props = new Properties();
            props.load(is);
            commandLineClientLocation = props.getProperty("commandLineClientLocation",
				DEFAULT_SVN_PROGRAM_LOCATION);
            commandLineClientFileName = props.getProperty("commandLineClientFileName", 
				DEFAULT_SVN_EXE);
        }
    }

    /**
     * @see http://svnbook.red-bean.com/en/1.4/svn.ref.svn.c.log.html
     *
     * @param url
     * @return
     * @throws IOException
     * @throws ExecuteException
     * @since Nov 18, 2014
     */
    public String log(String url) throws ExecuteException, IOException {
        Preconditions.checkNotNull(url, "url param is null");
        CommandLine cmdLine = createCmdLine()
                .addArgument("log")
                .addArgument("--stop-on-copy")
                .addArgument("--verbose")
                .addArgument("--xml")
                .addArgument(url);

        return executeCommand(cmdLine);
    }

    /**
     * @see http://svnbook.red-bean.com/en/1.4/svn.ref.svn.c.list.html
     * @param baseURL
     * @return
     * @throws IOException
     * @throws ExecuteException
     * @since Nov 19, 2014
     */
    public String list(String url) throws ExecuteException,IOException {
        Preconditions.checkNotNull(url, "url param is null");
        CommandLine cmdLine = createCmdLine()
                .addArgument("list")
                .addArgument("--xml")
                .addArgument(url);
        return executeCommand(cmdLine);
    }

    private CommandLine createCmdLine() {
        return CommandLine.parse(commandLineClientFileName);
    }

    /**
     * Execute command line at working directory.
     * @param cmdLine
     * @return String that captured the error and standard output streams
     * @throws ExecuteException
     * @throws IOException
     * @since 2014-11-20
     */
    private String executeCommand(CommandLine cmdLine) 
		throws ExecuteException,IOException {
        DefaultExecutor exec = new DefaultExecutor();
        exec.setWorkingDirectory(new File(commandLineClientLocation));

        String str ="";
        try(ByteArrayOutputStream outputStream = 
              new ByteArrayOutputStream()){

            exec.setStreamHandler(new PumpStreamHandler(outputStream));
            exec.execute(cmdLine);
            str =  outputStream.toString();
        }

        return str;
    }

    private static final String DEFAULT_SVN_EXE = "svn.exe";
    private static final String DEFAULT_SVN_PROGRAM_LOCATION = 
		"\\Program Files\\CollabNet\\Subversion Client";

    private String commandLineClientLocation = DEFAULT_SVN_PROGRAM_LOCATION;
    private String commandLineClientFileName = DEFAULT_SVN_EXE;
}

 

Further reading

  • Guava
  • Apache Commons Exec
  • SVNkit
  • Calling SVN commands from a java program
  • Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

    Groovy is a language

    A few years ago I wrote a few Groovy language scripts to help with some configuration and testing needs. I discussed these with my co-workers. But, lo and behold, for weeks they thought I was saying that the scripts were Groovy, as in cool, not Groovy as in the JVM based dynamic language. They never heard of Groovy. We had a big laugh.

    This situation made me think again that developers have differing interests in their field. No offense, but a certain percentage just go to work and do what is required and punch out at the end of the day. It is Java today, but it may as well be COBOL, there is always opportunity to copy and paste and do the minimum to “solve” the current business stakeholder requirements.

    I’m sure this is only true for some corporate IT environments which have a top down rigid structure and legacy applications. Introducing change into the software process and tools is difficult. Stability and safety is paramount. Thus, the worker who toes the line and is not disruptive is an asset. Sure, there is talk of change and new techniques, but at the end of the day: “no, we can’t use that, we have this.” The new web businesses and open-source projects are different, of course.

    BTW, Groovy is now slowly being used in my company. But, not sure many have heard of it yet.

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

    Java reflection on a message using MethodHandle

    Some code I was looking at recently had an overloaded method and each method just accepted a different type argument. With Generics there are probably ways to reduce this clutter, or not.

    Anyway, I started thinking about the original concept of OO; it was all about ‘messages’. But what is the difference between a ‘message’ as per Alan Kay and Smalltalk and a method’, née “subroutine” in Java? I guess it’s intent, design, and the other features of OOP?

    Jump to example source code

    Following this line of thought I wound up looking at how to invoke a public method on a class and that method in turn delegates to private methods that match the data within the message. BTW, this is not a new concept, it is an often used ‘idiom’, like in servlets and other backend service handlers.

    The public method is the destination of a ‘message’. So I searched the web and found mention of the usual Reflection, Proxies, instanceof, and finally MethodHandles. The package java.lang.invoke contains the new approach to reflection introduced in Java 7. MethodHandle is the new class that makes all this possible.

    Not much on MethodHandle on the web (search instead for: java “method handle”), but the API docs are very good and this blog post, “A glimpse at MethodHandle and its usage”, is all you need to get started. Below in Listing 1, a simple example is shown. Class Server has a single method that takes a String message and a parser.

    The message contains the data that is used to determine the actual method to invoke. Simple, but the point is that this could be a JSON/XML string or some other data container. The parser is just me experimenting with callbacks, here the callback gets the data in the message. Yeah, I know, if the client can get the data, why not just send it? It’s just a ‘hello world’ example.

    Example
    In listing 1 the Service class exposes one method, send.

    public class Service {	
        public Object send(String message, Parser parser) throws Throwable {
    	Object pData = parser.parse(message);		
    
    	MethodType methodType = 
              MethodType.methodType(
                Object.class,pData.getClass());		
    
    	MethodHandle mh = MethodHandles.lookup()
             .findVirtual(
                Service.class, "call", methodType);		
    
    	Object actual = mh.invoke(this,pData);		
    	return actual;
        }
    
        @SuppressWarnings("unused")
        private Object call(String data) {
    	System.out.println("in string method ...");
    	return "string data";
        }
    
        @SuppressWarnings("unused")
        private Object call(Integer data) {
    	System.out.println("in int method ...");
    	return new Integer(42);
        }
    	
        public interface Parser{
    	public Object parse(String s); 
        }
    }
    

    Listing 1

    In listing 2, the Main class sends the message to the Service class.

    public class Main {    
        public static void main(String[] args) throws Throwable {
          Service app = new Service();
          Service.Parser parser = new Parser();   
    
          Object actual = app.send("some text", parser);
          assert actual == "string data" 
            : "Should have returned 'some data' string";
            
          actual = app.send("number: 42",parser);
          Integer expected = 42;
          assert (actual.equals(expected)) 
             : "Should have returned Integer with value 42";
      }
        
      static class Parser implements Service.Parser{                  
          @Override
          public Object parse(String s) {
              if(s.startsWith("number:")){                            
                  Integer i = Integer.valueOf(  
                      (s.split(":")[1]).trim() );
                  return i;
              }
              
              return s;
          }
      }
    }
    

    Listing 2

    Not earthshaking of course. The output is:
    in string method …
    in int method …

    The example is somewhat like the javax.servlet.Servlet class, only one method, service(ServletRequest req,ServletResponse res) is also used, and usually one invokes other methods based on the “message” params.

    I can see the use of MethodHandles leading to some powerful mojo.

    Links

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

    Groovy implementation of INIX file format, part 2

    Continued experimentation with the INIX “ini” file format. I take the original post code and add an alias feature.

    Background
    In three prior posts I presented a very simple metadata file storage approach. Pretty much using the INI file format with the sections as “heredocs.” In original INI format, afaik, the data within the sections were properties only, x=y.

    Updates

  • Dec 25, 2015: Just saw a mention of Tom’s Obvious, Minimal Language (TOML) This is not directly related to what I’m after with Inix, but interesting as an example of a simple markup language.
  • Alias
    Now I am working on adding the ability for a section of data to load data from another section. The sections to load are indicated by the ‘@’ symbol and then the section path. Multiple sections can be indicated. Though I’m using the term ‘alias’ for this, perhaps a better term is ‘importing’. So far, I can parse the alias from the tag string.

    I have not implemented the actual import. One complexity left to solve is recursion. If this section imports another section, what if that section imports others sections?

    Alias use case
    Since currently the Inix file format is being used for test data, aliasing allows reuse of data without duplication, i.e., DRY. This is problematic with hierarchical data like JSON or XML, but much easier with lists or maps. Further features like overriding and interpolation would be useful for Java Properties data. The goal would be to eventually support use of the Cascading Configuration Pattern.

    Example 1

    [>First]
    Data in first    
    [<]
    
    [>Second@First]
    Data in second
    [<]
    

    Now when the data in section “Second” is loaded, the data from the aliased section is prepended to the current section data:

    Data in first    
    Data in second
    

    Tag format
    The section tag format is now: [>path#fragment@aliases?querystring]. Note that unlike a URI, the fragment does not appear at the end of the string.

    The section ID is really the path#fragment. Thus, the end tag could be [<] or can use the section ID: [<path#fragment]. Example 2

    [>demo1/deploy#two@account897@policy253?enabled=true&owner=false]
    stuff here
    [<demo1/deploy#two]
    

    Grammar
    The start of a grammar follows, but has not been ‘checked’ by attempted use of a parser generator like Antlr.

    grammar Inix;
    section: start CRLF data end;
    start: '[>' path (fragment)?(alias)*('?' args)? ']';
    end: '[<' path? ']';
    path: NAME ('/' NAME)*;
    fragment: '#' NAME;
    alias: '@' NAME
    args: (NAME=NAME ('&' NAME=NAME)*)?;
    data: (ANYTHING CRLF)*;
    NAME: ('a'..'z' | 'A'..'Z')('a' .. 'z' | 'A'..'Z'|'0'..'9'|'_');
    
    TODO:

    1. Do the actual import of aliased section data.
    2. Allow multiple params per param key: ?measure=21,measure=34,measure=90. Or better yet, just allow array in arg string: measure=[21,34,90],color=red

     

    Implementation
    Source code available at Github: https://gist.github.com/josefbetancourt/7701645

    Listing 2, Implementation

    Test class
    Note that there are not enough tests and the implementation code has not been reviewed.

    Listing 3, Test class

    The test data is:

    Listing 4, data file

    Environment
    Groovy Version: 2.2.2 JVM: 1.7.0_25 Vendor: Oracle Corporation OS: Windows 7

    Further Reading

    1. The Evolution of Config Files from INI to TOML
    2. Groovy Object Notation using ConfigSlurper
    3. Configuration Files Are Just Another Form of Message Passing (or Maybe Vice Versa)
    4. INI file
    5. Data File Metaformats
    6. Here document
    7. JSON configuration file format
    8. Creating External DSLs using ANTLR and Java
    9. Groovy Object Notation (GrON) for Data
      Interchange
    10. Cloanto Implementation of INI File Format
    11. http://groovy.codehaus.org/Tutorial+5+-+Capturing+regex+groups
    12. URI
    13. Designing a simple file format
    14. The Universal Design Pattern
    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

    Regex group capture with optional delimeter

    Ever had one of those days where the simplest thing seems complex? A simple regex is doing that to me now.

    This is the example, simplified. You have a string “BEFOREAFTER”. If this string has a ‘x’ in it, you want to capture everything before the ‘x’, else you want to capture the whole string. So,
      “BEFOREAFTER” gives “BEFOREAFTER”
      “BEFORExAFTER” gives “BEFORE”

    jump to solution

    Yes, I know this can be done programmatically or just using String.split(….). Don’t you hate on Stackoverflow and other places where they say don’t do it that way, but you still want to know: yes, but if I do choose this way, how would it be done? This is a learning incident.

    This should be easy, regex 101, right? I thought so too. I thought /^(.*)x?.*/ would work, nope. I tried captures with non-greedy quantifiers, zero-width this or that, etc. I even went back to reading Mastering Regular Expresssions by Jeffrey E. F. Friedl, O’Reilly Media, Inc. Great book by the way.

    My solution just has to be wrong. Here it is written using the Groovy language.

    def re = /^(.*)x|^(.*)/
    
    getCaptureGroup(re,"BEFORExAFTER")
    getCaptureGroup(re,"BEFOREAFTER")
    getCaptureGroup(re,"")
    getCaptureGroup(re,null)
    getCaptureGroup(null,"x")
    
    def getCaptureGroup(regex, inString){
      def found = ""	
    
      def m = (inString =~ regex)
      if(m){
        List matches = (List)m[0]		
        found =  matches[1] ? matches[1] : 
          (matches[2] ? matches[2] : "")
       }	
    	
       println "Using pattern $regex in String '$inString', 
        found group: '($found)' of type: ${found.getClass().getSimpleName()}"
    }
    

    The output of this script is:

    Using pattern ^(.*)x|^(.*) in String 'BEFORExAFTER', found group: '(BEFORE)' of type: String
    Using pattern ^(.*)x|^(.*) in String 'BEFOREAFTER', found group: '(BEFOREAFTER)' of type: String
    Using pattern ^(.*)x|^(.*) in String '', found group: '()' of type: String
    Using pattern ^(.*)x|^(.*) in String 'null', found group: '(null)' of type: String
    Using pattern null in String 'x', found group: '()' of type: String
    


    Any other way of designing the regex using the Java regex engine?

    Solved
    I found a Stackoverflow entry that solved a similar question here.

    So the solution is now:

    def re = /^(.*?)(?:x.*|$)/
    
    getCaptureGroup(re,"BEFOREAFTER")
    getCaptureGroup(re,"BEFORExAFTER")
    getCaptureGroup(re,null)
    getCaptureGroup(null,"x")
    println ""
    
    def getCaptureGroup(regex, inString){
      def found = ""
    	
      def m = (inString =~ regex)
      if(m){
      	List matches = (List)m[0]		
      	found =  matches[1]
      }	
      
      println "Using pattern $regex in String '$inString', 
        found group: '($found)' of type: ${found.getClass().getSimpleName()}"
    }
    

    Or as one line:
    println ((“BEFORExAFTER” =~ /^(.*?)(?:x.*|$)/)[0][1])

    Further reading

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

    Don’t let Java varargs limit an API

    Was looking at Simple Logging Facade for Java (SLF4J), a Java logging library. One nice feature is that one can use message formats that don’t get evaluated until the log statement is executed, which in turn depends on the log level.

    It seems, maybe I missed it, that using this feature disallows you from logging exceptions. For example, you can log a complicated string and the exception like so:

    logger.error("Oh no, thing '" + 
         thing + "' took down the system!", ex);
    

    Alternatively, you can use SLF4J’s message formatting to avoid the costly String manipulations, and just pass in the ‘thing’ object and anything else needed in the message as varargs:

    logger.error("Oh no, thing '{}' 
         took down the system!", thing);
    

    But, where to you chain in the exception that caused this?

    Solution?

    Add to the API:

    void error(String format, Throwable t, Object... arguments)
      Log an exception and message at the ERROR level according to the 
      specified format and arguments.
    
      This form avoids superfluous string concatenation when the 
      logger is disabled for the ERROR level. However, this variant 
      incurs the hidden (and relatively small) cost of creating an 
      Object[] before invoking the method, even if this logger is 
      disabled for ERROR. The variants taking one and two arguments 
      exist solely in order to avoid this hidden cost.
    
       Parameters:
           format    - the message accompanying the exception
           t         - the exception (throwable) to log
           arguments - a list of 3 or more arguments
    

    Then the log could have been done as:

    logger.error("Oh no, thing '{}' 
        took down the system!", ex, thing);
    

    But…
    Of course, I’m sure the developers of SLF4j, and other libraries that change their API to take advantage of varargs, have very good reasons for the resulting changes and “limitations”.

    Varargs should be used sparingly?
    One advice given in Java docs is:
    “… you should not overload a varargs method, or it will be difficult for programmers to figure out which overloading gets called”.

    Resources

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

    Enum to Switch on Class types in Java and Groovy

    The Java Switch statement is usually considered a code smell since it’s use can be eliminated by better use of Object Oriented Programming (OOP) design. Nowhere is this more apparent than with a related technique: attempting to switch on Class types by using the instanceof operator.

    Real world
    Unfortunately, in the real world, OOP is sometimes lacking. The code may be using a minimal interface based design. Refactoring, redesigns, or sophisticated OO legerdemain cannot be used in such a project. What’s worse, these projects typically have no unit tests.

    In this situation, one must resort to use of ‘switch’ or nested “if else”. This is a situation I recently encountered with legacy code that used if-else conditionals and instanceof since the target classes had no commonality. I was curious at the alternatives, so wrote up this blog post.

    Important! The examples here do not reproduce the actual usage of the instanceof, wherein inheritance is taken account. See this Stackoverflow article for some info.

    Groovy approach
    In Groovy this is much easier since the switch statement supports much more types to switch on. In listing 1 below we simply use the classes directly. Note that this is not documented anywhere, afaik.

    Groovy Example source
    Listing 1

    package com.octodecillion.experiment
    
    class GroovySwithOnClass {
    
        static main(args) {
            
            switch(Class2.class){
                case Class1.class:
                    assert false
                    break
                case Class2.class:
                    assert true
                    break
                case Class2.class:
                    assert false
                    break
                default:
                    assert false
            }    
        }
        
        public static class Class1{}
    
        public static class Class2{}
    
        public static class Class3{}
    
    }
    

    Now that is sweet and to the point!

    Just to see if possible, one could explicitly switch on a Closure’s hashCode as follows:

    class SwithOnClosure {
    
        static main(args) {
            Closure cl1 = {}
            Closure cl2 = {}
            Closure cl3 = {}
            
            switch(cl2.hashCode()){
                case cl1.hashCode():
                    assert false
                    break
                case cl2.hashCode():
                    println "on cl2"
                    assert true
                    break
                case cl3.hashCode():
                    assert false
                    break
                default:
                    assert false
            }
        }
        
    }
    

    For some more Groovy Enum goodness, the reading list at end gives some more examples.

    Java Approach
    In contrast to the Groovy used above, in Java things get more wordy. Below in listing 2 a JUnit class illustrates two methods of using a switch that acts on Class types.

    Java 7
    The method “testOnJava7” shows that in Java 7 the switch can be on String values, so we just use the fully qualified class name (FQCN) as the case labels. This is not optimal, of course, any change to package or class names would break the switch.

    Unfortunately, you can’t use the class name found by, for example, Class1.class.getName(), to use for the case labels. The case labels must be “constant expressions“. Even creating String “constants” with private final String CLASS1 = …. would not work, afaik.

    Tip: In Java 7 the switch works with:
    • char
    • byte
    • short
    • int
    • Character
    • Byte
    • Short
    • Integer
    • String
    • Enum type
     

    Java 6
    In Java 6, the ‘switch’ is more limited. In method “testOnJava6” we create an Enum ‘Switcher’ that stores the FQCNs of the classes to switch on. To allow the conversion of class name to enum we have to implement the ‘fromString(String className)’ method (learned this in “Effective Java”).

    Java Example source
    Listing 2

    package com.octodecillion.experiment;
    
    import static org.junit.Assert.fail;
    import java.util.HashMap;
    import java.util.Map;
    import org.junit.Test;
    
    /**
     * @author josef betancourt
     */
    public class SwitchOnClass {    
        @Test
        public final void testOnJava7(){        
            switch(Class1.class.getName()){        
                case "com.octodecillion.experiment
                    .SwitchOnClass$Class1":
                    break;                
                case "com.octodecillion.experiment
                    .SwitchOnClass$Class2":
                    fail();
                    break;
                case "com.octodecillion.experiment
                    .SwitchOnClass$Class3":    
                    fail();
                    break;
                default:
                    fail();                    
            }        
        }
    
        @Test
        public final void testOnJava6() {
            switch(Switcher.fromString(Class1.class.getName())){            
                case CLASS1:
                    break;
                case CLASS2:
                    fail();                
                    break;
                case CLASS3:
                    fail();
                    break;                
                default:
                    fail();            
            }        
        }
    
        /** enum type that stores the class names as field */
        public static enum Switcher{        
            CLASS1(Class1.class),
            CLASS2(Class2.class),
            CLASS3(Class3.class);    
            
            private static final Map<String,Switcher>classNameToEnum = 
                 new HashMap<String, Switcher>();
            
            static{
               for(Switcher sw : values()){
                    classNameToEnum.put(sw.className, sw);
                }            
            }
            
            /** convert class name to the enum type */
            public static Switcher fromString(String className){
                return classNameToEnum.get(className);
            }
            
            private String className;
            
            // constructor
            Switcher(Class<?> klass){
                this.className = klass.getName();
            }
            
        } // end enum Switcher
        
        public static class Class1{}
    
        public static class Class2{}
    
        public static class Class3{}    
    }
    

    Alternatives
    1. Don’t do any of the above. Use instanceof to invoke a method specific to the target class. In this way future maintenance and possible OO refactoring can be done. This is possible with the Enum use too, but may be using the Enum for the wrong reason.

    2. An alternative is to change the classes in question to partake in the enum use as shown by Gaʀʀʏ in a Stackoverflow article. This, imho, is not a good approach since it mixes concerns.

    3. Still another approach was suggested by a colleague: switch on the hash code of a class, this would remove the maintenance of an Enum just for use of an instanceof replacement.

    4. An interesting approach is to forgo the use of a switch altogether and just use the enum to invoke type specific behavior. A state machine? See “Avoid switch! Use enum!

    5. Use the Visitor Pattern. However, this assumes you have or can modify the existing classes.

    Updates
    Feb 13, 2014: Changed the format of the post.
    Feb 15, 2014: added example with closures.
    Nov 7, 2015: Interesting discussion on the Guava project, Issue 562, IfElse and Switch Functions. The OP suggested something that would a Predicate and allow multiway conditionals. The commentators said it was not “Java”, so won’t fix.

    Environment

    • Windows 7
    • Eclipse 4.3
    • Java 7
    • JUnit 4
    • Groovy 2.2

    Further reading

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.