How (not) to extend standard collection classes

Today in ##java, someone had a problem: They wanted a bounded-size PriorityQueue. One solution offered was extending the PriorityQueue class to add this behavior1.
This article will talk about why that is not a good solution.
Here is an example implementation of this approach:

public class BoundedPriorityQueue<E> extends PriorityQueue<E> {
    private final int bound;
    public BoundedPriorityQueue(Comparator<? super E> comparator, int bound) {
        super(comparator);
        this.bound = bound;
    }
    @Override
    public boolean add(E e) {
        if (size() >= bound) { return false; }
        return super.add(e);
    }
}

Now… This looks somewhat correct, if you don’t pay attention. But it isn’t! The important thing missed here is that the Queue.offer(E) method is not overridden, and gives the user a way to put this queue into an invalid state (too many items).
In this particular case this is not a huge issue. There are only two methods, offer and add, that increase the size of a PriorityQueue, and add happens to delegate to offer. The important thing to get out of this example is that this bug can happen in the first place, and that the compiler – or runtime – won’t warn you about it.

Extending ArrayList

Let’s get to a more problematic example. We want to have a List that can only be added to, but never removed from.

public class AddOnlyArrayList<E> extends ArrayList<E> {
    @Override public E remove(int index) { throw new UnsupportedOperationException(); }
    @Override public boolean remove(Object o) { throw new UnsupportedOperationException(); }
    @Override public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); }
    @Override public void clear() { throw new UnsupportedOperationException(); }
    @Override public Iterator<E> iterator() { return Iterators.unmodifiableIterator(super.iterator()); }
    @Override public List<E> subList(int fromIndex, int toIndex) { return ...; }
    @Override public ListIterator<E> listIterator() { return ...; }
    @Override public ListIterator<E> listIterator(int index) { return ...; }
}

Hey, this is good, right? All remove methods and clear accounted for, iterators and subList also implemented, should be fine! Well, that’d be right. In Java 7.
With Java 8, Collection.removeIf(Predicate<E>) was added. This is a default method on Collection that normally only delegates to iterator, but ArrayList has its own, optimized version of it.
Suddenly, just with a JDK update, our class breaks and we may not even notice it. The issue is pretty subtle – it may never appear, and when it does happen, the only way we’ll notice is that our “AddOnly”ArrayList suddenly is shrinking because someone elsewhere decided to use that fancy new removeIf method.
The core problem with both these examples is that extension is fragile. A class has to be designed with extension in mind if it’s supposed to be extensible this way. While most standard library classes aren’t final, many of them are not intended to be extended, or only offer hooks for some specific forms of extension.

How to do it properly

You hear this repeated often, but many do not really seem to understand why: Prefer composition over inheritance. Here’s our AddOnlyArrayList with composition:

public class AddOnlyArrayList<E> extends AbstractList<E> {
    private final List<E> elements = new ArrayList<>();
    @Override public E get(int index) { return elements.get(index); }
    @Override public int size() { return elements.size(); }
    @Override public E set(int index, E element) { return elements.set(index, element); }
    @Override public void add(int index, E element) { elements.add(index, element); }
}

remove is unsupported by this class, but importantly, this can never change. The elements list we’re delegating to is fully encapsulated, and we control all access to it. There’s no way for a future change in List, AbstractList or even ArrayList itself to allow removal of elements. This approach is a lot less fragile than extending ArrayList itself.
Here’s our implementation of BoundedPriorityQueue following the same principle:

public class BoundedPriorityQueue<E> extends AbstractQueue<E> {
    private final Queue<E> elements;
    private final int bound;
    public BoundedPriorityQueue(Comparator<? super E> comparator, int bound) {
        this.elements = new PriorityQueue<>(comparator);
        this.bound = bound;
    }
    @Override public Iterator<E> iterator() { return elements.iterator(); }
    @Override public int size() { return elements.size(); }
    @Override public E poll() { return elements.poll(); }
    @Override public E peek() { return elements.peek(); }
    @Override
    public boolean offer(E e) {
        if (elements.size() > bound) return false;
        return elements.offer(e);
    }
}

Disadvantages

Of course, delegation has its disadvantages.

Memory overhead

There’s an additional object for the wrapper. This isn’t really a problem in practice, though.

Performance

You can’t take advantage of all optimizations a class may introduce in the future. ArrayList.removeIf is a great example again – the delegating class will only delegate a subset of methods, falling back to the potentially unoptimial behavior of AbstractList for others. But importantly, while this may be slower, it’s always correct – if it becomes a problem, just delegate that method as well. At least it won’t suddenly lead to broken behavior.

Missing Optional Methods

It’s possible to miss certain optional methods when delegating. In the standard AbstractList example, it’s very easy to forget to delegate the set(int, E) method since it isn’t used very often.
However, this is usually fail-fast – it’ll throw an Exception and you’ll notice it – and much preferrable to the unexpected and subtle results wrong extension may produce.

Additional Code

Especially with large interfaces and interfaces where you don’t have a handy stub class like AbstractList available, there can be quite a lot of methods to delegate. This is probably the biggest problem with delegation and a good reason to keep interfaces small.

Tooling

Your IDE can assist you with generating delegation methods.
If you are a fan of lombok, it offers an experimental @Delegate annotation. But beware: Using this annotation with only excludes defined can lead to the very same issue! Take the example from the lombok website:

class ExcludesDelegateExample {
  long counter = 0L;
  private interface Add {
    boolean add(String x);
    boolean addAll(Collection<? extends String> x);
  }
  @Delegate(excludes=Add.class)
  private final Collection<String> collection = new ArrayList<String>();
  public boolean add(String item) {
    counter++;
    return collection.add(item);
  }
  public boolean addAll(Collection<? extends String> col) {
    counter += col.size();
    return collection.addAll(col);
  }
}

Here we are missing proper handling for the listIterator.add and corresponding subList methods – we can enter invalid states and can have subtle bugs. Be very careful when using this annotation!

Conclusion

Don’t extend classes that weren’t meant to be extended. A class not being final does not give us a free pass – non-final is the default in java, and many programmers do not design their classes with extension in mind (and that’s fine).
Before extending a class with actual logic in it, think about alternatives. Can you use delegation instead? With collections and their convenient Abstract* stub implementations it’s easy, but with small interfaces you may not even need that.


Javachannel's interesting links podcast, episode 5

Welcome to the fifth ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 October 23.
This podcast covers news and interesting things from the ##java IRC channel on Freenode; if you see something interesting that’s related to Java, feel free to submit it to the channel bot, with ~submit and a URL to the interesting thing, or you can also write an article for the channel blog as well; I’m pretty sure that if it’s interesting enough to write about and post on the channel blog, it’s interesting enough to include in the podcast.

  1. First up, we have a DZone entry; DZone‘s actually really good at picking out content that’s interesting. However, sometimes you have to be fairly selective about what you read, because they end up like a lot of such sites and go for volume and consistency in publishing as opposed to being selective for stuff that’s truly relevant. That’s why you have things like this podcast, of course, because I clearly know what’s interesting and relevant more than they do! Anyhoo, the actual reference is for Eclipse: “Fifteen Productivity Tips for Eclipse Java IDE Users,” and they’re pretty good; none of them are what I would consider the most obvious (which is: “Use IDEA instead”). The truth is, Eclipse is very popular; anything that helps people use their tools more efficiently is a good thing. Some of the tips are fairly obvious (“use the most recent version of Eclipse”) and others are just things that experienced users might know and use already, but that’s the benefit of articles like this: they make sure that everyone has a baseline of competence. Other tips: switch editors with ctrl-tab; group related projects in working sets rather than using multiple workspaces (this is one of Eclipse’ better features, and I’m glad it’s here); download the sources of libraries; conditional breakpoints and watchpoints; leverage code coverage. There are more (nine more, making a total of fifteen, as the article title promises), and none of them are awful.
  2. Next up: Java 8 updates have an end-of-life: September 2018. Along the way, new versions of Java 9 and Java 8 have been released (9.0.1+11 and 8u151/8u152) – which is good, I suppose, although expected with a new major release – but the big news here is that Java 8 is going to see no more public updates after September 2018. Progress marches on, but I have a feeling this is going to be like the Java 7 migration – which is still ongoing. We aren’t seeing as many people saying they’re still on Java 7 – or Java 6 – as we used to, which is anecdotally a good signal that people are moving to Java 8 after all. So who knows? Maybe with such a recent mass migration to Java 8 there will be momentum to allow people to move to Java 9 – especially if they don’t have to use the module system yet – and people will stay more current.
  3. More DZone: they’re on a roll (and sneak preview: they have two more links after this one). The entry this time is “Artificial Intelligence: Machine Learning and Predictive Analytics.” It’s a fairly high-level guide, and being on artificial intelligence, it’s not just Java – and shouldn’t be. It’s a good reference, though. It’s well-done. I would love to see Java be more relevant in AI; it’s certainly relevant, and is a major player in the space, but the truth is that the starting point for AI is in Python, not Java. The same goes for natural language processing; you can find tools in Java, to be sure (Stanford NLP, for example), just like you can find AI resources in Java (WEKA, among others) but they’re typically trailing the cutting edge. Most data scientists would see a preference for Java as a bit of an affectation. (And I say that because I do prefer Java, and the data scientists I know think I’m a loon for that. They’re probably right.)
  4. This is an old link, but it showed up on my feeds recently, so I’m pretending the publication date of May 16, 2017, is badly inaccurate: Java 8u131 – and yes, 131, 151 is the current build – is transparently aware of Docker memory and CPU limits. Why is this important? It’s because older builds were, well, not aware of Docker‘s machine limitations. The idea is that Docker runs a constrained virtual machine; your actual machine might have 16Gb of RAM, but your Docker image might have 2Gb available to it, and only two of your eight cores. But if you ran an older build of Java in that Docker image, it would use the actual physical machine limits to gauge heap allocation limits and CPU core usage – which could obviously cause problems (your 2Gb image would allocate heap as if it were on a 16Gb machine, which would be incorrect). So… I guess, what with this information being fairly stale, it’s good that they fixed this. And if you happen to be running an older Java, update, please. Note that you do actually need to tell the JVM to use group memory for the heap. This is via two command line options: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap.
  5. Another DZone article! This one is “Automata-Based Programming in Spring.” It really serves as a bare introduction for Spring Statemachine, which isn’t quite what the title led me to expect – I was thinking that I was going to get to read about how to apply cellular automata for problem solving, a la Wolfram Alpha, but instead it’s just a library that makes state transitions easy to manage. It’s a Finite State Machine, not Cellular Automata. This is on me for reading it wrongly, by the way; FSMs are automata, but not cellular in nature.
  6. Daniel Dietrich wrote an article called “Opinionated Database Access in Java” – because we all know that database access has no opinion involved at all, ever. In this case, he’s writing a library that provides yet another abstraction: this one leaves modeling to the database; complex queries are moved to the database; access should be simple and obvious. In other words, it’s one of the Java libraries that provides access to the database services, as opposed to backing up Java data structures with a database. It’s not mature yet (and he provides an example of the API using Scala, too, so it never will be mature.) The only thing is: the article doesn’t provide a reference to an actual project, so it’s all vaporware at this point. Plus, as the lively comment flow indicates, it’s another entry in a space that’s very crowded with possible implementations depending on what you want, from ORMs like Hibernate to JDBC layers like MyBatis and jOOQ.
  7. Java’s version numbers are likely to change. Java has generally followed a semantic versioning approach: you have a major version, a minor version, and a build number (sort of). However, there’s a proposal put together by Mark Reinhold (He Who Controlled Java 9’s Release) to go to a date-based release cycle, so the next release won’t be Java 10, but Java 18.3, meaning “released in the third month of 2018.” There are a few problems with this proposal, and I’m hardly alone in seeing them: one is that there’s not a “major release” associated with the build. With Java 8 versus Java 7, there’s a clear delineation of major versions; Java 8 is the one with streams. Java 9, likewise, has Jigsaw. But the next major feature – let’s say “value types” as an example – might be in Java 18.6 as opposed to Java 18.3, so we lose the ability to easily determine feature groups. Plus, Java applications will have a harder time determining the actual baseline versions they require; right now they can parse out the major version and say “Oh, I’m on Java 8 instead of Java 7” but now they’ll have to factor in the actual release year. Maybe it’s me being a curmudgeon, maybe it’s me resenting how Mark handled the Java 9 release, but I think semantic versioning is still better than the year/month release versioning. With Reinhold proposing it, it’s likely to be approved by fiat; I’m sure it’ll grow on me over time, like a fungus, but I still don’t have to like it. Now get off my lawn!
  8. Last week I highlighted Excelsior JET, which allows delivery of native binaries using Java 8 (so far). This week, we see Steve Perkins writing “Using Java 9 Modularization to Ship Zero-Dependency Native Apps“, using Java 17.10… yeah, the date-based versioning isn’t something I like at all yet. Anyway, it’s just a simple “Hello world” example, but it, like others, is a good start; I like seeing articles like this, because this is how we build a repository of knowledge concerning how to use these neat new features Java 9 provides.
  9. And now for the last of our links, this one also from DZone: “OpenLiberty.io: Java EE Microservices Done Right.” OpenLiberty is another microservice framework, like Spring Boot, DropWizard, or Vert.x, this one focusing fairly heavily on canonical Java EE APIs (as opposed to leveraging those APIs where appropriate as Spring Boot or DropWizard do.) It’s billed as a “deep dive into OpenLiberty,” but it’s really not; it’s really a cursory example with a single JAX-RS endpoint (although it does show live redeployment, which is neat.) The actual OpenLiberty sample application isn’t much to speak of; the redeployment is important, but the main thing the article shows is configuration of the OpenLiberty build, which is probably the most important thing it should want to show. It’s interesting; it’d be interesting to try out.

Interesting links podcast, episode 4

Welcome to the fourth ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 October 16.
This podcast covers news and interesting things from the ##java IRC channel; if you see something interesting that’s related to Java, feel free to submit it to the channel bot, with ~submit and a URL to the interesting thing, or you can also write an article for the channel blog as well; I’m pretty sure that if it’s interesting enough to write about and post on the channel blog, it’s interesting enough to include in the podcast.

  1. Worth noting, not because it’s Java-related but because we’re all on the same Internet: there’s a security vulnerability with WPA2, the wireless encryption used by, well, pretty much everyone. Check your routers for security patches; if they’re not available, they should be soon, and if they’re not available soon, consider getting a good router.
  2. Effective Java is one of the recommended books from the channel regulars; it covers a lot of things that affect efficiently written Java. However, Josh Bloch is working on an update for the third edition of Effective Java. It’s available for pre-order. Highly recommended; Josh Bloch is one of the people who really knows Java, to the point where he says he can write code in Java such that he can influence how the JIT works, to make it more efficient than code mere mortals like you or I would write. So when he has a book on writing effective Java, it’s probably pretty authoritative.
  3. Facebook apparently uses their own build system, called “Buck.” It’s supposedly really fast; it apparently supports a lot of languages, which is a good thing; it does not, however, use the same build structure for source that Maven and Gradle use. That’s sort of okay; the Maven convention (which is what Gradle uses) is idiomatic in Java only because Maven itself became idiomatic, but it’s still something to consider if you’re moving to something different. My thought is that Buck might be cool but in a java-centric project, it’s probably not of sufficient interest to really move the needle. I looked; I considered; I moved on, seeing nothing really compelling in the description or tutorial that made me think “Wow!” like I did with, well, both Maven and Gradle, both of which I use regularly.
  4. Excelsior JET – who makes an ahead-of-time compiler for the JVM, so you can deploy your Java applications as native binaries – has an interesting post called “The Folder of God.” No, it’s not a religious post, although religious fervor might be involved if you hate Windows enough. Basically, there’s a way to create a folder in Windows such that Java programs running from that folder will crash, every time. (I don’t know why you’d actually do that in practice.) It’s an actual Java bug, not an Excelsior bug – but Excelsior experiences the bug nonetheless. It’s apparently been addressed in the Java sources, but your JVM might not be updated with the fix. It’s fascinating reading, even if only to make you glad you’re not using Windows.
  5. A report by realm.io suggests that “Java (on Android) is dying. There aren’t simply more Kotlin builders: they’re also switching their apps to Kotlin. In fact, 20% of apps built with Java before Google I/O are now being built in Kotlin. Kotlin may even change how Java is used on the server, too.” As a Kotlin user myself, I can say that the transition to Kotlin in dreamreal-land is progressing rather nicely… but what’s more relevant is that Kotlin on Android is increasing momentum, and that may very well drive server-side development as well, as there’s a strong tendency to be homogenous even if interoperability between languages like Kotlin and Java is quite strong. The channel recently had a discussion about Java’s checked exceptions, a feature Kotlin doesn’t share (because nobody really likes checked exceptions and the JVM itself doesn’t have them – they’re a javac thing, not a JVM thing); checked exceptions are actually a good thing in that they force you to think about your exception handling, but there’s no guarantee you’re going to actually handle your exceptions well, so they end up being an unnecessary burden in many peoples’ minds. Worth thinking about, in any event…
  6. Something that comes up fairly often in the channel is the use of the Oracle JDK vs. OpenJDK, and what the differences are between them. I always said it was in a set of closed-source libraries used in Oracle JDK, such that some features might be present in Oracle’s JVM that OpenJDK did not have. Well, while that was true at one point, it’s like all Internet knowledge: it erodes. The Adopt OpenJDK project has a page on Differences between Adopt OpenJDK binaries and Oracle JDK Binaries that actually walks through the differences, which is a really short list: font rasterizers, color management, and graphics renderers. That doesn’t compare the differences with other implementations of the JVM – Zulu and whatnot – but what it does say is that OpenJDK and Oracle’s JDK are really closely aligned right now, just as designed.
  7. The Jooq blog has an article called Benchmarking JDK String.replace() vs Apache Commons StringUtils.replace(). It walks through an optimization process and measures the effectiveness, offering a ton of apologies for what might appear to be premature optimization along the way; the upshot is that Java 9’s String.replace() works better than it used to, which might affect which implementation to use. (It turns out that Java 9’s version is slower for matches in long strings but faster for matches in short strings, which – in practice – are probably more common.) They ended up staying with Apache’s implementation for now if only because most people are still on Java 8 and thus the performance improvements are worthwhile. It’s a fascinating read.
  8. Wrapping up, we have an article from Baeldung called “Introduction to Caffeine“. Caffeine is a caching library; the article walks through its use, as one might expect. All that’s fine. What the article does not do, though, is differentiate why one might use Caffeine as opposed to one of the other caching libraries out there, like EHCache, or Guava Cache – which inspired Caffeine, actually. Channel inhabitant dudeji – which I don’t know how to pronounce – points out that Caffeine has time-to-live (as most of them do) but also automatic elimination based on unused keys; I can see some use in that, although I’d be concerned that the cache was deciding that a key was unused more aggressively than I’d have liked. I’m sure it’s tunable, though.

Interesting Links podcast, episode 3

Welcome to the third ##java podcast. I’m your host, dreamreal on the IRC channel, and it’s Monday, 2017 October 9.
As usual, this podcast is built from interesting content submitted to the channel bot, using the ~submit command. If you’re on the channel, it’s very easy to use: ~submit and a URL is all you need, although it’s very helpful if you include a comment about what makes the content interesting. That saves your host – me – a lot of work trying to figure out why something was submitted.

  1. First up, we have “Reverse Engineering an Eclipse Plugin,” a long (but good) post from someone trying to figure out a security issue in the a popular Eclipse plugin – I don’t use it, but he says that apparently the Eclipse Class Decompiler Plugin as deployed on the Eclipse Marketplace has a “phone home” feature that isn’t shown in the github repository for the plugin. The author did some basic security auditing and found that the plugin apparently does something after a number of classes have been decompiled, and that the open source version of the plugin does not show this functionality. Good call by the author; he doesn’t actually reverse engineer the plugin, but actually dives into the security aspects of it, but it’s an excellent walkthrough nonetheless.
  2. Common Excuses Why Developers Don’t Test Their Software, as the title might suggest, walks through some of the reasons software tests don’t get written and run. For the most part, it’s laziness and self-deception; headings include “My code runs perfectly, why do I need to test,” “I don’t know what to test,” Barbie’s favorite excuse of “testing is hard!,” “testing increases development time.” Well worth checking out – and sending to your co-workers.
  3. Zircon is an extensible text UI library that targets multiple platforms and was designed specifically for game developers. It actually looks neat – you could imagine Dwarf Fortress or Nethack‘s user interface with something like this. I still content that while Nethack lacks the twitchy adrenaline rush of first person shooters and other such games with high frame rates, it’s still one of the best – if not THE best – computer game ever written. And yes, I know, I sound old. Now get off my lawn.
  4. Sticking to the user interface theme, Say no to Electron! Using JavaFX to write a fast, responsive desktop application, addressing the growing use of Electron. Electron is a web browser that hosts only your web application, leveraging a common approach these days that uses Java for a backend and renders the front end with HTML and Javascript. Electron isolates your app into its own browser window. While this gets you a lot of capabilities (people are used to how the web renders things, and it’s easier) it mostly reflects a failure on the part of Java to render cleanly and consistently on every platform – you can usually smell a pure Java application by the user interface features and feel it has. So people use other technologies for the user interface, which makes the apps feel more “native,” I guess, even though that’s an abuse of that term. This article actually walks through some of the alternatives to the HTML user interface in Java, and settles on JavaFX for an example. It doesn’t go very deep, but it hits the beginning aspects pretty well.
  5. The Atlantic – a hotbed of coder information, I’m sure we’ll all agree – has “The Coming Software Apocalypse,” an article going into how programmers construct code. There are people out there for whom 4GL is not dead; they want to snap things together to program. It’s not a bad idea, really, and done well it even works – like everything done well. But the problem is that it’s not easy to do well; maybe they have a solution that’ll work this time. The JavaBeans specification was actually meant to enable this sort of thing, even, but nobody uses it that way because it’s hard to do properly, and let’s face it, we as programmers tend to be conservative in our methods; we like writing code, we don’t care for connecting boxes to each other very much.
  6. Announced at JavaOne – or, well, exposed better at JavaOne, more like, was FN, aan equivalent to Amazon’s Lambda functionality. As a really poor summary of both Lambda and FN, what you would do is write a simple function that accepted input – presumably – and wrote output, and you’d connect these functions to build more complex functionality – almost like programming, you might say. It tends to have determinate latency (it’s not fast) and indeterminate scalability (it will scale out) – and with Java 9 potentially being far lighter on resources than prior JVMs thanks to things like JLink, this could be really nice to have on hand.
  7. Lastly, we have Oracle. The United States Government asked for commentary on how to modernize government IT, and Oracle responded – with a long PDF. It’s an interesting paper, for various reasons, but what’s really interesting is how… outdated and self-serving it sounds. It comes off as telling the government “you need people like us and not those silly hippies from Silicon Valley!” even though Oracle is based in Silicon Valley. Basically their paper is a repudiation of modern software practices, even though the older methods of coding are the whole reason the government is asking for how to modernize in the first place. (Techdirt‘s article on the Oracle comment points out a number of failures given us by what Oracle is propositioning.) Actually, the TechDirt article does a good job of decomposing Oracle’s commentary altogether – it’s a worthwhile read, too. Oracle comes across as whining about new-fangled, agile methodologies, saying “That’s now how we made our money back in the day! We earned it like real men, by crushing our competition because we could absorb losses they couldn’t and making sure they were iced out of big contracts. Let’s go back to that, shall we?”

Interesting Links podcast, episode 2

Welcome to the second ##java podcast.
We have lots of interesting things to cover, so let’s dive in.

  1. Java EE development has moved to the Eclipse Foundation, under the project name “Eclipse Enterprise for Java“, or “EE4J.” Java EE is still the branding for enterprise Java. This move makes Java EE more open; we’ll have to see how well it works under the Eclipse Foundation. We’ll survive either way; it’s a good move for everyone.
  2. RebelLabs’ Developer Productivity Report 2017 is here, almost 72% of the developers said their main programming language is Java 8 – and about time, considering Java 7’s been dead for two years; IntelliJ IDEA is the most popular Java IDE at 54% with the respondents, and one of the survey questions says that 91% of the people who like it said it’s because of superior functionality, as compared to 13% of Eclipse users and 73% of NetBeans users. Some other things that stood out: small teams are the norm, with teams of three to nine people making up half the teams, with medium-sized teams (10-19) coming in at 22%. Hmm, maybe a team of nine people isn’t actually all that small. It’s a great report; you should check it out.
  3. Given Java 9’s release and new features, it’s expected that a lot of migration articles are coming up. Sure enough, DZone’s in play with one that shows migrating a Spring app to Java 9. It has some module-based concerns and walks through fixing them; it’s not exhaustive, but it’s likely to be representative of early adoption efforts.
  4. Nicholas Frankel discusses some clean coding standards around lambdas. It’s easy to decide that a tool is available and thus must be used everywhere, he says – actually, he says that developers act like children and we have to play with our new toys, which is probably a pretty appropriate description. He shows a fairly ugly way to use lambdas primitively, then shows how it can be made a lot more developer-friendly. It’s not exhaustive, but still worth looking at.
  5. According to InfoWorld, Java 9 is not going to receive long-term support. That doesn’t mean it’s not supported, but that the long-term support plans are different than what we’ve seen in the past. Long-term support releases are going to be made every three years, so that’s the baseline for support plans; we’ll have to see if (and how) this affects Java in the long run.
  6. Up next: another DZone link, this time on Java’s Optional. The author, Eugen Paraschiv (from Baeldung) offers Optional as a tool for functional programming, and I suppose he’s right, in a way. The article does a good job of walking through most, if not all, of what Optional can do for your code, including with Java 9, and he does say that Optional is meant as a return type and not a property type, which is … better than he could have done. The article’s worth reading, and is done at much more depth than many similar articles.
  7. We also saw mention of OpenTable’s embedded PostgreSQL container. This allows us to treat PostgreSQL as if it were an embedded database (well, sort of); considering that PostgreSQL is a lot stronger for production use than, say, H2 or Derby, this is a nice way to do database-oriented integration tests on a “real database.” That’s not to say that H2 or Derby aren’t real databases, but they’re anecdotally used in the Java ecosystem more as embedded databases to help with integration testing than as production databases. Of course, now that I’ve made that assertion, I expect RebelLabs to ask something about this on their next survey and completely demolish my statement. Thanks ahead of time, guys.
  8. A bit more on Java 9. RankRed has “What’s new in Java 9,” covering a bird’s-eye view of the changes: the module system, new versioning, the Java Shell, a better mechanism for compiling for older versions of Java, JLink, compact strings, high definition graphics, new factory methods for collections – catching up to Kotlin and Scala, better networking and serialization security, Nashorn changes, a new random generator, segmented code caches, dynamic linking of object models, and an enhanced garbage collector. Whew, that’s a lot – and I left some out. It gets better, though: The Java 9 readme points out that the default JCE policy files now allow for unlimited cryptographic strengths, a feature that the RankRed list left off.
  9. Spring 5.0 has gone to general availability – it’s been released, in other words. Support for Java 9, Java EE 8, functional variants, Kotlin, a new reactive web framework… all kinds of goodies for Spring fans.
  10. Kotlin 1.2 Beta is out. Kotlin is another JVM language; this one’s from IntelliJ, the people who bring you the IDEA editor family. There are a lot of little improvements here, including some things that can drive you crazy during normal development – there’s also multiplatform support, which is important even if you’re like me and only really deploy on the JVM.
  11. We mentioned ZeroTurnaround early in the podcast – the RebelLabs report – but it’s worth noting that in addition to the developer survey, they also released JRebel 7.1, with Java 9 support, Spring 5 support, and a bunch of other things too.

Okay, that’s this week’s podcast – thanks for listening.

Interesting Links podcast, episode 1

This is the first ##java channel podcast. I decided to do a podcast for a few reasons: probably the most important is that I thought it would save time for me; another reason is that I thought it would be nice to have more of a multimedia approach to propagating information from the channel.

I don’t know what kind of schedule the podcast will take. I wanted it to be weekly; some of the interesting stuff for this podcast is a little older than a week, but that’s largely because I’ve been stuck trying to get my ducks in a row to record the podcast. We’ll see how the schedule plays out.
If there’s any advice or criticism you have, you can always put it on the IRC channel, of course, but if you want to make sure I see it, send it to me via private message, memoserv, or – probably best – email, at [email protected].

The interesting stuff

Before we get too far in, it’s worth pointing out that this is all material referenced and sourced elsewhere. As such, we try to vet it for accuracy, but there’s no way to prevent the authors’ opinions from being a factor. It’s perfectly okay if you disagree with this podcast or the links offered in the podcast – after all, the channel even has a few vim and blueJ users, so clearly not everyone on the channel is all that bright, right?
Also, the podcast is associated with a blog post on the channel blog, at http://javachannel.org/. All links to the source material can be found in the blog post that goes with each podcast edition. This is the first podcast, so look for podcast-1 in the search bar.
So off to the news!

  1. Atom gets IDE functionality. Atom is a text editor; IDE features means that it gets a little easier to do quick fixes in Atom if that’s your bag. Invoke your build tool, see errors inline, get autocompletion, and other such features, too. Atom’s open source.
  2. Sublime Text 3 has been released. Sublime Text is not open source, but it’s an excellent tool nonetheless; this release has been cooking for quite some time.
  3. OpenJ9 is available as part of OpenJDK 9. OpenJ9 is a JVM implementation; it’s a peer of the Oracle release. It comes from IBM, via Eclipse; it will behave differently than the “standard JVM,” although I don’t have any experience with it so I’m not sure what that looks like in practice.
  4. Speaking of J9, how did it get its name? Well, Ronald Servant has explained: it comes from the migration of a Smalltalk interpreter such that it handles Java.
  5. Glassfish 5.0 has been released! And … while that’s kind of important and relevant for Java EE users, it’s even more important to note that Java EE 8 is final. Glassfish is the reference implementation of Java EE 8; the new features include the Servlet 4.0 API, better JSON support, a new portable Security API, and Java 8 capabilities, just in time for Java 9.
  6. Speaking of Java 9… it’s finally out. It’s been a long road, but it’s done, for better or for worse. Java 9, with a lot of enhancements, is out – and the biggest enhancement, the biggest disruptor, is Jigsaw, the module system for Java 9. Early adopters have already been talking about migration efforts. This sounds fun, I think, but it’ll be worth it in the long run. Now we get to hope that the lessons we’ve learned in watching Java 9’s release and development cycle haven’t burned so many bridges that people stop being invested.
  7. Lastly, there’s a reference to some realtime resources for Java. There’s even a reference to a DSP library (digital signal processing, typically for sound) in TarsosDSP. Yes, you can use Java for audio processing; BBE’s Sonic Sweetener, for example, was written with Java back in the day and still might be. Sonic Sweetener was an exciter, which is one of the core effects that gave Joe Satriani his distinctive guitar sound on “Surfing with the Alien,” although he didn’t use this exact product (he used a hardware-based effect instead.)

Submitting More Information

The preferred way to get information into this podcast is to, well, submit it. The best way to submit it is through the channel bot.
The syntax is really easy. Join the channel, hit the tilde – the squiggly line that’s the standard trigger for the bot – and type the word “submit.” Then include your link; it has to be an actual URL, because I’m not posting unsubstantiated data, and it’s ideal if you include some commentary about what’s interesting about the link. That’s about it, really.
Okay, that’s it! Thanks for listening, and keep coding, folks.

JarSplice: building fat jars with native resources bundled

JarSplice is an application that builds a fat jar, with the main difference being that JarSplice will build invocation scripts and include native resources.
The main weaknesses of JarSplice seems to be its lack of build tool integration, its (apparently) unmaintained status, and its lack of source code availability (even though it’s described as being under the BSD license).
A “fat jar” (or a “shaded jar”) is a jar file that has been bundled with a project’s full set of required resources.
To explain, imagine that we have a Java project called “foo“, that depends on an external project, called “bar.”
For foo to run properly, then, our runtime classpath must contain foo.jar:bar.jar (in some order, although the order can be significant); both files must be present for the classloader to read in order for the project to run.
A “fat jar,” however, includes all of the resources from the classpath in a single jar. The build would extract every class from both foo.jar and bar.jar and built a new jar – named, for example, foo-all.jar – and therefore only this file would be required in order to run the project, since it has every resource that the prior classpath held.
However, this only works for Java resources; it doesn’t include native resources, like LWJGL‘s or SQLite‘s binary components. If foo uses SQLite, then the computer that foo is running on has to have SQLite deployed as a system library in order for foo to run.
This is what JarSplice addresses; it does bundle SQLite or LWJGL resources into the fat jar.
Again, the main weakness of JarSplice is that it’s not integrated into a build tool, so invoking it is an external mechanism for deployment. Development seems to have stopped (the home page says the code is BSD-licensed but no reference to the code exists.) Luis Quesada Torres built a command-line tool, JarSplicePlus; there are forks of that project that seem like there’s some promise for the future.
Feel free to participate and comment.

Getting a usable, non-localhost IP address for a JVM

I recently had a task where I needed to inform a docker image of the host OS’ IP address. (The docker image needed to make an HTTP call to the host machine, for testing purposes.) However, it’s not trivial to find code to actually get a host machine’s IP address. Here’s some code in Kotlin (and in Java) to accomplish the task; I can’t say it’s perfect (and won’t) but it worked for me, and hopefully this can serve as a tentpole for perhaps better code.
There are two pieces of code here; both eliminate the 10.*.*.* network. If you don’t need that network to be eliminated, well, remove that line.

Kotlin

import java.net.NetworkInterface
fun getAddress(): String {
    return NetworkInterface.getNetworkInterfaces().toList().flatMap {
        it.inetAddresses.toList()
                .filter { it.address.size == 4 }
                .filter { !it.isLoopbackAddress }
                .filter { it.address[0] != 10.toByte() }
                .map { it.hostAddress }
    }.first()
}

Java

The Java code’s a lot more convoluted, and isn’t helped at all by the requirement for a means by which to convert an Enumeration to a Stream (copied shamelessly from “Iterate an Enumeration in Java 8“, by the way.) However, it’s functionally equivalent to the Kotlin code. If it can’t find a valid address or an internal exception is thrown, a RuntimeException is created and thrown.

private static  Stream enumerationAsStream(Enumeration e) {
    return StreamSupport.stream(
            Spliterators.spliteratorUnknownSize(
                    new Iterator() {
                        public T next() {
                            return e.nextElement();
                        }
                        public boolean hasNext() {
                            return e.hasMoreElements();
                        }
                    },
                    Spliterator.ORDERED), false);
}
public static String getAddress() {
    try {
        Optional address = enumerationAsStream(NetworkInterface.getNetworkInterfaces())
                .flatMap(networkInterface ->
                        networkInterface.getInterfaceAddresses().stream()
                )
                .filter(ia -> !ia.getAddress().isLoopbackAddress())
                .map(InterfaceAddress::getAddress)
                .filter(a -> a.getAddress().length == 4)
                .filter(a -> a.getAddress()[0] != 10)
                .findFirst();
        if (address.isPresent()) {
            return address.get().getHostAddress();
        } else {
            throw new RuntimeException("Address not accessible");
        }
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }
}

Summary

This is not perfect code, I wouldn’t think. It was thrown together to fit a specific need, and ideally should have been easily located on StackOverflow or something like that.

Interesting Links – 2017/Jun/12

Interesting Links – 2017/Jun/5