From 76aed6ef732de38d82245b3d674f70bab30221e5 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Fri, 3 Jul 2015 22:31:49 -0400 Subject: Fuck it, serve the files directly. --- .html/java/_list.html | 101 ++++++++++++ .html/java/a-new-kind-of.html | 203 ++++++++++++++++++++++++ .html/java/index.html | 101 ++++++++++++ .html/java/install/_list.html | 96 ++++++++++++ .html/java/install/centos.html | 136 ++++++++++++++++ .html/java/install/index.html | 102 ++++++++++++ .html/java/install/ubuntu.html | 158 +++++++++++++++++++ .html/java/kwargs.html | 223 +++++++++++++++++++++++++++ .html/java/stop-using-class-dot-forname.html | 155 +++++++++++++++++++ 9 files changed, 1275 insertions(+) create mode 100644 .html/java/_list.html create mode 100644 .html/java/a-new-kind-of.html create mode 100644 .html/java/index.html create mode 100644 .html/java/install/_list.html create mode 100644 .html/java/install/centos.html create mode 100644 .html/java/install/index.html create mode 100644 .html/java/install/ubuntu.html create mode 100644 .html/java/kwargs.html create mode 100644 .html/java/stop-using-class-dot-forname.html (limited to '.html/java') diff --git a/.html/java/_list.html b/.html/java/_list.html new file mode 100644 index 0000000..4b6c78f --- /dev/null +++ b/.html/java/_list.html @@ -0,0 +1,101 @@ + + + + + The Codex » + ls /java + + + + + + + + +
+ + + + + +
+

ls /java

+ + +
+

Directories

+ +
+ + + + + + + +
+ + + + + + + + +
+ + \ No newline at end of file diff --git a/.html/java/a-new-kind-of.html b/.html/java/a-new-kind-of.html new file mode 100644 index 0000000..764fb45 --- /dev/null +++ b/.html/java/a-new-kind-of.html @@ -0,0 +1,203 @@ + + + + + The Codex » + A New Kind of Java + + + + + + + + +
+ + + + + +
+

A New Kind of Java

+

Java 8 is almost here. You can play with the early access +previews 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 package, designed by the folks +behind the extremely capable Joda time library; reflective +access to parameter names; Unicode +6.2 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. +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.

+
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file diff --git a/.html/java/index.html b/.html/java/index.html new file mode 100644 index 0000000..4b6c78f --- /dev/null +++ b/.html/java/index.html @@ -0,0 +1,101 @@ + + + + + The Codex » + ls /java + + + + + + + + +
+ + + + + +
+

ls /java

+ + +
+

Directories

+ +
+ + + + + + + +
+ + + + + + + + +
+ + \ No newline at end of file diff --git a/.html/java/install/_list.html b/.html/java/install/_list.html new file mode 100644 index 0000000..4af64c6 --- /dev/null +++ b/.html/java/install/_list.html @@ -0,0 +1,96 @@ + + + + + The Codex » + ls /java/install + + + + + + + + +
+ + + + + +
+

ls /java/install

+ + + + + + + + +
+ + + + + + + + +
+ + \ No newline at end of file diff --git a/.html/java/install/centos.html b/.html/java/install/centos.html new file mode 100644 index 0000000..9bbf3f4 --- /dev/null +++ b/.html/java/install/centos.html @@ -0,0 +1,136 @@ + + + + + The Codex » + Installing Java on CentOS + + + + + + + + +
+ + + + + +
+

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, from +the Fedora project. Install EPEL before proceeding.

+

You didn't install EPEL. Go install EPEL. The directions are in the EPEL +FAQ.

+

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 +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.

+
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file diff --git a/.html/java/install/index.html b/.html/java/install/index.html new file mode 100644 index 0000000..d167e58 --- /dev/null +++ b/.html/java/install/index.html @@ -0,0 +1,102 @@ + + + + + The Codex » + Installing Java … + + + + + + + + +
+ + + + + +
+

Installing Java …

+

This document provided as a community service to +##java. Provided as-is; pull requests +welcome.

+
    +
  1. +

    … on Ubuntu (may also be applicable to Debian; needs verification + from a Debian user)

    +
  2. +
  3. +

    … on CentOS (probably also applicable to RHEL; needs verification + from a RHEL user)

    +
  4. +
+
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file diff --git a/.html/java/install/ubuntu.html b/.html/java/install/ubuntu.html new file mode 100644 index 0000000..0d81292 --- /dev/null +++ b/.html/java/install/ubuntu.html @@ -0,0 +1,158 @@ + + + + + The Codex » + Installing Java on Ubuntu + + + + + + + + +
+ + + + + +
+

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, +and have a dedicated alternatives manager +script. +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 +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.

+
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file diff --git a/.html/java/kwargs.html b/.html/java/kwargs.html new file mode 100644 index 0000000..64cc16b --- /dev/null +++ b/.html/java/kwargs.html @@ -0,0 +1,223 @@ + + + + + The Codex » + Keyword Arguments in Java + + + + + + + + +
+ + + + + +
+

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. +
  3. Varargs positional arguments.
  4. +
  5. Keyword arguments.
  6. +
+

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.
  • +
+
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file diff --git a/.html/java/stop-using-class-dot-forname.html b/.html/java/stop-using-class-dot-forname.html new file mode 100644 index 0000000..85190e8 --- /dev/null +++ b/.html/java/stop-using-class-dot-forname.html @@ -0,0 +1,155 @@ + + + + + The Codex » + Stop Using Class Dot Forname + + + + + + + + +
+ + + + + +
+

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. +
  3. +

    Obtain them by passing a URL to DriverManager.

    +
  4. +
+

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, +via the jdbc.drivers system property.

+

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 +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:

+ +
+ + + +
+
+ + +comments powered by Disqus +
+ + + + + +
+ + \ No newline at end of file -- cgit v1.2.3