Gradle’s includeBuild() is Awesome

I’ve worked on teams that use many repositories and teams that put everything into a giant monorepo. But no matter how much code we jam into git, there’s always something else on the outside. Gradle’s includeBuild() feature smashes multiple projects together into one. Recently I used it…

I Love Control Flow

As discussed previously, I’m working on a file system API for Okio. I’ve already written real & testing implementations, and now I’m adding ZipFileSystem: it views a zip archive as a read-only file system. Most of the work is reading specs, writing tests, and learning the gotchas…

NullPointerException: bio == null

Sometimes multiple threads close the same Socket concurrently. Unfortunately, Android 10 and 11 may crash when this happens: java.lang.NullPointerException: bio == null at com.android.org.conscrypt.NativeCrypto.SSL_pending_written_bytes_in_BIO() at com.android.org.conscrypt.NativeSsl$BioWrapper.getPendingWrittenBytes() at com.android.org.conscrypt.ConscryptEngine.pendingOutboundEncryptedBytes(…

Files, Boilerplate, and Testability

I’m working on Okio’s multiplatform filesystem API. It introduces 3 main types: Path: a value object that identifies a file or directoryFileMetadata: a value object that describes a file or directory, including its type and sizeFilesystem: a service object to read and write files and directories Plus two…

On Files and Okio

Though Okio has been multiplatform for a year, it still lacks support for reading & writing files. I’ve been thinking about what application developers need and what APIs we should build. But the more I consider it, the more I think, ‘fuck, filesystems are awful’. Files as UIComputing used…

Building on the Wrong Abstraction

Writing sturdy software is hard work. Sometimes it’s very hard work, but it doesn’t need to be. Very Hard Problem: ORMI have a confession: I like Hibernate. The @Version feature is my favorite; it makes optimistic locking easy and safe. I also like how simple it is to…

Many Correct Answers

Let’s copy a file with bad Java I/O: private void copy(File source, File target) throws IOException { try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target)) { while (true) { int b = in.read(); if (b == -1) break; out.write(b); } } } Whoops, it’s super slow. Reading a…

Optimizing ‘new byte[]’

How much time does it take to allocate a byte array? Let’s write a JMH benchmark: @Param({"1000", "10000", "100000"}) int size; @Benchmark public void newByteArray() { byte[] bytes = new byte[size]; bytes[bytes.length - 1] = 'a'; }Running this on my laptop shows that time scales with size: size…