Well. True, to a degree, I suppose, but whoever this Tim Bray guy is adds some pretty important context. He co-authored the XML spec and was director of web technologies at Sun. You know, the people who made Java and promoted it as a web technology. Going out on a limb here, but it doesn't seem to me that the man is a Java newbie.
The point of Bray's rant, I'd suggest, is that these tools largely haven't gotten any easier since 2004. It frequently seems to be controversial in these parts to assert that it's worthwhile to make developer tools easy to use ("what you're complaining about is obviously easily addressed by whipping together something with bash, awk and sed and therefore isn't a pain point at all, you whiner"), which has always vaguely irritated me. A toolchain which requires you to wrangle it into place for every project is a toolchain which could benefit from usability improvements.
Fundamentally, I think the problem is arrogance – companies like Oracle or Sun historically assumed that their products are so important that it's someone's full-time job to deal with the rough edges, they've invested in training or reading massive doc dumps, etc. – familiar to anyone who's heard tales of mainframe operators with run books of canned solutions for each problem. Those HN commentators have the same blindspot.
In addition to usually being flat-out wrong, as the more common user is someone who just needs to do what should be a simple task which is blocking their actual real job, this ignores how profligately that mindset wastes other peoples' time and how it sets a dangerous long-term precedent where alternatives look attractive because everyone simply assumes e.g. Java, Solaris, Oracle's database etc. is hard to use and expensive.
Installing updates is a complete trainwreck for almost
every product they've ever released and that's one of the
most basic tasks for a software vendor."
Also, your generalisations about 'no cultural tradition of taking toolchain usability seriously' are simply not true, I can show you plenty of tools where clearly whoever was working on them did care about usability.
With that said, I'm sure you're just venting and didn't mean what you said "literally"...
I've used both Sun and Oracle products since the mid-90s. The only one which I can recall seeming to respect my time was DTrace and maybe ZFS. Oracle is by far worse (updates shipped as a flat ZIP file with text instructions where to install them?) but both really left the impression that they assumed my time was cheaper than them hiring a packaging engineer.
You claimed none of their products ever showed any care about usability. Yet, at last check, they all had fairly extensive documentation, accessibility work done to them, and clearly do many things that consider the user experience.
Like I said, you're clearly venting. Consider being more constructive in your comments, or at least focusing on something specific instead of just ranting.
Then it's a good thing I didn't do that. I've used a number of products from both company, ranging in price from free to suites which come with 6 figure annual support contracts.
> You claimed none of their products ever showed any care about usability. Yet, at last check, they all had fairly extensive documentation, accessibility work done to them, and clearly do many things that consider the user experience.
Allow me to quote what I actually said:
> both Sun and Oracle have no cultural tradition of taking toolchain usability seriously
That's not saying that they don't do things like, say, accessibility as required to get government contracts. What I was talking about is that all of the products seemed to assume that their product was so compelling that we would be willing to invest considerable resources doing the kind of support which other vendors do as part of their job.
At multiple employers, having spent 6-8 figures on Oracle database or enterprise business applications, we used to get things like critical security updates delivered as a ZIP file with instructions for where to copy files and what permissions to set them. Sure, it's not that hard to roll a pkg, rpm, etc. but why should every customer need to do that?
During the year I spent supporting that mess, our half-million-year contract didn't once get a support engineer who fixed a problem, or could even troubleshoot it without my hand-holding them through reading the error messages and eventually entering a ticket. At every point the answer was to install the latest version or reinstall what we already had, which was a long manual process with tons of hand redundant configuration in many places (many daemons on many servers). Having documentation telling you to open an XML file here and add certain blocks of text with values matching this plist over there is extensive but is not usable.
Sun wasn't as bad but they weren't well organized. Brand new V40z servers arrive with Solaris 10. The updater rendered them unbootable. Support says to try the install again, which produces the same result. Calling our sales guy says this is a known problem and they can have a systems engineer help walk us through patching a bunch of stuff by hand so the updater won't break it – great, they're supporting us but … who's paying us for the hours spent on something which would literally take 5 minutes for their QA team to reproduce? If we had thousands of them and a strong case for Solaris we might have been able to justify the time investment but it took 20 minutes to have the systems in production running Debian Linux and we spent less time on OS support over the life of hardware than trying to get a core feature to work once.
With that said, I still disagree with your conclusion that Sun and Oracle has no "cultural tradition of taking toolchain usability seriously". Again, I strongly disagree and believe that does not apply to all products or projects.
Perhaps it doesn't apply to the degree that you want, but you are claiming that it doesn't exist at all, and I can assure you that was / is not the case based on people I know that have worked on many of those projects.
At multiple employers, having spent 6-8 figures on Oracle
database or enterprise business applications, we used to
get things like critical security updates delivered as a
ZIP file with instructions for where to copy files and
what permissions to set them. Sure, it's not that hard to
roll a pkg, rpm, etc. but why should every customer need
to do that?
Sun wasn't ... it took 20 minutes to have the systems in
production running Debian Linux and we spent less time on
OS support over the life of hardware than trying to get a
core feature to work once.
If that's even mildly interesting to you, there's a website where both the FOSS source code for the new packaging system and the reasoning behind it is available:
The "Background Reading" section on that page has several helpful links that talk about the reasoning and philosophy behind it.
Solaris 11+ has a great update story compared to pretty much any UNIX-like system out there today. To update to the next release of the operating system, it's generally as simple as:
1) newest "package catalog" is retrieved from the configured package repositories (local and/or remote)
2) determines which packages are installed, and what all of the newer versions of those packages are
3) parses dependencies of all packages involved to establish the transitive closure of the dependency graph
4) transforms dependencies into a set of boolean statements that can be evaluated by minisat, the boolean satisfiability solver that's used
5) takes the solution (if one is available) provided by the solver and then maps that to the equivalent set of packages
6) retrieves package manifests for all packages that will be upgraded, added, or modified
7) determines differences between installed version and target version ensuring that only files that have changed between package versions are retrieved and only files that need to be updated, installed, or removed are modified
8) organises differences based on the order they need to be executed as a single set ignoring package boundaries, performing reference counting and conflict checking
9) retrieves only the files that will be upgraded or installed as part of the operation
10) determines if the operation can be safely performed on the live system, if it cannot, it will create a snapshot of the root filesystem and clone it, otherwise, it will take a snapshot of the filesystem as a precaution before execution
11) executes planned operation, executes commands that prepare new boot environment for use, etc.
12) if operation succeeds, new boot environment (if applicable) is activated
Or put more simply, when you execute 'pkg update' on Solaris 11+, generally only a copy of the system is updated. So if the update fails, you can just pick an older boot environment from the GRUB2 menu and be right back to a working system in moments.
The other big difference from all of this, as an example, is that the package system is capable of upgrading from any older version of Solaris to any newer version of Solaris.
There are no patch readmes or zip files; administrators just update from one version to the next -- the system figures out the rest. It even knows when upgrades require a firmware update.
Not even "specifically"; these updating woes rarely exist on platforms where you have a proper package manager (be it APT or YUM or Zypper or Pacman or Homebrew or whatever). Software devs shouldn't have to worry about writing updaters, since updating should be handled by the OS.
Linux distributions have the same problem so I don't understand the downvotes.
For example, the vim package name is 'editor/vim'. A similar naming scheme is used for almost every package.
In other words, Java wont search the internet for you.
The other classic example is the increasingly popular multi-cursor editing editors, which should be a giant red flag over the lack of expression in the programming language. What happens is they make it almost tolerable, and the incentives to improve are thus diminished greatly, to the point the problem will be ignored by most.
> Maven is that toolchain.
If we bundled maven or maven-like functionality into the Java core it would slow down the release schedule and destroy the productively competitive build tool ecosystem we have at the moment. What is it you think we'd gain?
I used to think this, but Go changed my mind. Like Go or not, its an excellent example of awesome tooling.
Go run/build/install/vet/test make my life to much easier than it used to be in Java/C/++ world (and C# tool because I'm not enslaved to VS for my teams tooling).
It's awesome tooling now. Most of the Python standard library was awesome when it was written. My concern is that it will stagnate as time goes on.
This is how old languages work. You want a nice language? Switch! People get Scala working on Android, I hear.
That's not really true. I was doing professional Java development in 2004. Nowadays we have things like Dropwizard and Play.
It sounds like Bray was intentionally trying to use just the Oracle-provided tools and libraries. If he wanted to do that he'd been better off with Play. That's a single distribution designed for exactly his use case: simple OOTB text editor scripting, no compilation, no deployment, lots of stuff built in, just go.
If you refuse to download Play out of some misguided principle that everything must be OOTB by the core language provider, then (a) that's arbitrary and (b) you're misunderstanding the design principle of low-level languages like Java and C++ that have enabled them to stick around for so long. They don't bake in (as many) opinions. Play does, which makes it easier OOTB. So does Dropwizard. Take your pick, they're all "Java". That's the beauty of it.. it can address a very wide range of needs from "I just want to get something done" to "I want to control every detail very close to the metal".
I'm partly joking, but I'd be hiding in shame if I had inflicted either of those things upon the world (that is the XML spec, and Java's web technologies, especially JSF and J2EE).
Now, it could just be me, I never found Tim Bray's posts interesting, and this is a case in point. The same blog post could have come from any random guy trying to run a Java app on the commandline. It might be a valid complaint for the status of java packages, but it's not insightful at all.
It's nothing wrong with Java the language, but the platform just seems to make common UNIX best practices hard.
Edit: Just remembered Kafka is Scala, not Java, but I think it just supports my asssertion that the Java/JVM ecosystem just makes common best practices hard.
That said, java is a special bit of shit. Those shell scripts are really complex. Most java shops have had problems with classpaths exceeding the 32k limit in shells! And java is yet another language where the morons who run it refuse to sand off some of the really sharp edges most likely because their heads are in their asses. To give two really simple examples:
1 - why the fuck can't I import a directory full of jars? eg
2 - a nullsafe repeated dereference operator, like groovy. If I'm pulling out a.b.c.d out of a nested object, in real code, I have to say if
String address = null;
if (a != null)
if (a.b != null)
if(a.b.c != null)
if(a.b.c.d != null)
address = a.b.c.d.address;
// vs groovy
String address = a?.b?.c?.d?.address;
And for java, the combination of ant, maven, ivy, etc, are a special set of hell.
Subdirectories are not searched recursively.
1 - why can't I import a directory full of jars? eg
or better yet, recursively descend
-cp "$(print -l ./lib/jars/**/*.jar | tr '\n' :)"
Use the -Djava.ext.dirs command line flag to do it.
> like Groovy [...] String address = a?.b?.c?.d?.address
The Groovy backers have been talking for years every now and then about making ?. ripple though the . after it, so using a?.b.c.d.address would have the same effect as a?.b?.c?.d?.address , but nothing ever gets done. Better look for a language solution being actively maintained for its original purpose, instead of its backers going off on tangents looking to entangle itself in every pie.
You are doing it wrong then.
So, besides the use of a BS idiom "you're doing it wrong", the parent comment doesn't add much value to the discussion.
Java is FINALLY adding Lambda functions (a lackluster implementation at that), but guess what? There already exist billions of lines of code written in "noun based" Java.
Our shop has a client that refuses to upgrade from Java 5. There's no chance in hell this project sees a Lambda.
Java through 1.7 does not even have functions, the closest thing you can get is to write a class and give it a static method (which of course is not a closure).
AFAIK in Java 1.8 you still cannot define or call functions outside of a class. So it's still "noun based."
cat /proc/28014/environ | tr \\000 \\n
This is partly a technology problem, partially a philosophy problem (Java does not have a scripting language heritage which counsels e.g. having a REPL or really obvious options for program invocation), and partly a marketing problem. I rather doubt that anyone at Oracle has the job "Make people's first experience with Java suck less." Web devs thankfully have standardized on "batteries included; max five minutes to install" for new platforms in the last few years (Rails strikes me as the conspicuous first example, and ironically is harder to install now than it used to be).
Most of which comes down to the fact that official documentation for first-time users is somewhere on the spectrum of nonexistent to crappy. Many languages have pretty good tools for managing virtual environments and dependencies and such these days, but odds are that a new user won't find out about them for quite some time unless they know to go looking.
Here's the manual page for calling an HTTPS service . You just call WS.url("https://example.com").get(). And if it's a self-signed certificate then it's more or less one line in a config file to add it. That's about as easy as it gets short of deliberately making HTTPS insecure.
My experience: I very quickly evolved beyond this case and prefer the robustness of standard Java with the convenience of a bundle like Dropwizard . Dropwizard packages up and glues together various best-of-breed libraries for building services. That was the real pain point for me, not so much having to use an IDE.
I guess it doesn't slow me down, because I know the unit test 'trick', in the same way as I know how to get Light Table to execute arbitrary s-expressions to get around Clojures load times has meant that I'm far less obsessed with Clojures slow startup.
Its a problem, sure, but I don't think Java is broken, its just never had the CLI in mind.
Exactly. JUnit is your "command line" (and your REPL) for Java.
It's why I still don't use Clojure significantly (or even ClojureScript), even though I really like the language. Things just break or simply never work and it appears random. Other environments I use get a lot less wrong (although node is pretty bad too).
As for the JVM "just breaking", I can't agree with that. The JVM is an impressive piece of engineering and I'm very glad I can make use of it in Clojure, rather than deal with half-baked attempts at building yet another VM (reference counting, anyone?).
"The Most Dangerous Code in the World:
Validating SSL Certiﬁcates in Non-Browser Software"
Having said that (snarky response) having worked with Java from 1.1, I think the language is moving in the right direction. The latest release (8) adds a ton of syntactic sugar and there is a real impetus towards easier more dev friendly features.
Plus Java needs a non-backwards compatible version soon. I suggest Java X be that where it gets rid of a lot of the cruft that has built up.
Not to mention that the O'Reilly book for Perl6+Parrot doesn't have a parrot, or even a camel. Deal-breaker right there ;)
Java is a decent language but its developers have way too much tolerance for pointless hoopjumping.
The command line is a bit quirky, but I think like anything else in java, we typically solve it with libraries like args4j. It's not the best situation, and there's lots of ways to do things.
That being said, whether you consider this stockholm syndrome or not, I'm used to the quirkiness and it doesn't really affect my day to day. Could I be as productive had java had better features/support? yes. Is it that much of a non starter? I think it's just like any situation, use what makes sense for the job.
The complaint about overstrict PKI libraries is spot on as well. Dealing with Java's PKI infrastructure for https URLs, etc, in a systems level setting where, you know what, sometimes the CN on the cert ain't gonna match the internal name, is a huge pain. Other languages are actually pretty bad about this too, and so too often I resort to calling out to curl -k because it'll just shut up and do what needs to be done.
It's clear that this is all because Java is built around the assumption that you're creating a big program and you're going to use an IDE and you're willing to deal with multiple steps before you have something that'll run on the server. That's fine and dandy. If the Java community wants Java to be more useful for smaller tasks, then Tim's complaints here are dead on target. But if not, I long ago gave up trying to use Java in this way, and I think Tim should do the same.
The default in other languages is often to not do any certificate validation.
That seems like the worse approach since no-one can tell their code is insecure. Maybe fine for a scripting tool, but I wouldn't want that on my production boxes.
I'm not sure why every language needs to be useful as a scripting tool. If there are things that help the common case and also scripting (eg classpaths being a pain), there's obviously an argument for "why the fuck hasn't this been fixed yet", but in other cases there are either fundamental tradeoffs or resource constraints.
"Easy things should be easy, and hard things should be possible." -- Larry Wall
One of the reasons why I switched from Java to Perl. I didn't feel that easy things were easy in Java, and I don't run into enough hard problems on a daily basis to justify the verbosity and masochism involved.
On the other, I've spent a good chunk of time just reading other people's code, and I've come to appreciate really straight forward verbose code.
So I am a bit biased against the Perl I've seen, since it is generally not written with ease of understanding as a priority.
That said, too much verbosity can introduce the same problem of unreadability by making important things harder to identify. There's an important balance between verbosity and terseness that should always be considered.
First of all, it took me forever to figure out the java
command-line incantations to tell it that it needed my
project’s class files and the json.org library (which I’d
already downloaded so I could compile the sucker). Yeah,
I used to know that stuff ten years ago, but there really
shouldn’t be any complexity here.
Especially used of tricks that are so poorly documented
that they must be learned from a wizard.
If you need more than one addition, do you use a colon separated list (Unix), semicolon (Windows), or repeat it once per option? Does it expand ~ or do you need to
None of this is that hard but if you don't use this all the time it's easy for everyone's soup of almost-but-not-quite similar conventions to blur together and you waste time figuring it out.
In the Java world you have the added problem that the JVM has a legacy convention which doesn't follow any platform standard and the problem that many projects use different conventions so you probably also have a different set of rules for JVM options and the actual program options.
This is just a rant and personally I can't sympathize with. How that is a newsworthy is another issue, though.
1. Launching Java Programs can suck
2. Java defaults to secure on https requests.
First, on #2, yeah, really cant do anything here. If they didnt do this way, it would be reported as another vulnerability in the JVM that they would have to patch.
On #1, this is actually an old problem that I had worked on this years ago and i even published the solution in javanet (remember that?). If there is any interest in this, i can revive the project since its been dead for nearly 10 years. (http://web.archive.org/web/20070724060104/https://launcher.d...)
Basically I had a custom classloader read the lib dir that worked similarly to tomcat's classloader. Dump any jars/wars/etc in there that you want. All you had to do was tell me where the main class was (because a lot of jars have testing Main built into it and i wouldnt know which one you wanted to run).
$CLASSPATH is purely runtime, so it's all the fun of dynamic linking, all the time. Monolithic shaded JARs can solve this problem but introduce some of their own.
The only reason it's not quite as bad in .NET is that it can usually reference at least the framework in a well-known location.
But generally, whatever you call the problem that $CLASSPATH is designed to solve (assembly binding, reference resolution), it's an unsolved problem.
HTTPS is built on top of PKI, which involves a list of trusted root authorities who verify that the certificate for blahblah.com is actually for blahblah.com. A self-signed certificate won't have that, and any application that doesn't validate that the certificate is signed by a trusted authority and not expired, etc. has no security.
If an application doesn't validate it's certificate, anybody sitting between you and the HTTPS server can step in between you and your traffic, give you a phony certificate, and then proxy all your "secure" traffic to the HTTPS server. And, of course, "sitting between you and the HTTPS server" means not only the NSA with their low-latency network specifically built to conduct these types of attacks, it also means the guy in the corner at Starbucks too (because WiFi is a radio).
Java only actually started checking if certificates were valid very recently (IIRC it was J7, r51). Prior to that, Java was just as lax as every other toolkit---probably specifically to address complaints like Bray's: "testing HTTPS is tough".
Besides ... why can't java just pull the certs out of the system (like you did manually) or ship with them like every browser does (I presume).
I agree that Java should use the certs the system provides, and that is a PITA to wrestle with keytool, but I also know that the self-signed cert that apache is using is not trusted by your PC either (so you've got work to do regardless).
Java runs as compiled bytecode, not interpreted script. Try "mvn exec:java". If you're not using Maven, you're likely making this ridiculously harder than it needs to be. (And yes, Maven sucks too, but it's also pretty good).
I do think a KeyBase Java client is a good idea though! Can't wait to see the results.
java -jar foobar.jar
Java's SSL handling is definitely annoying, though. But I think it's better than how other languages do it which is to simply bypass cert validation.
Also, I don't think it's fair to lump anything Android-related into complaints about Java. Google yoinked the Java syntax and the name and then added their own stack underneath.
My main pain point with Java is dependency management and builds. I don't like any of the systems out there. After years of Ant, Ivy, and Maven, I've just resigned myself to using Eclipse and downloading JARs manually, storing them with the code. It's ugly but not as ugly as Maven.
The script target creates a runnable shell script that has the jar and all dependencies embedded. The last step might be using packr to also embed the java runtime.
you can create a new project with from a maven archetype that has log4j and Spring set up for you. A centipede application contains a bunch of little command line applications that are defined simply by writing classes that implement CommandLineApplication; Spring automatically finds all of these and makes them available.
Centipede also defines a per-user configuration mechanism that means you have no excuse to hardwire database passwords into your version control.
You can see this in the SSL Labs simulator, in the bottom part of the report. Clicking "Java 7" will show the cipher suites available by default.
I feel like I'm missing something.
You might want to check your hearing, because this is Tim Bray.
He is trying to load this URL:
This URL is not self signed and loads fine as a valid cert in a browser. In the Java application it throws an exception about a bad handshake. I believe this is because Java 7 and 8 ship with less trusted certificate authorities than browsers do.
I forked his project and made it easy to run via the command line without Android if anyone wants to try it out:
Just clone the repo and execute "./run.sh something"
Good luck trying to compile a C project without autotools/make either.
gcc test.c -o test
Easy to run, too:
is equally easy and unrealistic.
The Java + Clojure + JRuby ecosystem has been very good to me. That said, I have been spending more time writing Haskell code that anything else this year and being away frmm the JVM, and being able to build compact executables is a breath of fresh air, especially since I am looking at Haskell now more as a strongly typed and perhaps better Lisp.
These were the types of problems dynamic JVM language Groovy was created back in 2003 to solve. If only Groovy had stuck to its knitting when the new management, er, took over from its creator a few years later, it would still be a solution. Unfortunately, Groovy diversified into providing CompileStatic tags to compete with Java, DSL syntax to compete with Maven, a MOP to compete with Rails, and AST annotation hooks to compete with Lisp. It's now become obsolete for its original purpose of JVM scripting, missing the Java 8 boat despite several years advance warning, as well as being at best 2nd fiddle but usually 9th fiddle at the stuff it tried diversifying into.
if you use intellij or another good ide it'll package it up for you with a execute script
(gradle's application/java plugin also do this)
manual classpath supplying is not advised
Which overriding is a bit of black magic.
exec java $JAVA_OPTS -jar "$0" "$@"
the best way to distribute a package is to create a proper package for each plateform and encapsulate any java "gimmick".
java -jar Product.jar
rhodey@rhodey$ mvn package
rhodey@rhodey$ java -jar <package-name>.jar <command line options>
A pom.xml at least has a schema and tons of copy/paste examples. Every language sucks in it's own way.
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
He wants to run a smoke test on a library he's writing. He doesn't want to run a full-blown application just to test his library, or to have to plug in a device to test his library. He wants to open up a terminal, type "java test KeybaseLib" (or something like that) and have it just work.
So, I don't think go is a scripting language. It requires you to write a function and then call it before it will output anything.
In my mind languages tend to have an optimal code size where they work well, and what works at <1000 lines often does poorly at even 10k lines.