Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

Ah Apache Velocity is something that I've always liked and we tend to make moderate use of it on a project I'm working on. So it was an off-chance that I happened to be looking at some code that was dealing with Velocity configuration that I noticed that custom directives are used all over the place instead of simple utility (or tool) classes. This wasn't a part of the code base that I was familiar with so thought there must be a reason for this choice.

Note: this article is based on Velocity 1.7 because that is the version in use. I know version 2.0 exists and it probably has a very different performance profile compared to what I have shown here. This exercise was more of an outside of work curiosity and not a full assessment of Velocity's performance.

Directives are harder to code and aren't very well documented. On the other hand utility/tool classes are documented and are an integral part in how Velocity is designed to be extended. So in my mind, going to the trouble of writing custom directives has only one purpose - performance gains.

So I set up a very simple test harness that would call merge() the same template 100 times. In one of the cases I made use of a utility/tool class and the other case used a custom directive. The only functionality that both of these had was to take an input string and output it as is.

This was the code for the harness (with the run*() calls commented out). Note that I made sure to start timing only around the merge() method, excluding VelocityContext population, though in reality this made little difference.
 Java
public class VelocityTest {
public static final void main(String[] args) {
VelocityEngine engine = new VelocityEngine();
engine.addProperty(RuntimeConstants.RESOURCE_LOADER, "class");
engine.addProperty("class.resource.loader.class",
ClasspathResourceLoader.class.getName());
engine.addProperty("class.resource.loader.cache", "true");
engine.addProperty("class.resource.loader.modificationCheckInterval", "0");
engine.loadDirective(MyOpDirective.class.getName());
for (int i = 0; i < 100; i++) {
/*runUtility(engine);*/
/*runDirective(engine);*/
}
}
private static void runUtility(VelocityEngine engine) {
StringWriter writer = new StringWriter();
Template template = engine.getTemplate("template1.vm");
VelocityContext context = new VelocityContext();
context.put("myOp", new MyOp());
context.put("var1", "Hello World");
long startTime = System.currentTimeMillis();
template.merge(context, writer);
System.out.println(System.currentTimeMillis() - startTime);
}
private static void runDirective(VelocityEngine engine) {
StringWriter writer = new StringWriter();
Template template = engine.getTemplate("template2.vm");
VelocityContext context = new VelocityContext();
context.put("var1", "Hello World");
long startTime = System.currentTimeMillis();
template.merge(context, writer);
System.out.println(System.currentTimeMillis() - startTime);
}
}


The utility class and its corresponding template looked like this. It doesn't get any simpler...
 Java
public class MyOp {
public String doSomething(String inpStr) {
return inpStr;
}
}

 Template 1 - Utility Class
#foreach ($number in [1..100])
$myOp.doSomething($var1)
#end


Continue reading...  

, , ,

It was over 5 years ago (5 years, 1 month and 29 days as Data would correct) that I wrote about assembling my Portabee 3D printer. Since then I've built a nice enclosure for the printer, modified it many times and even did an almost complete rebuild of it. Lately however it's been sitting outside on my balcony gathering dust and having other things piled on top of it...

IMG_0822.jpg

I decided that this was a clear sign that the 3D printer had to be disassembled (at least partially), its enclosure taken apart and for it to make space for something else that may come in its place. So I took it down and started...

IMG_0823.jpg
So Long, and Thanks for All the Fish


The enclosure had to be taken apart first since the printer was mounted inside. This itself had to be disassembled in a particular order to make it easier to get to everything. The front door was first to go.

IMG_0824.jpg IMG_0826.jpg


Continue reading...  

, , ,

When macOS High Sierra (10.13) was released, the telnet utility disappeared. This has probably been a good move by Apple since telnet is outdated and not a secure protocol; it shouldn't be used in general. However, telnet did serve a useful function - checking if it was possible to connect to a remote server on a particular port. Luckily there is a much better tool for this included in macOS - nc (netcat).
nc.png


Using nc is simple and it has command line arguments that are very similar to telnet. I like to use the -vz arguments whenever I need to check if a remote server can be reached on a particular port. These arguments make nc have this behaviour...
-v Have nc give more verbose output.
-z Specifies that nc should just scan for listening daemons, without sending any data to them.


The result is nc tries to connect to the server and then immediately terminates if it succeeds. Here's an example...
 nc output
> nc -vz 10.xxx.xxx.xx0 7002
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif en0
src 192.168.xxx.xxx port 61731
dst 10.xxx.xxx.xx0 port 7002
rank info not available
TCP aux info available
Connection to 10.xxx.xxx.xx0 port 7002 [tcp/afs3-prserver] succeeded!


Continue reading...  

, ,

This weekend I decided to put together the Optiumus Prime kit from Facinations/Metal Earth. It's part of their transformers range which also includes kits like Bumblebee (and Gold Bumblebee), Megatron and Soundwave. I was expecting this kit to be as difficult to put together as the Gundam Barbatos I assembled a few months ago but surprisingly it was significantly easier.

The end result was very cool...
DSC04454.JPG


This was a two-sheet kit. The instructions came on two separate sheets, which was usual for this size kit. Again my (minor) complaint as many other times was that the numbered part layout was on the first page and required flipping between it and the rest of the instructions multiple times (as can be seem in the assembly video). Apart from that the kit gave me no trouble and was very enjoyable to put together.
IMG_0780.jpg

IMG_0778.jpg IMG_0779.jpg


As usual I got my selection of tools to assemble this kit. That metal spatula was very useful and this time around I found that the scalpel really came in handy too.
IMG_0781.jpg


Continue reading...  

, , ,