My work machine runs Windows (go ahead and laugh. I’ll wait). While I’ve been able to tweak the machine and get a moderately acceptable setup, there are times when I’d really like to use Linux for something, so I spin up a virtual machine with VirtualBox. While that works, I don’t really like having source code — especially with changes in flight — on the VM, as it makes it a bit more dangerous/difficlt to destroy the VM should I need the disk space (which happens more often than I’d like). I set out, then to get shared folders working so I can keep the source on my host machine, and just do the work in the VM. Unfortunately, it doesn’t seem to be as simple as adding a shared folder to the VirtualBox config. This post, then, will detail the steps I took to make things work for me.
If you wrote software on a DOS system in the 80s or 90s, you probably used one of the Borland products, Turbo Pascal or Turbo C, with that beautiful, beautiful blue, mouse-enabled text-based user interface (TUI, if you will). Those IDEs were powered by a library called Turbo Vision (TV), which Borland documented and published for others to use. I loved it. While we all live in a GUI world and there are lots of libraries for building GUIS, I have for years now been dying to be able to use TV again, if for no other reason than hard core nostalgia. The problem being that I have used C in about 2 decades, and, to be honest, I’m not sure I’m too excited about writing even toy apps in the language. Dead end, right? Not so fast.
Enter, stage left: SWIG. SWIG, the Simplified Wrapper and Interface Generator, is a tool for building wrappers for libraries written in, say, C or C, for languages such as Python, PHP, and... Java. While it may not be the best option, it's an option, and I've been tinkering with it off and on for many, many moons now with the C version of the library open source by Borland long ago, before they were sold off and the Borland brand quietly disappeared. Tonight, I made great progress on it.
I’m currently working on a DSLs-in-Kotlin presentation for my local JUG, so I need a good domain in which to work. HTML is a great sample domain, but it’s been done to death. After a bit of head scratching, I’ve come up with what is, I think, a somewhat novel domain: REST application building. Sure, there are libraries like Ktor, but suffers from some very serious NIH. I’m totally kidding, but the dearth of discussions regarding REST applications and DSL construction was good enough for me, so let’s see what we have so far.
If you’ve been working with Java for very long, you’ve probably had occasion to use
String.format()
. And, if you’re like me, you may very well have been doing it "wrong".
Let’s take a look at what was, for me, common usage, and how, maybe, you should be
doing it.
I was recently on a business trip and, as is my custom, I took along my Roku box so that I would have something to watch in the hotel room in the evenings. Unfortunately, the hotel wifi required that you sign in on each device in order to access the internet, but this Roku is old enough that it didn’t offer way to do that. I found some options in The Tubes, but I didn’t care for them for various reasons, but, fortunately, I found an easy — and free — way to do what I needed.
The two options I found included buying a "travel router", which might have worked, but that required that I buy the device (they appear to be about $15), but I’m kinda cheap at times, and even if I weren’t, that didn’t help me much at 10:00 at night in the hotel room, so that was out. Another option involved downloading some software to a Windows machine, which, when run, would set up a small wifi network to which I’d connect my Roku. Since I have a Linux laptop, that would be a bit difficult, but, even in the Windows VM I have installed, it also required downloading and running software from a site I’ve not heard of, so I passed.
What I finally did was a very simple hack.
-
On the Roku, I looked at the network configuration and took note of the Mac address for the device.
-
On my laptop, I changed the Mac address of my wireless adapter
-
Disconnected and reconnected from the laptop to make the Mac address change take effect.
-
From the laptop, I authenticated on the hotel’s wifi network
-
Also from the laptop, disconnect the laptop’s wifi.
-
Clear the overridden Mac address and reconnected.
-
From the Roku, connect to the hotel wifi
-
Stream until I fall asleep
Wise or not, I recently made the move to Linux on my work machine. For the most part, it works wonderfully. For reasons that aren’t too terribly relevant here, I found myself needing (or wanting) to run the Windows version of Firefox. While I could run it successfully, it wouldn’t connect to the internet. After a whole lot of digging, I finally found the answer, which I thought I should document here with the hope that it will be easier for others to find (including me when I go through this again in a few years ;).
The culprit, it seems, is a couple of Firefox settings: browser.tabs.remote.autostart and browser.tabs.remote.autostart2
Once you have Firefox running under Wine, go to about:config in the browser, and enter remote.autostart in the Search box, and change the value of both settings to false:

Restart Firefox, and you should be golden.
For what it’s worth, credit where credit is due: this is the post that finally got me over the hump.
Today I found myself with a common problem: I had a delimited string of an unknown number of parts that that I needed split apart and process. Prior to Java 8, implementing that might looked something like this:
1
2
3
4
5
6
7
for (String part : string.split("\\n")) {
if (!myList.contains(part)) {
if (!part.isEmpty()) {
myList.add(part);
}
}
}
While that works and seems to be pretty efficient, I felt it could use a stream makeover, as I find the stream operations to be clearer and more concise. What I ended up with was something like this:
1
2
3
4
Pattern.compile("\\n")
.splitAsStream(string)
.filter(s -> !myList.contains(s))
.forEach( s -> myList.add(s));
I could also have used Arrays.stream()
rather than Pattern
:
1
2
3
4
Arrays.stream(string.split("\\" + DELIMITER))
.filter(s -> !myList.contains(s))
.filter(s -> !s.isEmpty())
.forEach(s -> myList.add(s));
I haven’t done any profiling to see if Pattern.compile()
has any non-negligible
performance impact versus String.split()
(and I probably won’t, but you can easily
"cache" the compiled pattern in an instance or static variable if needed :), but I will
point out this difference: when using split()
, streamed or not, we may get a blank
value in some situations, so we need to check for that (notice the calls to
String.isEmpty()
in both of those implementations). With the Pattern
-based
implementation, we don’t have that problem.
At any rate, there you have it: you can convert String.split()
to a stream-based
implementation fairly easily, and, I think, get more readable code out of it. Any
performance implications are left as an exercise for the reader. :)
Recently at work, we found an odd scenario with a REST (-ish ;) endpoint from another team: If the request provided a list of, say, 11 IDs in the query string, the system would only return information on the first 10 of them, silently dropping anything over that seemingly odd limit. The initial reaction was of, course, "Well, let’s just increase the limit." To be honest, I had the same reaction, but then I remembered one of my favorite quotes, known as Chesteron’s Fence:
In the matter of reforming things, as distinct from deforming them, there is one plain and simple principle; a principle which will probably be called a paradox. There exists in such a case a certain institution or law; let us say, for the sake of simplicity, a fence or gate erected across a road. The more modern type of reformer goes gaily up to it and says, "I don’t see the use of this; let us clear it away." To which the more intelligent type of reformer will do well to answer: "If you don’t see the use of it, I certainly won’t let you clear it away. Go away and think. Then, when you can come back and tell me that you do see the use of it, I may allow you to destroy it."
Chesterton’s context, politics in Great Britain of the 1920s, is, of course, quite different from a software development shop almost 100 years later, but the message is still extremely appropriate: Before you go tearing things down or otherwise changing something you’ve found, you really need to understand not only what you’re changing, but why it was made that way in the first place.
In the case of this REST call, we should ask questions like
-
Are there system load concerns, such as memory or processing time?
-
Are there concerns about the on-the-wire response size?
-
Was there an explicit Product Management decision to set the limit this low for business reasons we don’t see reflected in the code?
And so on. Until we can answer those questions (or reasonably rule them out as irrelevant), we need to be very hesitant in making the change. Once we’ve explained the original developer(s) built that fence, then we can talk about ripping it down.
As the title states, my book has finally been published. You can get it (and you know you want to) at a number of places:
I had fun and learned a lot while working on this. I hope you find it useful.
I recently struggled trying to text in a JavaFX ListView to wrap inside the container like I asked it to, rather than extend (and disappear) past the boundaries of the container. After some discussion on Twitter and a bit of Googling, I found an answer that I thought I’d share here to, perhaps, save someone some time.