diff options
Diffstat (limited to 'wiki/java')
| -rw-r--r-- | wiki/java/a-new-kind-of.md | 137 | ||||
| -rw-r--r-- | wiki/java/install/centos.md | 57 | ||||
| -rw-r--r-- | wiki/java/install/index.md | 11 | ||||
| -rw-r--r-- | wiki/java/install/ubuntu.md | 84 | ||||
| -rw-r--r-- | wiki/java/kwargs.md | 152 | ||||
| -rw-r--r-- | wiki/java/stop-using-class-dot-forname.md | 69 |
6 files changed, 0 insertions, 510 deletions
diff --git a/wiki/java/a-new-kind-of.md b/wiki/java/a-new-kind-of.md deleted file mode 100644 index 6cc81e5..0000000 --- a/wiki/java/a-new-kind-of.md +++ /dev/null @@ -1,137 +0,0 @@ -# A New Kind of Java - -Java 8 is almost here. You can [play with the early access -previews](http://jdk8.java.net/download.html) right now, and I think you -should, even if you don't like Java very much. There's so much _potential_ in -there. - -## The “One More Thing” - -The Java 8 release comes with a slew of notable library improvements: the new -[`java.time`](http://openjdk.java.net/jeps/150) package, designed by the folks -behind the extremely capable Joda time library; [reflective -access](http://openjdk.java.net/jeps/118) to parameter names; [Unicode -6.2](http://openjdk.java.net/jeps/133) support; numerous others. But all of -these things are dwarfed by the “one last thing”: - -**Lambdas**. - -## Ok, So..? - -Here's the thing: all of the “modern” languages that see regular use - C#, -Python, Ruby, the various Lisps including Clojure, and Javascript - have -language features allowing easy creation and use of one-method values. In -Python, that's any object with a `__call__` method (including function -objects); in Ruby, it's blocks; in Javascript, it's `function() {}`s. These -features allow _computation itself_ to be treated as a value and passed -around, which in turn provides a very powerful and succinct mechanism for -composing features. - -Java's had the “use” side down for a long time; interfaces like `Runnable` are -a great example of ways to expose “function-like” or “procedure-like” types to -the language without violating Java's bureaucratic attitude towards types and -objects. However, the syntax for creating these one-method values has always -been so verbose and awkward as to discourage their use. Consider, for example, -a simple “task” for a thread pool: - - pool.execute(new Runnable() { - @Override - public void run() { - System.out.println("Hello, world!"); - } - }); - -(Sure, it's a dumb example.) - -Even leaving out the optional-but-recommended `@Override` annotation, that's -still five lines of code that only exist to describe to the compiler how to -package up a block as an object. Yuck. For more sophisticated tasks, this sort -of verbosity has lead to multi-role “event handler” interfaces, to amortize -the syntactic cost across more blocks of code. - -With Java 8's lambda support, the same (dumb) example collapses to - - pool.execute(() -> System.out.println("Hello, world")); - -It's the same structure and is implemented very similarly by the compiler. -However, it's got much greater informational density for programmers reading -the code, and it's much more pleasant to write. - -If there's any justice, this will completely change how people design Java -software. - -## Event-Driven Systems - -As an example, I knocked together a simple “event driven IO” system in an -evening, loosely inspired by node.js. Here's the echo server I wrote as an -example application, in its entirety: - - package com.example.onepointeight; - - import java.io.IOException; - - public class Echo { - public static void main(String[] args) throws IOException { - Reactor.run(reactor -> - reactor.listen(3000, client -> - reactor.read(client, data -> { - data.flip(); - reactor.write(client, data); - }) - ) - ); - } - } - -It's got a bad case of Javascript “arrow” disease, but it demonstrates the -expressive power of lambdas for callbacks. This is built on NIO, and runs in a -single thread; as with any decent multiplexed-IO application, it starts to -have capacity problems due to memory exhaustion well before it starts to -struggle with the number of clients. Unlike Java 7 and earlier, though, the -whole program is short enough to keep in your head without worrying about the -details of how each callback is converted into an object and without having to -define three or four extra one-method classes. - -## Contextual operations - -Sure, we all know you use `try/finally` (or, if you're up on your Java 7, -`try()`) to clean things up. However, context isn't always as tidy as that: -sometimes things need to happen while it's set up, and un-happen when it's -being torn down. The folks behind JdbcTemplate already understood that, so you -can already write SQL operations using a syntax similar to - - User user = connection.query( - "SELECT login, group FROM users WHERE username = ?", - username, - rows -> rows.one(User::fromRow) - ); - -Terser **and** clearer than the corresponding try-with-resources version: - - try (PreparedStatement ps = connection.prepare("SELECT login, group FROM users WHERE username = ?")) { - ps.setString(1, username); - try (ResultSet rows = rs.execute()) { - if (!rows.next()) - throw new NoResultFoundException(); - return User.fromRow(rows); - } - } - -## Domain-Specific Languages - -I haven't worked this one out, yet, but I think it's possible to use lambdas -to implement conversational interfaces, similar in structure to “fluent” -interfaces like -[UriBuilder](http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/UriBuilder.html). -If I can work out the mechanics, I'll put together an example for this, but -I'm half convinced something like - - URI googleIt = Uris.create(() -> { - scheme("http"); - host("google.com"); - path("/"); - queryParam("q", "hello world"); - }); - -is possible. - diff --git a/wiki/java/install/centos.md b/wiki/java/install/centos.md deleted file mode 100644 index 51c83f6..0000000 --- a/wiki/java/install/centos.md +++ /dev/null @@ -1,57 +0,0 @@ -# Installing Java on CentOS - -Verified as of CentOS 5.8, Java 6. CentOS 6 users: fucking switch to Debian -already. Is something wrong with you? Do you like being abused by your -vendors? - -## From Package Management (Yum) - -OpenJDK is available via [EPEL](http://fedoraproject.org/wiki/EPEL/FAQ), from -the Fedora project. Install EPEL before proceeding. - -You didn't install EPEL. Go install EPEL. [The directions are in the EPEL -FAQ](http://fedoraproject.org/wiki/EPEL/FAQ#Using_EPEL). - -Now install the JDK: - - sudo yum install java-1.6.0-openjdk-devel - -Or just the runtime: - - sudo yum install java-1.6.0-openjdk - -The RPMs place the appropriate binaries in `/usr/bin`. - -Applications that can't autodetect the JDK may need `JAVA_HOME` set to -`/usr/lib/jvm/java-openjdk`. - -## By Hand - -The [Java SE Development Kit -7](http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html) -tarballs can be installed by hand. Download the “Linux x64” `.tar.gz` version, -then unpack it in `/opt`: - - cd /opt - tar xzf ~/jdk-7u45-linux-x64.tar.gz - -This will create a directory named `/opt/jdk1.7.0_45` (actual version number -may vary) containing a ready-to-use Java dev kit. - -You will need to add the JDK's `bin` directory to `PATH` if you want commands -like `javac` and `java` to work without fully-qualifying the directory: - - cat > /etc/profile.d/oracle_jdk <<'ORACLE_JDK' - PATH="${PATH}:/opt/jdk1.7.0_45/bin" - export PATH - ORACLE_JDK - -(This will not affect non-interactive use; setting PATH for non-interactive -programs like build servers is beyond the scope of this document. Learn to use -your OS.) - -Installation this way does _not_ interact with the alternatives system (but -you can set that up by hand if you need to). - -For tools that cannot autodetect the JDK via `PATH`, you may need to set -`JAVA_HOME` to `/opt/jdk1.7.0_45`. diff --git a/wiki/java/install/index.md b/wiki/java/install/index.md deleted file mode 100644 index 684f050..0000000 --- a/wiki/java/install/index.md +++ /dev/null @@ -1,11 +0,0 @@ -# Installing Java … - -This document provided as a community service to -[##java](irc://irc.freenode.org/##java). Provided as-is; pull requests -welcome. - -1. [… on Ubuntu](ubuntu) (may also be applicable to Debian; needs verification - from a Debian user) - -2. [… on CentOS](centos) (probably also applicable to RHEL; needs verification - from a RHEL user) diff --git a/wiki/java/install/ubuntu.md b/wiki/java/install/ubuntu.md deleted file mode 100644 index 75d3478..0000000 --- a/wiki/java/install/ubuntu.md +++ /dev/null @@ -1,84 +0,0 @@ -# Installing Java on Ubuntu - -Accurate as of: Java 7, Ubuntu 12.04. The instructions below assume an amd64 -(64-bit) installation. If you're still using a 32-bit OS, work out the -differences yourself. - -## Via Package Management (Apt) - -OpenJDK 7 is available via apt by default. - -To install the JDK: - - sudo aptitude update - sudo aptitude install openjdk-7-jdk - -To install the JRE only (without the JDK): - - sudo aptitude update - sudo aptitude install openjdk-7-jre - -To install the JRE without GUI support (appropriate for headless servers): - - sudo aptitude update - sudo aptitude install openjdk-7-jre-headless - -(You can also use `apt-get` instead of `aptitude`.) - -These packages interact with [the `alternatives` -system](http://manpages.ubuntu.com/manpages/hardy/man8/update-alternatives.8.html), -and have [a dedicated `alternatives` manager -script](http://manpages.ubuntu.com/manpages/hardy/man8/update-java-alternatives.8.html). -The `alternatives` system affects `/usr/bin/java`, `/usr/bin/javac`, and -browser plugins for applets and Java Web Start applications for browsers -installed via package management. It also affects the symlinks under -`/etc/alternatives` related to Java. - -To list Java versions available, with at least one Java version installed via -Apt: - - update-java-alternatives --list - -To switch to `java-1.7.0-openjdk-amd64` for all Java invocations: - - update-java-alternatives --set java-1.7.0-openjdk-amd64 - -The value should be taken from the first column of the `--list` output. - -### Tool support - -Most modern Java tools will pick up the installed JDK via `$PATH` and do not -need the `JAVA_HOME` environment variable set explicitly. For applications old -enough not to be able to detect the JDK, you can set `JAVA_HOME` to -`/usr/lib/jvm/java-1.7.0-openjdk-amd64`. - -## By Hand - -The [Java SE Development Kit -7](http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html) -tarballs can be installed by hand. Download the “Linux x64” `.tar.gz` version, -then unpack it in `/opt`: - - cd /opt - tar xzf ~/jdk-7u45-linux-x64.tar.gz - -This will create a directory named `/opt/jdk1.7.0_45` (actual version number -may vary) containing a ready-to-use Java dev kit. - -You will need to add the JDK's `bin` directory to `PATH` if you want commands -like `javac` and `java` to work without fully-qualifying the directory: - - cat > /etc/profile.d/oracle_jdk <<'ORACLE_JDK' - PATH="${PATH}:/opt/jdk1.7.0_45/bin" - export PATH - ORACLE_JDK - -(This will not affect non-interactive use; setting PATH for non-interactive -programs like build servers is beyond the scope of this document. Learn to use -your OS.) - -Installation this way does _not_ interact with the alternatives system (but -you can set that up by hand if you need to). - -For tools that cannot autodetect the JDK via `PATH`, you may need to set -`JAVA_HOME` to `/opt/jdk1.7.0_45`. diff --git a/wiki/java/kwargs.md b/wiki/java/kwargs.md deleted file mode 100644 index d745010..0000000 --- a/wiki/java/kwargs.md +++ /dev/null @@ -1,152 +0,0 @@ -# Keyword Arguments in Java - -## What - -Java arguments are traditionally passed by position: - - void foo(int x, int y, int z) - -matches the call - - foo(1, 2, 3) - -and assigns `1` to `x`, `2` to `y`, and `3` to `z` in the resulting -activation. Keyword arguments assign values to formal parameters by matching -the parameter's name, instead. - -## Why - -Fuck the builder pattern, okay? Patterns like - - Response r = Response - .status(200) - .entity(foo) - .header("X-Plane", "Amazing") - .build(); - -(from JAX-RS) mean the creation and maintenance of an entire separate type -just to handle arbitrary ordering and presence/absence of options. Ordering -can be done using keywords; presence/absence can be done by providing one -method for each legal combination of arguments (or by adding optional -arguments to Java). - -The keyword-argument version would be something like - - Response r = new Response( - .status = 200, - .entity = foo, - .headers = Arrays.asList(Header.of("X-Plane", "Amazing")) - ); - -and the `ResponseBuilder` class would not need to exist at all for this case. -(There are others in JAX-RS that would still make `ResponseBuilder` mandatory, -but the use case for it gets much smaller.) - -As an added bonus, the necessary class metadata to make this work would also -allow reflective frameworks such as Spring to make sensible use of the -parameter names: - - <bean class="com.example.Person"> - <constructor-arg name="name" value="Erica McKenzie" /> - </bean> - -## Other Languages - -Python, most recently: - - def foo(x, y, z): - pass - - foo(z=3, x=1, y=2) - -Smalltalk (and ObjectiveC) use an interleaving convention that reads very much -like keyword arguments: - - Point atX: 5 atY: 8 - -## Challenges - -* Minimize changes to syntax. - * Make keyword arguments unambiguous. -* Minimize changes to bytecode spec. - -## Proposal - -Given a method definition - - void foo(int x, int y, int z) - -Allow calls written as - - foo( - SOME-SYNTAX(x, EXPR), - SOME-SYNTAX(y, EXPR), - SOME-SYNTAX(z, EXPR) - ) - -`SOME-SYNTAX` is a production that is not already legal at that point in Java, -which is a surprisingly frustrating limitation. Constructs like - - foo(x = EXPR, y = EXPR, z = EXPR) - -are already legal (assignment is an expression) and already match positional -arguments. - -Keyword arguments match the name of the formal argument in the method -declaration. Passing a keyword argument that does not match a formal argument -is a compilation error. - -Calls can mix keyword arguments and positional arguments, in the following -order: - -1. Positional arguments. -2. Varargs positional arguments. -3. Keyword arguments. - -Passing the same argument as both a positional and a keyword argument is a -compilation error. - -Call sites must satisfy every argument the method/constructor has (i.e., this -doesn't imply optional arguments). This makes implementation easy and -unintrusive: the compiler can implement keyword arguments by transforming them -into positional arguments. Reflective calls (`Method.invoke` and friends) can -continue accepting arguments as a sequence. - -The `Method` class would expose a new method: - - public List<String> getArgumentNames() - -The indexes in `getArgumentNames` match the indexes in `getArgumentTypes` and -related methods. - -Possibilities for syntax: - -* `foo(x := 5, y := 8, z := 2)` - `:=` is never a legal sequence of tokens in - Java. Introduces one new operator-like construct; the new sequence `:=` - “looks like” assignment, which is a useful mnemonic. - -* `foo(x ~ 5, y ~ 8, z ~ 2)` - `~` is not a binary operator and this is never - legal right now. This avoids introducing new operators, but adds a novel - interpretation to an existing unary operator that's not related to its - normal use. - -* `foo(.x = 5, .y = 8, .z = 2)` - using `=` as the keyword binding feels more - natural. Parameter names must be legal identifiers, which means the leading - dot is unambiguous. This syntax is not legal anywhere right now (the dot - always has a leading expression). The dot is a “namespace” symbol already. - -To support this, the class file format will need to record the names of -parameters, not just their order. This is a breaking change, and generated -names will need to be chosen for existing class files. (This may be derivable -from debug information, where present.) - - -## Edge Cases - -* Mixed positional and keyword arguments. - * Collisions (same argument passed by both) are, I think, detectable at - compile time. This should be an error. -* Inheritance. It is legal for a superclass to define `foo(a, b)` and for - subclasses to override it as `foo(x, y)`. Which argument names do you use - when? -* Varargs. diff --git a/wiki/java/stop-using-class-dot-forname.md b/wiki/java/stop-using-class-dot-forname.md deleted file mode 100644 index b01e972..0000000 --- a/wiki/java/stop-using-class-dot-forname.md +++ /dev/null @@ -1,69 +0,0 @@ -# JDBC Drivers and `Class.forName()` - -The short version: stop using `Class.forName(driverClass)` to load JDBC -drivers. You don't need this, and haven't since Java 6. You arguably never -needed this. - -This pattern appears all over the internet, and it's wrong. - -## Backstory - -JDBC has more or less always provided two ways to set up `Connection` objects: - -1. Obtain them from a driver-provided `DataSource` class, which applications or - containers are expected to create for themselves. - -2. Obtain them by passing a URL to `DriverManager`. - -Most people start with the latter, since it's very straightforward to use. -However, `DriverManager` needs to be able to locate `Driver` subclasses, and -the JVM doesn't permit class enumeration at runtime. - -In the original JDBC release, `Driver` subclasses were expected to register -themselves on load, similar to - - public class ExampleDriver extends Driver { - static { - DriverManager.registerDriver(ExampleDriver.class); - } - } - -Obviously, applications _can_ force drivers to load using -`Class.forName(driverName)`, but this hasn't ever been the only way to do it. -`DriverManager` also provides [a mechanism to load a set of named classes at -startup](https://docs.oracle.com/javase/8/docs/api/java/sql/DriverManager.html), -via the `jdbc.drivers` [system property](http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html). - -## JDBC 4 Fixed That - -JDBC 4, which came out with Java 6 in the Year of our Lord _Two Thousand and -Six_, also loads drivers using the [service -provider](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Service%20Provider) -system, which requires no intervention at all from deployers or application -developers. - -_You don't need to write any code to load a JDBC 4 driver._ - -## What's The Harm? - -It's harmless in the immediate sense: forcing a driver to load immediately -before JDBC would load it itself has no additional side effects. However, it's -a pretty clear indicator that you've copied someone else's code without -thoroughly understanding what it does, which is a bad habit. - -## But What About My Database? - -You don't need to worry about it. All of the following drivers support JDBC -4-style automatic discovery: - -* PostgreSQL (since version 8.0-321, in 2007) - -* Firebird (since [version 2.2, in 2009](http://tracker.firebirdsql.org/browse/JDBC-140)) - -* [MySQL](../mysql/choose-something-else) (since [version 5.0, in 2005](http://dev.mysql.com/doc/relnotes/connector-j/en/news-5-0-0.html)) - -* H2 (since day 1, as far as I can tell) - -* Derby/JavaDB (since [version 10.2.1.6, in 2006](https://issues.apache.org/jira/browse/DERBY-930)) - -* SQL Server (version unknown, because MSDN is archaeologically hostile) |
