TIL: Java stuff

Java Lambda as parameter

First you need an interface

    private interface Ec2Operation {
        void apply(Ec2Client ec2, String... instanceId);
    }

Then declare the operation (note that you don’t need to define “apply”, just use the interface name. “apply” can actually be anything, as you’ll call it later

Ec2Operation startInstance = (ec2, instances) -> {
StartInstancesRequest request = StartInstancesRequest.builder()
.instanceIds(instances)
.build();
ec2.startInstances(request);
};

Then use it with the interface as a signature, call the function you named

private RequestResult executeEc2Operation(Ec2Operation operation) {
    operation.apply(client, instances);
}

Then call the lambda as parameter in a third function

    public RequestResult start() {
        return executeEc2Operation(startInstance);
    }

Having to declare the interface explicitly makes it much more verbose than Javascript. However you get the benefit of a strong type.

Scala and Go’s approach is probably the best of both worlds: you just need to declare the type in the lambda itself.

SSH library for Java

JSCH is the first result in Google. However it hasn’t been updated in along time and doesn’t support newer algorithms.

SSHJ seems to be a more modern choice. It’s on github too!

TIL: When finally Is Executed

In short, finally overrides some of the “expected” behavior like returning from the try – catch block, allowing you to free up resources / do clean up regardless of whether there was an error or not

No Exception Is Thrown

When the try block completes, the finally block is executed, even if there was no exception:

try {
    System.out.println("Inside try");
} finally {
    System.out.println("Inside finally");
}

In this example, we aren’t throwing an exception from the try block. Thus, the JVM executes all code in both the try and finally blocks.

This outputs:

Inside try
Inside finally

Exception Is Thrown and Not Handled

If there’s an exception and it is not caught, the finally block is still executed:

try {
    System.out.println("Inside try");
    throw new Exception();
} finally {
    System.out.println("Inside finally");
}

The JVM executes the finally block even in the case of an unhandled exception.

And the output would be:

Inside try
Inside finally
Exception in thread "main" java.lang.Exception

Exception Is Thrown and Handled

If there’s an exception and it is caught by the catch block, the finally block is still executed:

try {
    System.out.println("Inside try");
    throw new Exception();
} catch (Exception e) {
    System.out.println("Inside catch");
} finally {
    System.out.println("Inside finally");
}

In this case, the catch block handles the thrown exception, and then the JVM executes the finally block and produces the output:

Inside try
Inside catch
Inside finally

Method Returns from try Block

Even returning from the method will not prevent finally blocks from running:

try {
    System.out.println("Inside try");
    return "from try";
} finally {
    System.out.println("Inside finally");
}

Here, even though the method has a return statement, the JVM executes the finally block before handing the control over to the calling method.

We’ll get the output:

Inside try
Inside finally

Method Returns from catch Block

When the catch block contains a return statement, the finally block is still called:

try {
    System.out.println("Inside try");
    throw new Exception();
} catch (Exception e) {
    System.out.println("Inside catch");
    return "from catch";
} finally {
    System.out.println("Inside finally");
}

When we throw an exception from the try block, the catch block handles the exception. Though there is a return statement in the catch block, the JVM executes the finally block before handing control over to the calling method, and it outputs:

Inside try
Inside catch
Inside finally

From https://www.baeldung.com/java-finally-keyword

Troubleshoot running JMeter programmatically

Resolving “Could not find org.apache.jmeter:bom”

With the release of the v5 of the JMeter library comes a bug. When you include JMeter gradle will complain that it “Could not find org.apache.jmeter:bom”. To resolve this, edit build.gradle to say

// There's a bug in JMeter leaving extra metadata right now. This is a workaround
class JMeterRule implements ComponentMetadataRule {
    void execute(ComponentMetadataContext context) {
        context.details.allVariants {
            withDependencies {
                removeAll { it.group == "org.apache.jmeter" && it.name == "bom" }
            }
        }
    }
}

dependencies {
    implementation group: 'org.apache.jmeter', name: 'ApacheJMeter_core', version: '5.3'
    implementation group: 'org.apache.jmeter', name: 'jorphan', version: '5.3'

    components {
        withModule("org.apache.jmeter:ApacheJMeter_core", JMeterRule)
        withModule("org.apache.jmeter:ApacheJMeter_java", JMeterRule)
        withModule("org.apache.jmeter:ApacheJMeter", JMeterRule)
        withModule("org.apache.jmeter:jorphan", JMeterRule)
    }
}

Installing subversion support for Eclipse on Linux

You have two choice: subversive (Belongs to the Eclipse project) or subclipse (hosted on tigris.org).

Even though Subversive is the more ‘official’ option, I find it prohibitively confusing to install. You have to go to an external site (polarion) and download a bunch of stuff nobody told you what. It took me 2 hours fiddling back and forth between Eclipse site and Polarion site only to install the wrong stuff. Highly not recommended! Agrh!

I have a better start with subclipse. The only URL from their site worked perfectly with eclipse’s ‘install new software’ dialog. Better still, you don’t really need to install JavaHL (which is also¬†ridiculously¬†hard to install), you can use the SVNKit package in the same repository and everything will work.

To install subclipse, go here

 

For those of you who prefer JavaHL, here is how to install JavaHL on Fedora 16. JavaHL is another middle layer required between any Eclipse plugin and SVN (I don’t know why things are so complicated when it come to designing on Linux). Most of the sites on the internet recommends you to install that by

sudo apt-get install libsvn-java

But there is no such package on Fedora, so I tried to use add/remove software and searched for various part of the name. I finally found it when searching for ‘JavaHL’, the correct package name is

subversion-javahl

Documentation and tutorial and another thing the Linux community didn’t do well!

Resolving ClassCastException using ADT’s visual designer

Recently when maintaining an old android program I encountered a strange exception when attempting to view a layout in visual designer:

error!
ClassCastException: com.android.layoutlib.bridge.MockView cannot be cast to android.view.ViewGroup
Exception details are logged in Window > Show View > Error Log
The following classes could not be found:
- TableLayout (Change to android.widget.TableLayout, Fix Build Path, Edit XML)

Searching stack overflow and Android developers, I found this could be caused by using an old version SDK for an application targeted to a newer version, with new elements. But TableLayout was available since API level 1, and I’m using the latest version of the development tools, so these could not be the problem. The temporary fix was to remove the table layout and replace it with something else.

Today I have the time to compare my code to Android’s example. It turned out to be one tiny little thing that messed the designer up:

<TableLayout

			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:orientation="vertical"
			android:stretchColumns="">

There, one attribute doesn’t match the schema (it should be 0 or 1, not empty “”), and the designer will refuse to load. Worse still, the code will compile but will crash at run-time for the same reason.

My recommendation? Android team should note this case and provide better details on the loading exception in upcoming versions. “ClassCastException” is not really helpful!