Top Banner
Growing an ecosystem on the Java platform Iulian Dragos Typesafe Inc
40

Growing an ecosystem on the JVM

Apr 16, 2017

Download

Software

Iulian Dragos
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Growing an ecosystem on the JVM

Growing an ecosystem on the Java platform

Iulian Dragos Typesafe Inc

Page 2: Growing an ecosystem on the JVM
Page 3: Growing an ecosystem on the JVM

The Premise

Ecosystems flourish on stable grounds

Page 4: Growing an ecosystem on the JVM

The Promise

• Software composes well

• Pick off-the-shelf (open source) components

• Glue them together

• Profit

Page 5: Growing an ecosystem on the JVM

The reality

Page 6: Growing an ecosystem on the JVM

It is hard to pick the right libraries that work together.

Page 7: Growing an ecosystem on the JVM

Abstraction

• Stable interfaces

• Pluggable implementations

Page 8: Growing an ecosystem on the JVM

Stable interfaces

• An interface specifies a contract

• names, method signatures, etc.

• It can be automatically checked in a typed language

Page 9: Growing an ecosystem on the JVM

class TextFile { def readText(file: File): String }

Page 10: Growing an ecosystem on the JVM

Binary Compatibility: One can simply swap one compiled binary library for another

Page 11: Growing an ecosystem on the JVM

Stable Interfaces

class TextFile { def readText(file: File): String }

Page 12: Growing an ecosystem on the JVM

Stable Interfaces

• They evolve (so they are not stable)

class TextFile { def readText(file: File, encoding: String): String }

Page 13: Growing an ecosystem on the JVM

Stable Interfaces

• They are stable within a version

• The problem now becomes “finding a configuration of libraries and their versions that work together”

• DLL Hell, Jar Hell

Page 14: Growing an ecosystem on the JVM

Dependency resolution(more software)

Page 15: Growing an ecosystem on the JVM

Dependency resolution

• Linux: apt-get, rpm (user-level) or autotools (dev side)

• Mac OS (homebrew, fink, etc.)

• Maven, Ivy for Java developers

• OSGi

Page 16: Growing an ecosystem on the JVM

Dependency resolution

• Allow upgrades/downgrades of individual libraries without ripple effects (i.e. human intervention)

• Use versions (or version ranges) to derive constraints

Page 17: Growing an ecosystem on the JVM

Semantic Versioning

• patch: drop-in replacement (binary compatible)

• minor: additional APIs (binary compatible)

• major: breaking changes

Page 18: Growing an ecosystem on the JVM

What is versioned?

Maven/Ivy OSGi

Granularity Artifact (Jar) Bundle (Jar) Package

Namespace GroupID+ArtifactID

Fully Qualified Name

Page 19: Growing an ecosystem on the JVM

Example:

<dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> <version>4.1.0</version> </dependency>

Require-Bundle: org.eclipse.core.runtime, org.scala-lang.scala-library;bundle-version="[2.11,2.12)"

Page 20: Growing an ecosystem on the JVM

Resolution

• The tool selects a version for each dependency

• May fail to find a workable configuration

Page 21: Growing an ecosystem on the JVM

HTTP-lib

SMTP-lib

TCP-libMyApp

1.0.0

1.1.0

3.1.2

3.1.3

A typical application has >200 libraries!

Page 22: Growing an ecosystem on the JVM

Multiple inheritance

• Libraries are used through different dependency chains

• Sometimes with different versions

• resolution picks a compatible version based on

• semantic versioning (OSGi)

• distance — nearest-wins (Maven)

Page 23: Growing an ecosystem on the JVM

OSGi platform

• Resolution happens at runtime (wiring)

• Allows different versions of the same library (side-by-side)

• avoids conflicts using classloader isolation

• “communication” only through shared classes (for example, JDK objects)

Page 24: Growing an ecosystem on the JVM

Java Runtime• Everyone depends on the JRE (standard library)

• JDK has very strict binary compatibility guarantees. That’s why Java is still version 1.8!

• ..and probably there won’t be a Java 2.0 ever

• Ensures Java upgrades don’t require a rebuild of the whole ecosystem

• (also, deprecated methods can never be removed)

Page 25: Growing an ecosystem on the JVM
Page 26: Growing an ecosystem on the JVM

The Scala Ecosystem

Page 27: Growing an ecosystem on the JVM

Scala ecosystem

• open-source

• decentralized

• following Functional Programming principles

• lots of small libraries

• focus on composition

Page 28: Growing an ecosystem on the JVM

Binary compatibility

• Micro version is binary compatible

• 2.11.0 —> 2.11.1 is a drop-in replacement

• Minor version is not binary compatible

• 2.8.0 —> 2.9.0 requires rebuild of ecosystem

• Major version (epoch) is reserved for breaking language changes

Page 29: Growing an ecosystem on the JVM

Binary compatibility

• A given library can work with only one Scala major version

• ..therefore a Scala version (2.10) determines a partition of the ecosystem

• ..an organization has to standardize on such a version

Page 30: Growing an ecosystem on the JVM

More constraints• Given a library, how do you know the Scala version it works with?

• 1st try: semantic versioning

• version 1.0-1.99 works with 2.10

• version 2.0-2.99 works with 2.11 etc.

• Downsides:

• each library may have a different base version

• a given version works with only one Scala version

Page 31: Growing an ecosystem on the JVM

Cross Compilation

• Let’s encode that in the name

• scalatest_2.10 v. 1.0

• scalatest_2.11 v. 1.0

• A library can be cross-compiled to many different Scala versions

• Uniform convention for all libraries

Page 32: Growing an ecosystem on the JVM

Major releases

• A Scala major release is a big thing

• happens every 1.5 years

• requires everyone to rebuild their code

• No cycles in the dependency graph!

Page 33: Growing an ecosystem on the JVM

Major releases

• What about unit testing frameworks?

• everyone depends on them

• they might depend on other libraries

• hence a cycle is formed!

Page 34: Growing an ecosystem on the JVM

Dependency scoping• Solution: Dependency scope

• one set of dependencies for runtime

• another set of dependencies for testing

• This way we can bootstrap the ecosystem in three steps

• build/publish without test

• build testing frameworks

• rebuild/publish with tests

Page 35: Growing an ecosystem on the JVM

Upgrades

• Upgrading to a new major version (2.10—> 2.11) requires a transaction

• All projects that interoperate have to move together to the new version

Page 36: Growing an ecosystem on the JVM

Micro Services

There will be no other form of inter-process communication allowed: no direct linking, no direct reads of another team’s

data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service

interface calls over the network.

Anyone who doesn’t do this will be fired. Thank you; have a nice day!

Jeff Bezos, Amazon

Page 37: Growing an ecosystem on the JVM

Micro services

• Decouple using lightweight HTTP servers

• Serialize to JSON (XML, proto buffers, etc)

• Services can evolve independently

Page 38: Growing an ecosystem on the JVM

Micro services

• There are also interfaces

• So need versioning

• but not statically checked :(

• Less coupling (no leaks of transitive dependencies)

Page 39: Growing an ecosystem on the JVM

Lessons learned

• Java has set a very high standard for BC

• People don’t like to rebuild their libraries

• ..but also don’t like broken APIs

• Minimize breaking changes (deprecated methods stay in for 2 major releases — 3 years cycle)

Page 40: Growing an ecosystem on the JVM

Summary

• Dealing with dependencies is hard

• Version numbers are important

• Many solutions (Maven, apt, OSGi, microservices)