Below you will find pages that utilize the taxonomy term “Java”
Fun with Java Backwards Compatibility
There’s a fun little gotcha introduced in Java 10 which causes trouble for anyone wanting to support earlier JVMs. If you take the code:
import java.nio.ByteBuffer;
public class ProblemCode {
public static void main(String[] args) {
final ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.position(10);
System.out.println("Yay it worked!");
}
}
If you compile it on Java 8 it will run on any Java from 8 and above. If you compile it on Java 10 or above it will only work on Java 10 and above, even if you specify -target 8 -source 8
.
Alert Dialogs Do Not Appear When Using WebDriverBackedSeleniu
With Selenium 1, JavaScript alert and confirmation dialogs were intercepted by the Selenium JavaScript library so they never appeared on-screen and were accessed using selenium.isAlertPresent(), selenium.isConfirmationPresent(), selenium.chooseOkOnNextConfirmation() and similar methods.
With Selenium 2 aka WebDriver, the dialogs do appear on screen and you access them with webDriver.switchTo().alert() which returns an Alert instance for further interactions.
However, when you use WebDriverBackedSelenium to mix Selenium 1 and WebDriver APIs – for example, during migrations from one to the other – the alerts don’t appear on screen and webDriver.switchTo().alert() always throws a NoAlertPresentException. This makes migration problematic because selenium.chooseOkOnNextConfirmation() doesn’t have any effect if the next confirmation is triggered by an action performed directly through Web Driver.
Testing@LMAX – Introducing ElementSpecification
Today LMAX Exchange has released ElementSpecification, a very small library we built to make working with selectors in selenium/WebDriver tests easier. It has three main aims:
- Make it easier to understand selectors by using a very English-like syntax
- Avoid common pitfalls when writing selectors that lead to either brittle or intermittent tests
- Strongly discourage writing overly complicated selectors.
Essentially, we use ElementSpecification anywhere that we would have written CSS or XPath selectors by hand. ElementSpecification will automatically select the most appropriate format to use – choosing between a simple ID selector, CSS or XPath.
The Single Responsibility Principle (and what’s wrong with it)
Marco Cecconi – I don’t love the single responsibility principle:
The principle is arbitrary in itself. What makes one and only Reason To Change™ always, unequivocally better than two Reasons To Change™? The number one sounds great, but I’m a strong advocate of simple things and sometimes a class with more reasons to change is the simplest thing. I agree that we mustn’t do mega-classes that try to do too many different things, but why should a class have one single Reason To Change™? I flatly disagree with the statement. It’s not supported by any fact. I could say “three” reasons and be just as arbitrary. Interesting critique of the single responsibility pattern. The quote above is perhaps one of the weaker arguments against the single responsibility pattern but it struck a nerve with me because all too often we assume that because a rule sounds good it has some validity. In reality, picking one responsibility for a class is quite arbitrary and, as the article argues, deciding what a responsibility is is even more arbitrary.
Javassist & Java 8 – invalid constant type: 15
Here’s a fun one, we have some code generated using javassist that looks a bit like:
public void doStuff(byte actionId) {<br /> switch (actionId) {<br /> case 0: doOneThing(); break;<br /> case 1: doSomethingElse(); break;<br /> default: <br /> throw new IllegalArgumentException("Unknown action: " + actionId);<br /> }<br />}
This works perfectly fine on Java 6 and Java 7 but fails on Java 8. It turns out the problematic part is "Unknown action: " + actionId
. When run on Java 8 that throws “java.io.IOException: invalid constant type: 15” in javassist.bytecode.ConstPool.readOne.
Why Are My JUnit Tests Running So Slow?
This is mostly a note to myself, but often when I setup a new Linux install, I find that JUnit tests run significantly slower than usual. The CPU is nearly entirely idle and there’s almost no IO-wait making it hard to work out what’s going on.
The problem is that JUnit (or something in our tests or test runner) is doing a DNS lookup on the machine’s hostname. That lookup should be really fast, but if you’re connected to a VPN it may search the remote DNS server which takes time and makes the tests take much longer than they should.
Background Logging with the Disruptor
Peter Lawrey posted an example of using the Exchanger class from core Java to implement a background logging implementation. He briefly compared it to the LMAX disruptor and since someone requested it, I thought it might be interesting to show a similar implementation using the disruptor.
Firstly, let’s revisit the very high level differences between the exchanger and the disruptor. Peter notes:
This approach has similar principles to the Disruptor. No GC using recycled, pre-allocated buffers and lock free operations (The Exchanger not completely lock free and doesn’t busy wait, but it could)
The Single Implementation Fallacy
As my colleague and favorite debating opponent Danny Yates noted:
We got into a bit of a debate at work recently. It went a bit like this:
“Gah! Why do we have this interface when there is only a single implementation?”
(The stock answer to this goes:) “Because we need the interface in order to mock this class in our tests.”
“Oh no you don’t, you can use the FingleWidget [insert appropriate technology of your mocking framework of choice here – e.g. JMock ClassImposteriser]! I’m smarter than you!”
Abstracting Acceptance Tests
For the past three months I’ve been settling into my new role with LMAX developing a high-performance financial “exchange”1{#footlink1:1301173295622.footnote}, hence the silence on the blog lately. One of the things I’ve found extremely impressive about LMAX is the impressive acceptance test coverage and the relative ease with which they are maintained. Normally as a set of acceptance tests gets to be extremely large they can become an impediment to being agile and changing the system since a small change to the UI can affect a large number of tests.
Apple-Scented Coffee Beans are Accurate
So Apple have announced that they will be contributing large swaths of code to the OpenJDK project and that from Java 7 onwards, Java will be a separate download from Oracle, much like Flash is now a separate download from Adobe. This really shouldn’t be unexpected for anyone who was paying attention to what was going on rather than just running around thinking the sky was falling.
This is fantastic news for Java developers of all types. Mac Java developers have been asking for Java to be separated from the OS for many, many years so that multiple versions of Java are more manageable and especially to decouple Java releases from the OS release timeline.
On the DVD vs in Software Update
James Turner gives a week in review and mentions the deprecated Java on OS X issue1{#footlink1:1288187415254.footnote}. One thing to correct:
Deprecation basically means that neither package will be delivered as part of the installation DVDs, and updates will not come via the Apple update mechanisms. It doesn’t mean they won’t be available anymore, it just means you’ll have to download them directly from Oracle and Adobe. Firstly, there’s nothing to suggest that Java won’t come from Apple but not be part of the standard OS X package.
Reading the Apple-Scented Coffee Beans
It’s interesting to see how many people are jumping to conclusions around the very carefully worded deprecation notice for Java in OS X. Read it carefully and pay careful attention to what it actually says:
As of the release of Java for Mac OS X 10.6 Update 3, the Java runtime ported by Apple and that ships with Mac OS X is deprecated. Developers should not rely on the Apple-supplied Java runtime being present in future versions of Mac OS X. Most notably the note only refers to the Apple ported JVM that ships with OS X. This leaves the door open for an Apple ported JVM that ships as a separate download and for a non-Apple JVM that ships with OS X.
FireFox is Picky About Clipboard HTML, Java is Sloppy
Windows uses a particularly ugly format for putting HTML on the clipboard, called CF_HTML. Basically, it adds a header to the content with pretty useless information essentially declaring how many bytes in the header (and yes you have to pad the byte counts since they themselves are included in the count).
The problem between Java and Firefox is that Java always sets the ‘StartHTML’ and ‘EndHTML’ fields to -1 to indicate there is no context and Firefox will refuse to paste HTML from the clipboard if StartHTML or EndHTML is set to -1. As such, if you copy HTML from Java it will be impossible to paste into Firefox. It works perfectly with Word and IE.
Java AWT Robot and Windows Remote Desktop
Problem
If you’re attempting to use the Java AWT Robot to help automate tests, you may find it convenient to log in via remote desktop to watch the tests execute and verify they work well. You may also find that they work fine while you’re watching them but then inexplicably start failing whenever you aren’t. Basically your test is an angel from Dr Who.
What’s most likely happening is that when you disconnect from the remote desktop session, the console on the Windows box is left in a locked state and you need to enter the user password before you can resume interacting with programs on the main display. Since the AWT Robot is doing a very effective job of acting like a user, it also can’t interact with the programs you’re intending and instead is interacting, probably quite ineffectively, with the login dialog box.
Returning Parameters in JMock 2
If you have a method like:
String getParameter(String name, String defaultValue)
where defaultValue is returned if the parameter isn’t specified, it can be challenging to get the right behavior in JMock without just hard coding what the defaultValue should be. Fortunately, a custom match which doubles as an Action can solve this pretty easily:
import org.hamcrest.*; import org.jmock.api.*; public class CapturingMatcher<T> extends BaseMatcher<T> implements Action { public T captured; public boolean matches(Object o) { try { captured = (T)o; return true; } catch (ClassCastException e) { return false; } } public void describeTo(Description description) { description.appendText("captured value "); description.appendValue(captured); } public Object invoke(Invocation invocation) throws Throwable { return captured; } }
It can then be used like:
Show Me the Metrics
There’s been a lot of new innovations going on in programming languages and development techniques in general lately, but there’s a really key missing element: metrics.
Seeing posts like Stephan Schmidt’s Go Ahead: Next Generation Java Programming Style and the response from Cedric Otaku really should make any professional software engineer concerned about the future of their craft. Not because either of them are necessarily right or wrong, but because two highly skilled engineers are engaged in debate based purely on pure personal preference. There’s barely even any anecdotal evidence provided, let alone actual measurements to see what impact on productivity, quality or other desirable qualities the proposed approaches have.
Better File System APIs
Dylan complained about the lack of testability with file system APIs, which reminded me of a neat looking library I stumbled across while looking at build systems: EntityFS. Among a bunch of other useful sounding things it provides:
File system APIs are backend-independent. File systems can be created in RAM memory, on Zip files, on file system directories, etcetera Sadly it’s under the LGPL which makes it difficult if you happen to sell to big enterprises that are still somewhat scared of GPL type licenses, but they’re nowhere near as common as they used to be. I should note though that Holocene Software are offering commercial licenses for an undisclosed price.
The New Cross Platform
When I first started professional programming, Java was reasonably young and was being hailed as a work of genius with it’s cross platform deployment capabilities. Programming was going to be revolutionised forever and all programs would run on any OS1{#footlink1:1253859827521.footnote}. Then Java wound up being most popular on the server side and liberated server code from the choice of OS more than the desktop side2{#footlink2:1253860194622.footnote}.
Server OS’s started to compete mostly on how well they were a server rather than what programs ran on them because what really mattered was that you could run the Java stack. In other words, Java became the platform that people deployed their applications to. It shouldn’t come as a surprise that a single platform didn’t stand unchallenged for long. .NET sprang up as the big enterprise competitor to Java and all of a sudden you had to choose sides again.
I Love Parser Generators, I Hate Parser Generators
I was reminded on the weekend of how much I like working with parser generators – they’re just so pure and clean. You really feel like you’re working with a grammar and all those CS lectures come flooding back. Writing code to parse the same content by hand just never has that feel. Plus they create incredibly accurate parsers in very little time at all.
Install the MSN Toolbar With Java?
So Microsoft has provided handy instructions for upgrading Java which is nice of them – especially since IE 8 doesn’t play nice with versions of Java before 1.6.0_11. Step 6 suggests installing the MSN toolbar along with Java though:
In addition to Java, you can also install the MSN Toolbar. The MSN Toolbar offers headlines, news alerts, and search tools from Microsoft. For more information see the MSN Toolbar home page. To install the toolbar, click the Terms of Use or Privacy Statement buttons and then read the statements. If you don’t want to install the toolbar, clear the Install the new MSN Toolbar check box. The odd thing is, last time I installed Java (this morning) it was the Yahoo toolbar that Java tried to install along the way. I guess Sun will give kick backs to whoever sends them traffic…
Debugging Deadlocks – Print All Stack Traces
One of the hardest types of bugs to track down is a deadlock situation. They are very time dependant which makes them intermitten, specific to a particular computer and configuration and generally impossible to reproduce in a debugger. Fortunately, at least in Java, it’s fairly easy to spot most of the situations where a deadlock is possible:
- Calls to SwingUtilities.invokeAndWait
- Calls to Object.wait()
- synchronized blocks
There might be a few others depending on the libraries you’re using, but starting with those three, in that order, is very likely to lead you to at least one point in the deadlock. Just put an old fashioned System.err.println before and after each of those calls and you’ll quite quickly see where things are waiting forever.
Loading PICT Images In Java
Since the search function for Apple’s mailing lists is pretty much useless, I’m making a note of the Reading PICT Images thread which contains numerous options for rendering PICT images in Java on OS X.
java.net.URL Timeouts
If your application uses java.net.URL, and chances it does are very high, and you are using Sun’s JVM (since 1.4.2), you should set the
sun.net.client.defaultConnectTimeout
andsun.net.client.defaultReadTimeout
system properties to a reasonable value. Otherwise, if a remote site hangs, your application or server will also hang. Useful to know…
ComponentOrientation and Right To Left Languages
For some time, we’ve had an Arabic translation in EditLive! and the editor pane itself fully supports bidirectional text, but we’ve never updated the UI to flip over to a mirror image when a right to left language is in use. Java actually has pretty reasonable support for this via the ComponentOrientation property in AWT (and inherited through to Swing) but there are a couple of annoying limitations:
- It applies on a per component basis, so there isn’t a single place you can apply the orientation and be done with it.
- Various components still don’t flip, eg JSplitPane.
- The Aqua L&F on OS X has some annoying bugs when in right to left mode.
For the first issue, you can use applyComponentOrientation which will automatically traverse the component hierarchy and make the changes but it still misses things like combo box renderers, dialogs or components that are generated later. For an application that loads its UI incrementally instead of blocking the swing thread while it loads in one go this is a significant annoyance. Even beyond that, all the dialogs need to be updated as well. While it is good that you can override the orientation on a per-component basis, it seems more intelligent to have a simple way to change the default value in one place without all the work.
Kudos To Landon Fuller
With all the complaining about Apple not having shipped JDK 6 with Leopard it’s nice that someone has actually stopped whining and started coding. So kudos to Landon Fuller for actually doing something useful. Of course, he hasn’t really gotten anywhere because porting Java is an awful lot of work, but if nothing else he’ll understand why it takes Apple so long.
It also means we can start the timer to see if the open source model can actually bring Java 6 to OS X faster than Apple can.
Java 5 on Leopard
The rumors of Java 5 being horribly broken beyond all usability on Leopard are, quite frankly, bullshit. It’s faster, has better integration with the OS, the Aqua L&F is significantly improved, it has full support for 64 bit and a huge raft of bug fixes and miscellaneous improvements. Everyone’s pointing to an uninformed rant on JavaLobby which as it’s key example actually highlights a major improvement to the Aqua L&F – the JOptionPane icons should use the application icon, not some obscure artwork that’s not used anywhere else in the system. The new dialogs actually allow you to look more like native app, not less. It’s even explained in the release notes – heck, the old implementation was probably reported as a bug against Tiger.
Java On Leopard
I was silly enough to open my work email this morning, only to discover that the Apple Java-Dev list had broken out into the age old Java on OS X argument. First up here’s what people have reported1:
- Java 6 is not included with Leopard.
- The previous Java 6 DP which was pulled from ADC a while back does not run on Leopard.
- Upgrading to Leopard from a system with the Java 6 DP installed can cause some frustrating issues with switching Java versions.
- Apparently Java 5 is much faster on Leopard.
- Java 5 looks different with quite a few tweaks to the Aqua L&F.
- Some fonts don’t look right in Java 5 on Leopard because it uses the Sun 2D graphics pipeline instead of the Quartz pipeline. The Sun 2D pipeline doesn’t support sub-pixel antialiasing. You can override the default and there’s a few other conditions that trigger the Quartz pipeline to be used by default.
- Java 5 supports 64bit on Intel Core 2s (but not PPC). There seemed to be some problem with it when using the Java tools in /usr/bin though – can’t say I followed that discussion too carefully.
- Lots of documentation is coming, but not much is available yet.
Pretty sure that’s the Java on Leopard wrap up, the other 150 emails to the list were just the usual gnashing of teeth about Apple abandoning Java and how Apple will lose so much business if they don’t get Java 6 out yesterday etc etc etc. Of course, Apple’s doing better than it ever has before and JavaOne was full of people using Macs – without Java 6 – so it would seem it’s all just talk and insignificant numbers of people are actually leaving OS X. As a fresh twist, this time round people are talking of porting OpenJDK to OS X themselves and finally freeing themselves from the evil clutches of Apple! Apparently no one has told them that Java 6 isn’t available from OpenJDK either – it will become Java 7 and is quite some way from that yet. I think it’s a safe bet that Apple will have Java 6 out long before even a reasonable uncertified port of OpenJDK is available for OS X.
Tomcat Startup Issues
I was so close to having everything working… EC2, S3, automatically pulling down the latest build and deploying it, Tomcat 5.5 with the native APR libraries, SSL support and using iptables to forward ports 80 and 443 directly over to Tomcat. Everything ready to go. Except Tomcat isn’t so keen on starting.
It usually starts, though it can take over half an hour to do so and on a couple of occasions it’s just flat out sat there and done nothing for multiple hours on end. At startup it outputs the log message:
Solr Is Cool
I’ve struggled with Lucene before and failed to configure it properly resulting in absolutely horrendous search results so a recent need to implement search functionality wasn’t something I particularly wanted to take on. In fact, I was prepared to do almost anything to avoid delving back into Lucene filters and parsers and tokenizers and “stuff”. This tends to be problematic given that Lucene is the dominate search library – so popular in fact that it’s been ported to other languages.
PermGen Nightmares
That permanent generation had better provide some pretty damn amazing optimizations or I’m going to add it’s inventor to my list of people to track down and torture at next JavaOne. It turns out you can only reload a Tomcat webapp so many times before the PermGen space fills up and everything dies. That’s annoying enough in development but it means I can’t upload a new WAR file to our test server regularly without also bouncing Tomcat. Right now our continuous integration server (Bob the Builder) is doing just that after every commit so the server isn’t staying up all that long.
Caching in Tomcat – SOLVED!
It took forever, but I’ve finally how to stop Tomcat adding a Pragma: no-cache header to any resources in a secure context. You need to set disableProxyCaching to false, so if you’re using basic authentication you need a valve like:
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator"
disableProxyCaching="false" />
That needs to go within the
<Context>
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator"
disableProxyCaching="false" />
</Context>
I found deploying as a WAR didn’t work (it seemed to ignore the context.xml), but deploying the exploded files did work and that’s fine by me.
Wowsers! Sun’s Updating The Swing Text APIs
Apparently Sun has finally decided to give some love to the Swing text APIs with the addition of a removeElement method. What the linked article fails to mention is that in the particular example given, you can remove the list item with a simple document.remove(e.getStartOffset(), e.getEndOffset() - e.getStartOffset());
When you get into trouble with the swing text apis is when there are two elements that start and end at the same point – ie: a list as the only child of a table cell:
No Signed Applets For Windows Safari
It turns out the root cause of the problems I was seeing with Safari on Windows is that it simply doesn’t support signed applets. That’s pretty sad really. Apple seem to have implemented their own Java plugin instead of using the one that Sun provides (they’re using the Sun JRE via their plugin) and of course it’s missing most of the features you’d want from a Java plugin.
I’ll report it to Apple officially just as soon as someone fixes the bug reporter – it’s currently down. Perhaps there are too many people logging bugs against the new Safari and Leopard builds….
Safari Brings Horrible Debugging To Another Platform
So Apple have released Safari for Windows – really no idea why, but they have. Sadly, just like on Mac it has terrible JavaScript and Java debugging support. In fact, it’s worse on Windows than on Mac – anyone know how to turn the debug menu on? Anyone know how to get a Java console to appear?
I’d really, really like to make things work with it but all I can do at the moment is randomly guess at the source of problems.
The Benefits Of Open Sourcing Java For Developers
There was an interesting panel discussion at JavaOne today about the open sourcing of Java. The panel was made up of folks developing open source JVMs and a representative from Sun. Compatibility is obviously a common theme to these discussions and there were a number of mentions to just how bug for bug compatible the alternative JVMs are trying to be. It occurs to me though that if all the implementations wind up behaving in precisely the same way, there’s not really any point to having multiple implementations. Yes multiple licenses are nice for particular niches but for the average Java developer, what’s the benefit?
JApplet Memory Leaks
I mentioned the other day that I was having trouble with OutOfMemoryErrors being thrown when there shouldn’t have been any references left around. We’ve done a fair bit more investigation into the cause of this and have wound up reporting a bug to Sun (still awaiting review so it’s not in the public bug database yet). It turns out that you can cause OutOfMemoryErrors with an applet as simple as the one below if you just refresh the page a few times – but apparently only if you’re using a dual-cpu or dual-core system.
Java OutOfMemoryError – Sanity Check
Just for my sanity, before an OutOfMemoryError is thrown, the garbage collector should do everything it can to free up more memory right? What I’m seeing now is that the JVM does a partial GC, throws an OutOfMemoryError and then decides to actually do a full GC which frees up enough RAM to get things working again.
Very annoying and I’m not sure what I can do about it. There are definitely no remaining references, but I still can’t get that memory back.
Remember To Turn On Antialiasing
If you’re doing some graphic work in Java that you want to look pretty (as opposed to most UI stuff where this doesn’t make any real difference), you probably want to make sure antialiasing is on for the graphics object. By default Java usually honors the OS settings for antialiasing, particularly for text, but you can get much smoother antialiasing by setting the appropriate rendering hint.
For example, originally the new progress bar I added last week didn’t have antialiasing on, but in the tweaks I’ve done this morning (now live on our internal systems) antialiasing is on and it looks much better. It’s also changed to be more dots than lines since the last post too. However, setting the antialias rendering hint for all the components in the editor simply slows everything down (rather dramatically) and doesn’t actually improve the appearance anyway. Definitely a setting to be aware of but be cautious in its use.
Improving The Applet Startup Experience
I’ve spent most of this week working on making the start up experience for our applet better. It should look better, take longer and most importantly feel fast to the user. The first step is obviously to profile and optimize – the faster the start up time actually is, the easier it is to make it feel fast for users. There were a few things we could do to help out there, but nothing that really made a dramatic difference.
Beware The Unused Thread
Many people think that because Java has garbage collection, that memory leaks aren’t possible – this is totally and utterly wrong. One really good way to introduce leaks into Java programs without blatantly holding on to object references is to create a new thread and then not use it. Once you create a thread, it is added to the list of runnable threads. I’m not sure why, but even before the thread is actually started, Java treats it as a running thread and holds on to it. Obviously threads that are currently running shouldn’t be garbage collected, but it seems like an unfortunate side effect that newly created threads also can’t be garbage collected. Once you know about it, the solution is simple – only ever create a thread immediately before you call its start method.
Here We Go Again, aka Java 6 On OS X
A new release of Java, a new wave of people saying they won’t buy Macs unless Apple get their Java update now, dammit now! John O’Conner joins the chorus. Of course, there’s no mention of why he needs Java 6 instead of Java 5, just that he has to be up to date with the very latest. Last time round at least people were eager to use generics and other new language features, but there’s really not that much that changed in Java 6 outside of a few specific cases.