Archive for the ‘JavaSE’ Category

Java app bundle on OS X

Quarta-feira, Fevereiro 27th, 2013

I have a complex project running in one of our biggest clients (one of the best worldwide in it’s area), and the deploy machines are all Apple.

Since my software is written in Java, it runs on every OS under the Sun (oh my…), but on the Mac you really want to go the extra step and integrate nicely with OS X.

So I picked up my app and created an Application Bundle. I love the concept: a simple directory structure, a couple of XML files, and your data. Install and uninstall is a simple drag-and-drop affair. Every OS should have a similar concept; it might not be the best strategy mass-storage-wise (and Apple now recommend you ship your app with the JRE “integrated”, ouch), but it’s so simple and innocuous, it almost slaps you in the face. I’ve actually touched this subject in this post. Kinda of reminds me of AmigaOS 3: the OS was all modular (datatype files, etc), and app installs/uninstalls were also a drag-and-drop affair.

Then I hit a wall: I don’t actually know what command the JavaApplicationStub will run, and my RMI server was not being launched properly (I need to specify the hostname for RMI as a Java property). But, as always, a simple look at Apple documentation and the thing is working great (it required a simple fine-tuning of the Info.plist XML file). Apple might not be the be-all and end-all company on this planet, and you know Apple is not exactly in love with Java anymore these days, but for me they always came through with a solution.

Hot Swap

Sábado, Janeiro 7th, 2012

One thing I’ve been absolutely jealous of the PLC world is the ability to hotswap DataBlocks, FCs, etc. I mean, while the PLC is running and executing code, you can simply upload a modified version of an FC (basically a function) and… it just works. The PLC (once the upload is completed) changes the function pointer to the new code between cycles, and all is well.

Obviously, PLCs are rather simple functional machines, they basically work with static memory blocks (for variables and functions) and with a very rigid structure (IN/OUT image management, main cycle). So it’s very easy to achive the hotswapping of functions, and even of variable blocks (you basically refer to a variable by it’s address; if you’re not carefull changing a varible block, you might be now pointing to some address that encompasses parts of two variables… it does not complain).

When you mainly roam on Java land, like I do, the sights change dramatically. Sure, you have an immense power on your hands, but think about class hierarchies, objects, constructors, third party libraries… and it’s very far from trivial to implement hotswapping in the Java Virtual Machine.

I’m using Java to build my most important “desktop” applications (actually, it’s a server-client aproach, but the server app is 100% built by me, no third party web or app servers involved), and sometimes I’d like to have hotswapping on my development system. It really bugs me to have to bring down my server app because of a simple bug fix or improvement.

Still, after reading a bit on HotSwap, JRebel and the like, it probably is not that important. I’m not willing to add significant amounts of complexity just to gain hotswap, since I’ve developed things with a very lightweight and encapsulated structure. On recent hardware and JRE, my server app starts up in 8 seconds (database startup included), and the client app in a mere 4 seconds. Even with a full recompile and shutdown times, I’m looking at a power cycle of under 30 seconds. Not bad.

Software : How it should NOT be done

Quarta-feira, Julho 8th, 2009

It’s impressive how some big name software developers still are so complaisant with utterly absurd limitations. This is a screen capture of the installation of a big industrial brand software for configuring their measuring hardware (fluid flow, level, temperature, etc).

“This will change your system permanently. While installing system components your computer may restart without warning.”

Now, there’s something to reassure a computer user. Come on, there has got to be a better way to build software! If that means breaking with Windows rules and traditions, so be it.

In my point of view, this is crippled software that cripples a computer. What it says is: “I’m irreversively modifying your computer system, as I grab hold to it, and scatter parts of my entity throughout my new domain. Oh, and I will shutdown and restart it as my whims dictate. You have no choice in any of this, for you have purchased my hardware, and I command. You obey.” This is beyond weird, it’s creepy.

I’m also a software developer. My software is built with user friendliness in mind, be it in installation, use, or removal.

* Install: just copy a file or folder wherever you want.
* Use: just run the executable file. The application is as intuitive as possible.
* Uninstall: just delete the original file or folder. No traces are left on your system.

As simple as that, and I use this method in all my apps. This works for the user and for the developer, because deploys are simple, *very* quick, and can be done by just about everyone.

Now that I think of it, this method is similar to what the majority of Mac applications use (even though they usually leave some (innocuous) preferences files behind).

OPC - OLE (Open?!) Process Control

Segunda-feira, Março 9th, 2009

In my industrial meanderings, I’ve been using some I/O modules for wich I write device drivers (for my data layer abstraction). One of these involves the OPC protocol (OLE for Process Control). It’s actually a pretty good ideia (badly implemented).

The ideia is that all data devices should be easily accessible by a standard communications protocol. There’s the ideia of an OPC server, an application that connects to the devices and exposes their data on the OPC protocol. Then, an OPC client connects to these servers and reads/writes on those devices. The problem is that they based OPC on a Microsoft-only (thus Windows-only) technology, DCOM. DCOM has a history of being difficult and picky to configure remote access and, because of this, almost nobody goes to the length (and risk) of configuring a system remotely (permissions problems, etc), and clients and servers are usually run on the same machine (defeating half the purpose).

Still, the ideia is too good to let go, and there are OPC servers for almost everything on the market. Getting OPC to work was one of my first projects at work, but since I write almost everything in Java (so that it runs on Windows, Mac and Linux) I had to find a way to get access to OPC from Java.

Back then, I developed a small TCP/IP proxy, socket-based, with a simple ASCII protocol, on Visual Basic (using the native OPC DLL). It not only brought along the lost OPC purpose (distributed access), but I could have access from just about anything (Java, Ruby…). Still, it was slow, configuration was local, and it did not implement all of the OPC protocol.

Later, I found almost exactly what I was looking for: a couple of companies were proposing JNI-based Java wrapper libraries, giving access to OPC. The problem: they cost as much as the OPC server (about 600 Euro) and, just like the server, I had to purchase one library license for each deployment.

I never understood this business model; I would hapilly buy the library once and deploy to my hearts content, as this would probably be cheaper than developing the library myself (I do this with JFreeChart, for example). But if I have to pay for every deployment this is simply not economical, since with the money of 2 or 3 deployments I was definitely able to develop the library from scratch. I was seriously thinking of developing the library myself and selling it with JFreeChart’s business model (I had no competition anyway), until I found JEasyOPC.

Antonin Fisher developed an OPC wrapper library based on JNI (and Delphi) and offered it with a LGPL license. I’m testing the library now and it seems to perform very well on Java 5. It crashes on Java 6 though (apparently due to multithreaded issues).

If Antonin ever gets around to fix this issue on Java 6, we’ll have a winner! :)

WayTooSimpleDateFormatToBeBelieved

Terça-feira, Janeiro 20th, 2009

Why is it always the things that are supposed to be simple that come around and byte you in the behind? In my present (Java) project (a quasi-real-time data aquisition and archiving module), I had a SimpleDateFormat for parsing and formating dates in UTC format. Things were all cute and sweet, until I got more than one client loading the server. Then, all hell broke loose on the dates that got to the tags; here’s an example:

 

2008-07-14 10:33:52,valor_calculado1,40.0,1

2008-07-14 10:33:52,SetPointZito0,14.42,1

2008-07-14 10:33:52,SetPointZito1,50.0,1

2008-07-14 10:27:25,Posição do elevador A17,43,1

2040-01-31 10:27:00,Freq. oscilacao da plataforma A17,8,1

0037-01-01 00:27:00,Valvula IN 01V001 A50,0,1

2008-07-01 00:00:00,Valvula IN 01V004 A50,0,1

2008-06-30 00:00:00,Pressao Vapor Caldeira A17,1.256,1

2008-01-01 10:00:55,Consumo - Agua da Rede A17,3.74,1

2008-07-14 10:27:58,alarmezecovisual0,1,1

2008-07-01 00:00:00,valor_calculado0,10.25,2

2008-01-14 00:28:00,alarmezecovisual1,1,1

2008-07-14 10:28:00,valor_calculado1,25.0,1

2008-07-14 00:00:00,SetPointZito0,20.25,1

2008-01-01 10:28:25,SetPointZito1,35.0,1

2008-07-14 10:33:58,Posição do elevador A17,26,1

2008-07-14 10:33:58,Freq. oscilacao da plataforma A17,-20.0,2

2008-07-14 10:33:58,Valvula IN 01V001 A50,0,1

 

This is supposed to be the transition from 2008-07-14 10:33:52 UTC to 2008-07-14 10:33:58 UTC, but as you can see there are a lot of bogus dates in between… the problem was a transient one (and darn difficult to track down), apparently the SimpleDateFormat class is not Thread-safe (I have 7 different work threads on this baby, not counting the dynamic RMI ones of course). Oh, oh, wait, what’s this on the SimpleDateFormat API docs?

 

Synchronization

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

 

RTFM situation, I guess. Oh well.