I would agree with that, though perhaps more about PHP than Java. We like to say "use the right tool for the job" and "you can write bad code in any language", but that's just a way of seeming egalitarian and not really dealing with the issue. It feels bad to talk about shitty programmers but they're kind of a problem.
all of his points except for one are related to the jvm in general, which most people agree doesn't suck, and then when it is time to address java he just says "scala, clojure.. are great" Yes, thats the point. The JVM is well liked, but Java as a language is not, and I don't think he did much to change anyones opinion.
I do not agree that JVM does not suck. It sucks badly. No tail calls support, no (optional and confined) unsafe pointer arithmetics, no value types and a pathetic limit on a method size makes it an extremely shitty target for any language other than Java. All the existing languages running on top of JVM are very, very inefficient, or have to pay a horrible price for being able to run reasonably fast (crap like `recur` in Clojure, for example).
edit: I suspect that none of the downvoters ever implemented a single compiler targeting JVM.
Is there a good reason for VMs to support TCO rather than having compilers perform it?
> no (optional and confined) unsafe pointer arithmetics
When do you want this? There's sun.misc.Unsafe#setMemory if you really need it.
> no value types
Might be added in JVMS 10 or some version thereafter.
> a pathetic limit on a method size makes it an extremely shitty target for any language other than Java.
True.
> All the existing languages running on top of JVM are very, very inefficient, or have to pay a horrible price for being able to run reasonably fast (crap like `recur` in Clojure, for example).
Fair enough, but it wasn't designed as a general purpose compilation target like llvm.
> Is there a good reason for VMs to support TCO rather than having compilers perform it?
Again this word! Proper tail calls handling is not an "optimisation". Optimisations are supposed to be optional, while tail calls handling makes a semantic difference.
And, no, compilers cannot do it statically. You cannot statically resolve virtual calls, for example. Consider the following trivial case:
`(define (f g x) (g x))`
> When do you want this? There's sun.misc.Unsafe#setMemory if you really need it.
Try implementing, say, an STG efficiently. Or even a WAM.
> Might be added in JVMS 10 or some version thereafter.
JVM may start to suck less at some point. But now it sucks.
> but it wasn't designed as a general purpose compilation target like llvm.
Exactly. And that's why it's inferior to the other VMs, which were designed with multiple source language semantics in mind. Including even CLR.
Why limit your VM expressive power? Restrict only untrusted loadable modules, do whatever you want in the trusted realm.
> C derived languages are already enough.
Not nearly. You won't have a managed VM with fast run-time code generation with C.
> Just because it looks like a method call, doesn't mean it is one.
Problem with intrinsics is that the majority of your optimisation passed do not know anything about them. See LLVM as an unfortunate example. Most of the SIMD intrinsics are not even used in a simplest constant folding there.
> Not nearly. You won't have a managed VM with fast run-time code generation with C.
I was speaking about security exploits. C should never have happened.
> Bingo! CLR is better. Scrap JVM.
Yes the CLR does quite a few things better than the JVM compatible VMs do currently.
However, the JVM being a specification means I can find a JVM for anything has that a CPU, from smart cards up, servers, mainframes, cars, weapon guiding systems, factory robots, anything.
So while technically better than the reference implementation, it doesn't cover the application spectrum JVM compatible VMs do.
People tend to forget that Sun (now Oracle) JDK is just the reference implementation.
> I was speaking about security exploits. C should never have happened.
I see. I sort of agree - C should never have been exposed to the programmers. But a C-level VM is an extremely useful thing for implementing high level languages. I'd rather move safety checks a number of levels up, and leave VM level to performance-related stuff.
VMs should be available in runtime (no matter if an AOT is present or not) in order to allow an efficient run-time code generation. And VMs should also be available during compilation to make it possible to efficiently implement reflective compile-time meta-languages (e.g., like Common Lisp).
And the difference between abstract machines, intermediate representations and virtual machines is very elusive (see all the confusion around LLVM for example).
The JVM is just another example of worse-is-better. If you were to actually write a high performance JIT-able cross-platform VM that supports multiple languages, it wouldn't look anything like the JVM.
The JVM worked well enough and a lot of companies put a lot of effort into it. But fundamentally, the design is "meh". It just gets the job done.
C compilers were between K&R C and ANSI C, writing portable code was #ifdef mess.
C++ compilers were even worse than C ones. Each between their own interpretations of CFront, C++ ARM and ongoing work at ANSI.
Outside UNIX world, no one cared about POSIX, which was in adoption phase anyway. So even across UNIX systems, #ifdef spaghetti code it was.
Safe system programming languages like Ada, Modula-2, Modula-3, Oberon were failing to pick up steam with the enterprise adopting UNIX variants and its two main languages C and C++.
Java brought sanity into writing portable code and better type safety.
The initial versions were surely slow, but the adoption of JIT and AOT compilation across commercial JVMs helped to adopt it.
As for the ivory towers that get written with Java, they were being written in code generators based in UML/OMT/Booch..., C, C++, Clipper and lots of 4GLs when it appeared.
It is just an enterprise sin to write such type of software.
Right now Java is slowly moving to the Third System (see the evolution from J2EE => JEE 5 => JEE 6 => JEE 7). Ditto with the mindset of Java developers of today.
TL;DR: Java as a language is not bad. The problem with Java is its bloatware ecosystem. Endemic to the Java world are uninstallability, Rube Goldberg machine code, and such heights of over-engineering that they're easily parodied:
I think the over-engineering is an unintended side effect of Java's most attractive features: incredibly stable standard ABIs, portable byte code, fantastic tooling, and a language that makes byzantine abstractions relatively easy to implement without the instability you get in C++ or the unmaintainability you get in dynamic languages. Sometimes you actually do need very high level complex abstractions, so this makes Java a fantastic language for those cases. But those cases are rare. Java makes it easy to build towers of babel that stand up, so they happen.
Java can be fine if you exercise discipline around complexity. Java coders need YAGNI and KISS tattooed on their inner eyelids more than coders in other languages.
I think that is both fair and unfair. Fair because what you say is absolutely true. But unfair because if you stick to the non-bloatware libraries, Java is very good, very fast and surprisingly productive. For me, that stack is Guava, Jetty, Jersey, Gson, Guice.
I believe though that you can make poor library choices in any language & framework. With languages that have been around for a while, there are a lot of bad libraries...
The last time I tried using a similar stack, I found out the latest Jersey doesn't play nicely with Guice, since jersey uses its own DI library (HK2). Only one user was actively trying to solve the problem and eventually I gave up and looked at alternatives like Ninja framework (which uses Guice, but not jersey).
Ah, true. I still use Jersey 1. Jersey 2 has gone bloatware, sadly. We need a cleaner implementation of JAX-RS (which is really what we want, not Jersey per-se); I've worked on Apache Wink a little bit, but really Jersey 1 is good enough & good.
I don't know what happened with JAX-RS 2. It feels like the J2EE team got hold of it...
(PS Thanks for the Ninja suggestion; I will check it out)
> TL;DR: Java as a language is not bad. The problem with Java is its bloatware ecosystem.
That's clearly a DR: one of the major headings is "The Java Language Kinda Sucks".
More accurate summary: Java as a platform is not bad, the problem is that the platform is popular enough that lots of less-than-skilled people are using it, and making lots of less-than-ideal choices about how to use it -- including failing to use the tools available in the ecosystem to streamline the experience (and including, as a subset of that, choosing the wrong one of the languages available on the platform, including choosing the Java language itself when its not the best choice.)
Anything can be parodied by exaggeration. One could provide a github parodying any language:
C: pointers-to-pointers-to-functions, type puns, and quasi-opaque "types" with really_long_identifiers_t everywhere (among many other possibilities, and bonus points for numerous reimplementations of basic data structures tailored specifically for different types without significant performance gains)
C++: see Java, but in C++ form; or alternatively larded with metatemplate programming
perl: write any valid perl, because it parodies itself
python: mishmash classes, functions-as-stateful-objects, and n-levels of decorators everywhere, and toss in some metaclass programming for giggles
And so on.
(Note: my favorite language to program in is currently C++, and I'm well aware of the less desirable traits of the language and codebases that exist.)
The difference is that with Java, the tools available allow creating immense complexity very easily - and due to how that complexity manifests itself as the complexity of the entire application, each individual piece still looks simple. A parody Java application resembles a real one more than the others you mention, which are more in the "clearly obfuscated" category.
So what you're saying is that the tooling for Java is more advanced than the tooling for other languages. I'm not sure I see this as a negative. I did node dev for a while, it was horrible, no tools that were any good, got a memory leak? Have fun!
Had a memory leak happen in Java once, had the proper tools already, didn't have to interrupt a live server or anything, plus the tools were easy to use and well documented.
Really the problem is that when you program in Java, you need to restrain yourself. You could create another level of abstraction, or you could just solve the problem at hand and abstract it later when you find a concrete case for it. And guess what, when you get there, you've got excellent tools for it.
I love making arguments to POSIX threads. My thread argument in my current project is a pointer to a struct with pointers to functions and arrays of structs which have mutexes and basic types in them. Try saying that fast. Now try changing something in it with the typesafety of C.
Java as a language not bad, but it's not good either. It's solidly mediocre.
IMO the best thing about Java is the interfaces and libraries. When you want to reuse some else's code, just looking at the public methods and their type signatures makes it basically self-explanatory. This is what I miss most when I'm working with dynamic languages like JS, Ruby and Python.
I think an important lesson for web application development—mentioned in the article—is keeping the server stateless, moving state into the client, and using a real middleware like Redis for the session cache.
Agreed about the verbosity and Java 8 is only making the situation worse. I've been a Clojure enthusiast for a number of years now, but I was hoping there would be less of a need to use other JVM languages with Java 8 and Streams. I find working with Streams to be 3 steps forward and 2 back. The syntax (as usual) is cumbersome, and add a layer of generics on top of that and you have somewhat of a mess. I also find interop with traditional Java Collections to be annoying though maybe I am not following (yet to be discovered) best practices for dealing with Streams.
Edit: Ohh and BTW, if you ever have the opportunity to see James Ward speak in person, do so. He is a great presenter, and a regular cast member at the Boulder Java User Group.
It is only tangentially related, but I recommend this video from Brian Geotz, a Java language architect. He breaks down the challenges of adding features to the language, in a room full of Clojure devs no less. Worth a watch: https://www.youtube.com/watch?v=2y5Pv4yN0b0
It's hard to imagine someone who wouldn't be turned off by the tone of this article. Kicker is the quote at the end: "If you are in a typical enterprise then maybe you are lucky and already doing most of this." I went looking for sarcasm twice and still couldn't find it.
Java enterprise shops are not using git and JRebel and Play Framework and continuous deployments and 2 week sprints and reactive development refactoring boilerplate into lambdas.
Nor are they "mocking" amazon web services for ease of local developer testing. And a request to your boss to write the next services layer in "Kotlin" is likely to be met with the slap it deserves.
In which case find a new job. I don't understand why people stick with these hell holes for engineers when there are many opportunities to be found elsewhere. You can even find remote work so even if you're stuck in a small town with only one Java employer and you have a family and can't move you can still find that dream remote job with modern tooling and practices.
If you apply to these remote jobs but aren't getting hired, that's a solvable problem too. Keep trying to learn more, self-improving and keep applying.
> Keep trying to learn more, self-improving and keep applying.
I think it's worthwhile to add "improve your job application strategy" to that list.
There was just an article on the how bad resumes are at predicting success; the converse is that you can likely improve your resume if you're not getting offers.
And write a cover letter. Probably one in 20 (or maybe one in a hundred) resumes come in with a cover letter. And make it relevant. Talk about what the company does and how you'd be a good fit. Paraphrase their requirements list as a list of your strengths, and explain how things you don't know can be overcome.
When I do this I have almost always gotten an interview. [1] And when I get an interview I almost always get an offer. [2]
The other strategy that works for me is to network. Go to MeetUps relevant to your field and interact with people. I don't care if you're an introvert; I am too. It's hard. But do it. It's worth it.
Right now I have a remote job that pays well where I was recommended by a friend who I met because I was networking.
[1] The only exception for me was the months following 9/11, when no one was hiring because the whole nation was in shock.
[2] I really recommend "Cracking the Coding Interview" by Gayle Laakmann McDowell; if you can answer all of the questions relevant to your field, you should be golden.
Solid advice, but I have a question for you that's always been in my "too embarassed to ask" category: When you say cover letter, do you mean you attach a cover letter to the email as well as the CV, or does the email itself serve as the cover letter?
You can go either way. It's more likely that they'll print a cover letter to go along with the resume if you attach it as a separate PDF, though. They might just ignore the email and print the resume, otherwise.
The point of adding a cover letter is to stand out. If you don't, you're far more likely to end up ignored in the avalanche of resumes, especially considering how poor of a signal most resumes are.
I'd rather have a chance to actually get the job, if it's one I'd find interesting, and writing a cover letter is easy. But you're free to be ignored if it makes you feel better.
I have been an enterprise Java dev. Of the things you mention us not doing, we did about half. We mocked external services for unit tests, used git, and did 2 week sprints. My boss had no say on the programming language we wrote services in, I just would have had to convince the rest of my dev team. I doubt that it looks very different at Google or other suitably modern enterprise Java companies. Enterprise doesn't mean shit, it means big.
I guess define Enterprise. The OS experience doesn't sound like "Enterprise" to me. Just install the JDK? Most enterprises I worked at, it was more like install WebSphere and it's clients.
I did hardly any of these things and I worked at a Fortune-5 company for close to 10 years on a mix of technologies; java being one. Much of the Java there was of the IBM variety. We had WebSphere and their over priced crap. As an insider, many of the DEVs preferred C#. I think much of this had to do with the better development tooling: Visual Studio vs. IBM's version of Eclipse and its infinite list of bolt on and buggy tools. My last 4-5 years there, just about all new apps. were going to C#/.NET platform. I was an insider in an architect role where one of my responsibilities was sitting on a board that oversaw every app. coming into our data center to make sure it followed best practices from language, tools, and general infrastructure stuff like Oracle vs. MS-SQL, SAN or local disk storage.
One of our major areas of problems was JMX Message queues and prioritizing them across load balanced clusters of WebSphere servers. It was extremely clunky where as the .NET had better alternatives.
Since we were an Enterprise (Fortune-5) by a reasonable definition, GIT and open source version control wasn't use. We use IBM Synergy which is another mess. My last year working there we actually did a trial using subversion which gained a lot of traction.
Another problem for Enterprises is single sign on. Especially when you have tons of vendors who want to vet user credentials against our backends. We looked at SAML, WS-Federation, and how much vendor support there was. Like many others at the time, we came up with a kluge based on shared cookies so both our Java apps and .NET apps could work. Largely these standards are too lose to begin with too. Enterprises with deep pockets are hard to work with if your small OEM who can't afford the same financial commitment.
In short, most "Enterprises" have a separate group of people who manage the development environment. You don't typically see DEVs setting these things up. We had standard loads for our developers to install and we had the same for our servers. Yea, there were occasions where we would install more JDKs and JREs to test to see if there was a bug or performance difference in the libraries but for the most part, none of the developers had to really mess with the dev environment or the version control stuff.
We use JRebel on my team, everyone has a license. We do continuous depolyments and are coming to the end of our current two week sprint. We use Java 8 and are actively leveraging lambdas for code that is more readable.
For sure, we are not doing everything mentioned but I think we're pretty progressive and, on the whole, have a healthy attitude towards learning new things. Not every job has to be as suffocating as your example.
I work in a Enterprise Java shop in the midwest that employs 35k+, of which 5k+ are software engineers. We have 2 weeks sprints, daily scrums, retro and IPMs. We maintain legacy code that has been in production for more than 8 years and write new fully unit and integration-tested code in Groovy/Grails, Ruby/Rails, Java, and Angular. We use the latest tools and machines (both Win and Mac, paired with Intelli J). And our servers are all virutalized. No physical servers under our desk.
"Java enterprise shops are not using git and JRebel and Play Framework and continuous deployments and 2 week sprints and reactive development refactoring boilerplate into lambdas.
Nor are they "mocking" amazon web services for ease of local developer testing."
We do all of these things (minus play framework and i don't know what reactive development is) where I work and we're in the fortune 500.
>Java enterprise shops are not using git and JRebel and Play Framework and continuous deployments and 2 week sprints and reactive development refactoring boilerplate into lambdas.
This is plain wrong, as many have already pointed out. I would have thought that the audience here would have been smarter than to give upvotes to a very poor, ignorant generalization of those using the second most popular programming language [1] but then I suppose it is reflective of the massive circlejerk against Java that we tend to witness here.
The following companies are Java shops (i.e. they use it for all/most/huge or very large part of their coding effort): Google, Amazon, IBM, Oracle, Twitter, Netflix, NASA, LinkedIn, Boeing, Raytheon, Twilio, Box and the list goes on and on and on. In fact, you'll be hard pressed to find companies working on large scale projects that don't use Java in any way (Microsoft, GitHub and Stack Exchange are notable examples -- there aren't too many more). Even Facebook, which isn't a Java shop, uses Java quite a lot for their analytics.
Pretty much all air-traffic control and defense systems in the Western world are written in Java (those of them written in recent years). In fact, every piece of software you really rely on (probably without even knowing it), there's a very good chance it's written in Java. Hell, there's even embedded avionics software written in Java nowadays[1]. So you'll be surprised what many different kinds of tooling -- both modern, super-modern and less so -- is being used in Java shops. Some use hard realtime GCs, some use really advanced model checking (NASA has built an awesome Java model checker), and yeah, many use Git. And even if many of them don't -- the work they do is so important, that I could really care less whether their SCM is hip or not.
I'm in a 70,000+ person company ("enterprise") and we use most of the things in your list. My direct experience does not match your assumptions. And this is a company that is not considered leading-edge in softwawre development, believe me.
> It would have been much better to utilize environment variables so the only thing that changed between environments was those variables.
I strongly prefer commandline arguments to environment variables: They're more transparent, easier to reason about ("what's running on this server? `ps`... oh, that process there is running in the staging configuration instead of production"), and it saves useless sudos (/proc/<pid>/environ has mod bits 0400, so if the processes you're investigating are running as separate users (and they probably should be), you can't inspect the actual environment that the process has, so you end up sudo'ing to check the environment out when you should have all the information you need in the process list).
If the environment variables are just interpolated into the run script by the deploy and then all passed to the process as arguments, that works too.
Often times environmental variables are used inappropriately and make tracking down issues harder due to loss of transparency.
Plus environmental variables are context specific (e.g. user 1 and user 2 might have different ones, or server 1 and server 2 might, or this specific script may have re-defined one(!)).
A good o' fashioned script with the constants defined at the top, commented, and passed into executables on the command line (so tools like ps or taskman can "see" them) is really easy to debug/alter/monitor.
Java and or Oracle's obsession with environmental variables causes more problems than it solves.
I also agree, the only way I would use environment variables is for global configuration like HTTP_PROXY for example, otherwise I still prefer arguments, at least there is no surprises.
I was sad when I learned about this http_proxy environment variable and that things were actually starting to use it.
An http proxy setting is no more suited for an environment variable than anything else. I think it should just be a string in a file in $XDG_CONFIG_DIR/http_proxy.conf or something like that.
I agree but I also use DEBUG in my scripts to allow for on the fly debugging to occur.
I consider it a degenerate case and its only there for my own use and abuse. All it really does is redefines certain functions to be more verbose or print out debug level information.
I had one script that let you do DEBUG=somefunc and it would instrument just that one function. But to be honest it was overkill.
Also depending on how those processes are started (as root, from initd, or by hand from shell etc) environment variables might be stripped or incomplete.
Environment variables are kind of like global variables a bit. They are easy to set but feel a little dirty.
And of course if you use libraries or third party package that rely on them, then you don't have a choice.
Environment variables make perfect sense for constants that only, you know, vary with the environment. It's very nice to run the same exact code/artifacts on dev, qa, testing and production.
The way I see it, basically variables that are implicit to the machine/network that everyone should be able to infer. TZ, HOST, that kind of thing. Including, of course, similarly implicit custom variables like bkeroack describes.
Environment variables are useful in their own situations. For instance, OpenShift signals the open IP and Port number as environment variables. Which is useful when you have a program with an unknown set of command-line parameters. Either that or when you only need a subset of the available command-line parameters.
On the other hand, environment variables are useful for things you specifically don't want showing up in ps. If you've got to supply credentials (passwords, tokens, certificates, etc) or anything else that requires a modicum of security, it's much better to pass those in as environment variables rather than command line arguments.
> env variables are inherited by children, which may be relevant if the app forks
If your app forks (or any of the multitude of libraries that it may depend on, check and _pin_ your sources (so they don't add un-audited behaviors)), whatever process it execs probably will get a copy of the environment of your process.
Yes, it's possible to clean the environment between the fork and the exec/execve. Do all / most frameworks do so or make it easy to do so? I'm not sure, but would check before making any assumptions about it.
I was about to suggest that sensitive information like credentials would better be kept in files that are referred to by name in command line arguments, but... unprivileged users cannot fork/exec a process as a different user, so children could read all the same files as the parent.
I can hardly believe it, but a plug for my masters work [0] is actually relevant here. I was interested at the time in the intersection of HCI and security, so I made up this thing called sub-identities that let unprivileged unix users create sub-users. It's a really watered-down version of some actual research that's been around for a while, but the point was, it was easy(ish) for the average unix user to use. I don't pretend that it was anything but a toy, though.
All that said, it seems that passing sensitive information in environment variables, squirreling them away in the process space somewhere, then cleaning the environment (all right away, during initialization) would be a smart thing to do.
> "Yes, it's possible to clean the environment between the fork and the exec/execve. Do all / most frameworks do so or make it easy to do so? I'm not sure, but would check before making any assumptions about it."
It might be better to wipe the contents of the environmental variable immediately after reading the value in it (presumably done at startup, or close to it).
Container runtimes like docker make it much easier to inspect the application environment and arguments. A short `docker inspect <id>` will show you everything that is relevant to the app (environment, arguments, and much more).
One thing not to forget is that env variables are inherited by children, which may be relevant if the app forks.
I'm not sure about the "Useless Blocking Sucks" paragraph, it's very opinionated and using the play framework in production is nothing I would recommend for enterprise deployments. The technology is still very immature and I do not see that the overhead of an extra thread per request would matter.
The problem is not necessarily with Java or the JVM as a technology, but rather the "Java shop culture"[1] that often goes along with it. Although I would call it "Enterprise shop culture" instead, since it seems to stem from people who (sometimes unknowingly) perpetuate big company politics and a consultant attitude, even in startups.
I've found "Java shop culture" in non-Java places as well--C#/.NET for example.
Java as a runtime is a really nice piece of technology, Java as a language is pretty good, if a bit dry.
It is the heavy-weight anti-YAGNI ecosystems that grow around it (the AbstractFactoryFactoryManager APIs that these Java shop cultures tend to produce) that makes working with Java suck, in my experience.
And yes, that stuff can be avoided if you aren't stuck working on a maintenance project and you are really careful to smash down any signs of that sort of culture growing when you see it.
I've coded with Java for... well, since it came out (C, C++, Lisp before that) and I have never worked at any place with a culture like that. In fact, in my experience, it's the Microsoft shops that have been all (wannabe) Enterprisey (yes - that is a word)
No really, Java the language is bad. Terrible in fact.
The fact I need an IDE to make it workable (just) highlights this point. J2EE was terrible too, because it showed where things can go, if you let the Java astronaut architects lead.
Some of my most profitable projects were helping to rescue systems by migrating to to an alternative language on the JVM, or off it completely.
The worst part is the damage Java inflicted upon a generation of developers.
I have a problem, I think I will use Java, and Eclipse, and Maven, and all the rest. Now I have twenty thousand problems!
Edit - if you disagree, then say so. Bit spineless to downvote without a valid point to back it up!
As HN has grown it has attracted a more vocal contingent of Java developers. It's getting progressively harder to criticize the language without somebody shouting you down.
Are you insecure about your new found favorite language that you have to bash the old one that you didn't have much success with to justify your new choice? If you are really happy with your new favorite language, great. Do good work with it and move on. No need to keep smearing the old one.
Heh, no. Your comment didn't seem rhetorical so I was just providing an explanation for the phenomenon you've observed. However, we do engage in much spirited discussion throughout the software world about the relative merits of various languages and their features. There's no getting away from it, and Java's gonna get beat on until the end of time. Hope you don't take it personally.
None taken. If those frequent "spirited discussion" soothed your ego, by all means increase the weekly Java bashing. Meanwhile we just keep making software with it.
It's not about ego, it's about taste. Specifically the tastes of the majority of HN.
Sure, lots of software gets written in Java. And (less so) Cobol and Fortran. Every sensitive Java (and PHP, etc) user who is on HN and feels compelled to respond to every slight has to understand, though:
HN was founded by the guy who wrote Beating the Averages[0].
We're in PG's house. And he never liked Java.
So if Java fans come here with a chip on their shoulder about it and constantly take the bait and get into flamewars about how solid and adequate their language is, they should remember what forum they're in. Not that opinions in the forum can't be changed, but why bother when there's plenty of Java love out there elsewhere?
So it's basically herd mentality with reinforced in-group cliche. Just because PG started HN, we all have to toe the party line to bash Java? If you think PG cared about everyone here has to agree and follow his opinion, you paint him a very shallow man.
And I think he's naive in that blog in using single language as a criteria to evaluate developers, but there's another story.
No, I'm just saying that like attracts like. If PG starts anything involving programmers, a lot of them are going to share a number of his opinions on the topic, because they self-select that way. So HN is naturally going to be dominated by those who dislike Java.
You can keep responding to that dislike, but on HN, given its natural audience, staking out much of a pro-Java position is doomed to futility.
And all throughout the land, the name "Viaweb" is on everyone's lips, synonymous with e-commerce, rather than the Blub technology also-rans at Amazon and eBay.
Did you need to rescue the systems because Java couldn't do the job? Or because it had 500 different(many poor) developers in the code? My guess is the latter...but I don't know your projects.
>The fact I need an IDE to make it workable (just) highlights this point. J2EE was terrible too, because it showed where things can go, if you let the Java astronaut architects lead.
IMO you could say the same thing about C# and VS as well. Using tools that require as much work from the developer as the developer requires from the tools has gotten way out of hand. Delphi turned this sorry state of affairs into an art form.
I'm well aware. The folks who write Xcode have spent a significantly greater amount of time making their code completion put exactly what I want at my fingertips at exactly the right time.
I don't necessarily disagree, but that's likely not the reason your being downvoted. Your tone is incendiary and the comment is devoid of content. Claiming different parts of Java are bad without reason doesn't have any more substance than simply saying Java is bad.
I don't need an IDE to write Scala (or Java I'm sure), but I certainly feel more productive not having to bother with memorizing package structures.
Working outside of Rails, I've found there's actually a fair amount of that in Ruby. And auto-require like functionality it helpful, with little to no downsides.
The same is true of IntelliJ IMO. Some developers prefer Sublime. I find code written in Sublime to be consistently messier, with more of a "this person just kept writing code until they got something that compiled" feel. Instead of having the ability to explore methods at your fingertips just an "arrow down" or ALT+SPACE or CTRL+J or CMD+B away, they use a map and filter where they probably wanted a collect.
>Clojure: The lack of some OO constructs makes managing a large code base challenging
I would be intrested in what his problem is. The only thing that I can think of is subtyping and Im not sure how subtyping helps managing organisation.
Clojures namespacing is pretty nice, it might be a bit to complicated but it does everything you need.
Before down-voting and replying, please, copy and paste examples from the Rosetta Code website, which would prove my statements to be incorrect.
1. Syntactic noise.
2. Verbosity.
These gives us lots of cryptic lines of code, full of design patterns and other kluges. This is also related to the two below:
3. Over-abstraction.
4. Everything must be a member of a class.
These two are simple and straightforward. These few pages long stack traces is a result of these unnecessary method calls.
5. Static typing makes our code safe.
This nonsense results in even more lines of cryptic code ("generics") and even longer stack traces.
I am not talking about XML configs, over-"engineered" components (beans, servlets, etc.)
Here is a lemma: Any algorithm (at least those represented on the Rosetta Code website) could be coded with less lines of code, less words per line, less "special symbols" (with much better readability) and executed with less memory waste (this one excluding scripting languages for obvious reasons) in any other mainstream language. Period.
Sure, Java does not suck. It is stupid us, who are unable to "get it".
Not that I typically defend Java, but I think that (going by your Rosetta Code algorithm comparison test) Java fairs well against a few mainstream languages:
Now, this isn't entirely fair; one of C++'s faults/benefits is that depending on your shop and/or framework/libraries, "idiomatic" C++ can vary greatly. Template heavy C++ tends to look like vomit. C++ that uses Boost will typically be more unpleasant to look at than C++ that uses Qt (imho anyway).
Java really comes into it's own horrible self when you get beyond mere algorithm implementation. A quicksort method in Java will tend to be relatively fine, but for projects larger than that it becomes idiomatic to make your java code a real mess.
Definitely. Pointing to C++ as a mainstream language that is uglier than Java seems a bit like missing the point since it is basically the exception that proves the rule, but he did say "in any other mainstream language. Period." ;)
Java itself was once so popular that a completely unrelated programming language, javascript, had java in its name to ride the coat-tails of its popularity.
The culture and behaviors that have grown up around it though make it easy for people to fall into holes. (Both technical and non-technical, e.g. hiring culture)
It's like if a minefield existed via the path of Java and people said "There's no way through this minefield." And another retorts "Of course there is a path! Just go through it carefully, learn the topology, and it's just as fast as sprinting across an open meadow."
I guess I just felt bad to see all those great bulleted itens with some nice phrasing around and then to see my dear Dynamic Typing there, alone, without any adjective. No love, no hate, simply emotionless "Bad" :(
Good point. I should have put more details in there. I prefer static typing with good type inference because it allows me to have a compiler validate a lot of my code pre-runtime. Otherwise I'm left with tests and actually running all of the code to do that validation. The value of this for large code bases has been worth the tradeoffs in my experience. But since this is one of the most debated things in programming I don't expect to sway anyone. I'm happy to leave this as an item of "it depends" / personal preference.
Clojure does have optional static typing via core.typed. It's still in active development, and the tooling around it is still rough around the edges, but it's a more sophisticated type system than Java's.
I'm confused about the title of this. I've never heard an argument that went "Java sucks because you are forced to (thing on this list)".
It's always been "Java sucks because it lacks (thing it certainly lacks)" or "Java sucks because it forces you to (thing it certainly forces you to do)", or, closest to this article, "Java sucks because it encourages you to (bad practice, such as those mentioned in this article)". None of these does the article refute.
I've seen places that used Java, and had most of these, and places that used Java and had little of it. I've seen places that used other languages that had all of these, and other places that used those same other languages that had none of it. This seems kind of orthogonal, and as such a bit of a strawman; is it in response to some specific arguments I've just not heard?
Java has some problems. I would contend that using the wrong tool for the job == using the tool wrong. Java has its place, but overall there is a better, more specialized solution in most instances that doesn't have some of Java's (pretty hideous) warts.
>>Spend a couple evenings or weekends working on implementing one of these items. Then show your manager what you did in your own time (that will convey how much you care) and then let them take the credit for the amazing new thing they thought of.
Why would someone want to do that , unless its someone's personal project?
If the expected cost of interviewing for and finding a new job where these things are already in place is greater than the cost of a couple evenings or weekends to add those features to the current work environment.
No developer should install JDK, it's a mess, madness and risk for crapware. Just use the JDK zip/tar.gz for that one specific project.
Even for distributing java apps I find it much easier to bundle JRE with the app and never ask for the devop or end user install it separately. The license for bundling is quite permissive [1] and bundling can be also used for os x apps [2].
210 comments
[ 6.0 ms ] story [ 264 ms ] threadedit: I suspect that none of the downvoters ever implemented a single compiler targeting JVM.
Is there a good reason for VMs to support TCO rather than having compilers perform it?
> no (optional and confined) unsafe pointer arithmetics
When do you want this? There's sun.misc.Unsafe#setMemory if you really need it.
> no value types
Might be added in JVMS 10 or some version thereafter.
> a pathetic limit on a method size makes it an extremely shitty target for any language other than Java.
True.
> All the existing languages running on top of JVM are very, very inefficient, or have to pay a horrible price for being able to run reasonably fast (crap like `recur` in Clojure, for example).
Fair enough, but it wasn't designed as a general purpose compilation target like llvm.
Again this word! Proper tail calls handling is not an "optimisation". Optimisations are supposed to be optional, while tail calls handling makes a semantic difference.
And, no, compilers cannot do it statically. You cannot statically resolve virtual calls, for example. Consider the following trivial case:
`(define (f g x) (g x))`
> When do you want this? There's sun.misc.Unsafe#setMemory if you really need it.
Try implementing, say, an STG efficiently. Or even a WAM.
> Might be added in JVMS 10 or some version thereafter.
JVM may start to suck less at some point. But now it sucks.
> but it wasn't designed as a general purpose compilation target like llvm.
Exactly. And that's why it's inferior to the other VMs, which were designed with multiple source language semantics in mind. Including even CLR.
Due to the way JVM does bytecode verification. It will be fixed in future versions
https://www.youtube.com/watch?v=2y5Pv4yN0b0
> no (optional and confined) unsafe pointer arithmetics
www.docjar.com/docs/api/sun/misc/Unsafe.htm
Will be replaced by an official API in Java 9.
> no value types
http://openjdk.java.net/jeps/169
> pathetic limit on a method size makes it an extremely shitty target for any language other than Java.
Java Virtual Machine
In CLR you can selectively switch off the verification.
> www.docjar.com/docs/api/sun/misc/Unsafe.htm
I do not want an inefficient API. I want a low level functionality which can be mapped efficiently to what the real hardware does.
> http://openjdk.java.net/jeps/169
> This work is not intended to change the Java Language Specification or JVM bytecode instruction set.
Okay... It's not going to be anything useful.
> Java Virtual Machine
And that's exactly why it sucks. There are much more universal VMs out there.
Why open the door to security exploits?!
C derived languages are already enough.
> I do not want an inefficient API. I want a low level functionality which can be mapped efficiently to what the real hardware does.
Ever heard of intrinsics? Just because it looks like a method call, doesn't mean it is one.
> Okay... It's not going to be anything useful.
The final form is still ongoing work.
> And that's exactly why it sucks. There are much more universal VMs out there
Except for the CLR, I don't know any other.
The universal VM has been pursuit since UNCOL was presented to the world.
Why limit your VM expressive power? Restrict only untrusted loadable modules, do whatever you want in the trusted realm.
> C derived languages are already enough.
Not nearly. You won't have a managed VM with fast run-time code generation with C.
> Just because it looks like a method call, doesn't mean it is one.
Problem with intrinsics is that the majority of your optimisation passed do not know anything about them. See LLVM as an unfortunate example. Most of the SIMD intrinsics are not even used in a simplest constant folding there.
> Except for the CLR
Bingo! CLR is better. Scrap JVM.
I was speaking about security exploits. C should never have happened.
> Bingo! CLR is better. Scrap JVM.
Yes the CLR does quite a few things better than the JVM compatible VMs do currently.
However, the JVM being a specification means I can find a JVM for anything has that a CPU, from smart cards up, servers, mainframes, cars, weapon guiding systems, factory robots, anything.
So while technically better than the reference implementation, it doesn't cover the application spectrum JVM compatible VMs do.
People tend to forget that Sun (now Oracle) JDK is just the reference implementation.
Note I use both eco-systems since the beginning.
I see. I sort of agree - C should never have been exposed to the programmers. But a C-level VM is an extremely useful thing for implementing high level languages. I'd rather move safety checks a number of levels up, and leave VM level to performance-related stuff.
And both Microsoft and Oracle are realizing this.
.NET has native compilation on WP, with .NET Native coming on .NET 5. NGEN is a very simple compiler just for optimizing startup time.
Java always had AOT compilers in commercial JVMs, but not on Sun.
Now Oracle has SubstrateVM, and there are plans for AOT compilation at least in Java 10 timeframe.
And the difference between abstract machines, intermediate representations and virtual machines is very elusive (see all the confusion around LLVM for example).
The JVM worked well enough and a lot of companies put a lot of effort into it. But fundamentally, the design is "meh". It just gets the job done.
C compilers were between K&R C and ANSI C, writing portable code was #ifdef mess.
C++ compilers were even worse than C ones. Each between their own interpretations of CFront, C++ ARM and ongoing work at ANSI.
Outside UNIX world, no one cared about POSIX, which was in adoption phase anyway. So even across UNIX systems, #ifdef spaghetti code it was.
Safe system programming languages like Ada, Modula-2, Modula-3, Oberon were failing to pick up steam with the enterprise adopting UNIX variants and its two main languages C and C++.
Java brought sanity into writing portable code and better type safety.
The initial versions were surely slow, but the adoption of JIT and AOT compilation across commercial JVMs helped to adopt it.
As for the ivory towers that get written with Java, they were being written in code generators based in UML/OMT/Booch..., C, C++, Clipper and lots of 4GLs when it appeared.
It is just an enterprise sin to write such type of software.
First System, Second System, Third System.
Right now Java is slowly moving to the Third System (see the evolution from J2EE => JEE 5 => JEE 6 => JEE 7). Ditto with the mindset of Java developers of today.
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
I think the over-engineering is an unintended side effect of Java's most attractive features: incredibly stable standard ABIs, portable byte code, fantastic tooling, and a language that makes byzantine abstractions relatively easy to implement without the instability you get in C++ or the unmaintainability you get in dynamic languages. Sometimes you actually do need very high level complex abstractions, so this makes Java a fantastic language for those cases. But those cases are rare. Java makes it easy to build towers of babel that stand up, so they happen.
Java can be fine if you exercise discipline around complexity. Java coders need YAGNI and KISS tattooed on their inner eyelids more than coders in other languages.
I believe though that you can make poor library choices in any language & framework. With languages that have been around for a while, there are a lot of bad libraries...
I don't know what happened with JAX-RS 2. It feels like the J2EE team got hold of it...
(PS Thanks for the Ninja suggestion; I will check it out)
That's clearly a DR: one of the major headings is "The Java Language Kinda Sucks".
More accurate summary: Java as a platform is not bad, the problem is that the platform is popular enough that lots of less-than-skilled people are using it, and making lots of less-than-ideal choices about how to use it -- including failing to use the tools available in the ecosystem to streamline the experience (and including, as a subset of that, choosing the wrong one of the languages available on the platform, including choosing the Java language itself when its not the best choice.)
C: pointers-to-pointers-to-functions, type puns, and quasi-opaque "types" with really_long_identifiers_t everywhere (among many other possibilities, and bonus points for numerous reimplementations of basic data structures tailored specifically for different types without significant performance gains)
C++: see Java, but in C++ form; or alternatively larded with metatemplate programming
perl: write any valid perl, because it parodies itself
python: mishmash classes, functions-as-stateful-objects, and n-levels of decorators everywhere, and toss in some metaclass programming for giggles
And so on.
(Note: my favorite language to program in is currently C++, and I'm well aware of the less desirable traits of the language and codebases that exist.)
Had a memory leak happen in Java once, had the proper tools already, didn't have to interrupt a live server or anything, plus the tools were easy to use and well documented.
Really the problem is that when you program in Java, you need to restrain yourself. You could create another level of abstraction, or you could just solve the problem at hand and abstract it later when you find a concrete case for it. And guess what, when you get there, you've got excellent tools for it.
IMO the best thing about Java is the interfaces and libraries. When you want to reuse some else's code, just looking at the public methods and their type signatures makes it basically self-explanatory. This is what I miss most when I'm working with dynamic languages like JS, Ruby and Python.
Edit: Ohh and BTW, if you ever have the opportunity to see James Ward speak in person, do so. He is a great presenter, and a regular cast member at the Boulder Java User Group.
http://www.slideshare.net/jeffz/why-java-sucks-and-c-rocks-f...
I won't defend the tone of that but some of the points are valid (particularly with Java pre-8).
Java enterprise shops are not using git and JRebel and Play Framework and continuous deployments and 2 week sprints and reactive development refactoring boilerplate into lambdas.
Nor are they "mocking" amazon web services for ease of local developer testing. And a request to your boss to write the next services layer in "Kotlin" is likely to be met with the slap it deserves.
If you apply to these remote jobs but aren't getting hired, that's a solvable problem too. Keep trying to learn more, self-improving and keep applying.
I think it's worthwhile to add "improve your job application strategy" to that list.
There was just an article on the how bad resumes are at predicting success; the converse is that you can likely improve your resume if you're not getting offers.
And write a cover letter. Probably one in 20 (or maybe one in a hundred) resumes come in with a cover letter. And make it relevant. Talk about what the company does and how you'd be a good fit. Paraphrase their requirements list as a list of your strengths, and explain how things you don't know can be overcome.
When I do this I have almost always gotten an interview. [1] And when I get an interview I almost always get an offer. [2]
The other strategy that works for me is to network. Go to MeetUps relevant to your field and interact with people. I don't care if you're an introvert; I am too. It's hard. But do it. It's worth it.
Right now I have a remote job that pays well where I was recommended by a friend who I met because I was networking.
[1] The only exception for me was the months following 9/11, when no one was hiring because the whole nation was in shock.
[2] I really recommend "Cracking the Coding Interview" by Gayle Laakmann McDowell; if you can answer all of the questions relevant to your field, you should be golden.
I'd rather have a chance to actually get the job, if it's one I'd find interesting, and writing a cover letter is easy. But you're free to be ignored if it makes you feel better.
I did hardly any of these things and I worked at a Fortune-5 company for close to 10 years on a mix of technologies; java being one. Much of the Java there was of the IBM variety. We had WebSphere and their over priced crap. As an insider, many of the DEVs preferred C#. I think much of this had to do with the better development tooling: Visual Studio vs. IBM's version of Eclipse and its infinite list of bolt on and buggy tools. My last 4-5 years there, just about all new apps. were going to C#/.NET platform. I was an insider in an architect role where one of my responsibilities was sitting on a board that oversaw every app. coming into our data center to make sure it followed best practices from language, tools, and general infrastructure stuff like Oracle vs. MS-SQL, SAN or local disk storage.
One of our major areas of problems was JMX Message queues and prioritizing them across load balanced clusters of WebSphere servers. It was extremely clunky where as the .NET had better alternatives.
Since we were an Enterprise (Fortune-5) by a reasonable definition, GIT and open source version control wasn't use. We use IBM Synergy which is another mess. My last year working there we actually did a trial using subversion which gained a lot of traction.
Another problem for Enterprises is single sign on. Especially when you have tons of vendors who want to vet user credentials against our backends. We looked at SAML, WS-Federation, and how much vendor support there was. Like many others at the time, we came up with a kluge based on shared cookies so both our Java apps and .NET apps could work. Largely these standards are too lose to begin with too. Enterprises with deep pockets are hard to work with if your small OEM who can't afford the same financial commitment.
In short, most "Enterprises" have a separate group of people who manage the development environment. You don't typically see DEVs setting these things up. We had standard loads for our developers to install and we had the same for our servers. Yea, there were occasions where we would install more JDKs and JREs to test to see if there was a bug or performance difference in the libraries but for the most part, none of the developers had to really mess with the dev environment or the version control stuff.
For sure, we are not doing everything mentioned but I think we're pretty progressive and, on the whole, have a healthy attitude towards learning new things. Not every job has to be as suffocating as your example.
Nor are they "mocking" amazon web services for ease of local developer testing."
We do all of these things (minus play framework and i don't know what reactive development is) where I work and we're in the fortune 500.
Was that sarcastic? A quick search turned up [1], which suggests it was. Or is "Chinese fire drill" an accepted development methodology these days?
[1] http://c2.com/cgi/wiki/CeeTwoProject?ReactiveDevelopment
This is plain wrong, as many have already pointed out. I would have thought that the audience here would have been smarter than to give upvotes to a very poor, ignorant generalization of those using the second most popular programming language [1] but then I suppose it is reflective of the massive circlejerk against Java that we tend to witness here.
[1] http://langpop.com/
>And a request to your boss to write the next services layer in "Kotlin" is likely to be met with the slap it deserves.
If your "boss" can't stand a conversation surrounding a backed and reasoned suggestion then I feel very sorry for you for working in those conditions.
Pretty much all air-traffic control and defense systems in the Western world are written in Java (those of them written in recent years). In fact, every piece of software you really rely on (probably without even knowing it), there's a very good chance it's written in Java. Hell, there's even embedded avionics software written in Java nowadays[1]. So you'll be surprised what many different kinds of tooling -- both modern, super-modern and less so -- is being used in Java shops. Some use hard realtime GCs, some use really advanced model checking (NASA has built an awesome Java model checker), and yeah, many use Git. And even if many of them don't -- the work they do is so important, that I could really care less whether their SCM is hip or not.
[1]: http://www.atego.com/products/atego-perc/
I strongly prefer commandline arguments to environment variables: They're more transparent, easier to reason about ("what's running on this server? `ps`... oh, that process there is running in the staging configuration instead of production"), and it saves useless sudos (/proc/<pid>/environ has mod bits 0400, so if the processes you're investigating are running as separate users (and they probably should be), you can't inspect the actual environment that the process has, so you end up sudo'ing to check the environment out when you should have all the information you need in the process list).
If the environment variables are just interpolated into the run script by the deploy and then all passed to the process as arguments, that works too.
Often times environmental variables are used inappropriately and make tracking down issues harder due to loss of transparency.
Plus environmental variables are context specific (e.g. user 1 and user 2 might have different ones, or server 1 and server 2 might, or this specific script may have re-defined one(!)).
A good o' fashioned script with the constants defined at the top, commented, and passed into executables on the command line (so tools like ps or taskman can "see" them) is really easy to debug/alter/monitor.
Java and or Oracle's obsession with environmental variables causes more problems than it solves.
An http proxy setting is no more suited for an environment variable than anything else. I think it should just be a string in a file in $XDG_CONFIG_DIR/http_proxy.conf or something like that.
I consider it a degenerate case and its only there for my own use and abuse. All it really does is redefines certain functions to be more verbose or print out debug level information.
I had one script that let you do DEBUG=somefunc and it would instrument just that one function. But to be honest it was overkill.
Environment variables are kind of like global variables a bit. They are easy to set but feel a little dirty.
And of course if you use libraries or third party package that rely on them, then you don't have a choice.
See also: http://12factor.net/
> env variables are inherited by children, which may be relevant if the app forks
If your app forks (or any of the multitude of libraries that it may depend on, check and _pin_ your sources (so they don't add un-audited behaviors)), whatever process it execs probably will get a copy of the environment of your process.
Yes, it's possible to clean the environment between the fork and the exec/execve. Do all / most frameworks do so or make it easy to do so? I'm not sure, but would check before making any assumptions about it.
I was about to suggest that sensitive information like credentials would better be kept in files that are referred to by name in command line arguments, but... unprivileged users cannot fork/exec a process as a different user, so children could read all the same files as the parent.
I can hardly believe it, but a plug for my masters work [0] is actually relevant here. I was interested at the time in the intersection of HCI and security, so I made up this thing called sub-identities that let unprivileged unix users create sub-users. It's a really watered-down version of some actual research that's been around for a while, but the point was, it was easy(ish) for the average unix user to use. I don't pretend that it was anything but a toy, though.
All that said, it seems that passing sensitive information in environment variables, squirreling them away in the process space somewhere, then cleaning the environment (all right away, during initialization) would be a smart thing to do.
edit: see `man 3 unsetenv` for how to do this
[0] http://ccl.cse.nd.edu/research/pubs/snowberger-thesis.pdf
It might be better to wipe the contents of the environmental variable immediately after reading the value in it (presumably done at startup, or close to it).
One thing not to forget is that env variables are inherited by children, which may be relevant if the app forks.
I've found "Java shop culture" in non-Java places as well--C#/.NET for example.
1. http://michaelochurch.wordpress.com/2012/04/13/java-shop-pol...
Java as a runtime is a really nice piece of technology, Java as a language is pretty good, if a bit dry.
It is the heavy-weight anti-YAGNI ecosystems that grow around it (the AbstractFactoryFactoryManager APIs that these Java shop cultures tend to produce) that makes working with Java suck, in my experience.
And yes, that stuff can be avoided if you aren't stuck working on a maintenance project and you are really careful to smash down any signs of that sort of culture growing when you see it.
The fact I need an IDE to make it workable (just) highlights this point. J2EE was terrible too, because it showed where things can go, if you let the Java astronaut architects lead.
Some of my most profitable projects were helping to rescue systems by migrating to to an alternative language on the JVM, or off it completely.
The worst part is the damage Java inflicted upon a generation of developers.
I have a problem, I think I will use Java, and Eclipse, and Maven, and all the rest. Now I have twenty thousand problems!
Edit - if you disagree, then say so. Bit spineless to downvote without a valid point to back it up!
Sure, lots of software gets written in Java. And (less so) Cobol and Fortran. Every sensitive Java (and PHP, etc) user who is on HN and feels compelled to respond to every slight has to understand, though:
HN was founded by the guy who wrote Beating the Averages[0].
We're in PG's house. And he never liked Java.
So if Java fans come here with a chip on their shoulder about it and constantly take the bait and get into flamewars about how solid and adequate their language is, they should remember what forum they're in. Not that opinions in the forum can't be changed, but why bother when there's plenty of Java love out there elsewhere?
[0] http://www.paulgraham.com/avg.html
And I think he's naive in that blog in using single language as a criteria to evaluate developers, but there's another story.
You can keep responding to that dislike, but on HN, given its natural audience, staking out much of a pro-Java position is doomed to futility.
IMO you could say the same thing about C# and VS as well. Using tools that require as much work from the developer as the developer requires from the tools has gotten way out of hand. Delphi turned this sorry state of affairs into an art form.
Or, for that matter, C++. You can write C++ in Vim, but I sure wouldn't. Especially with clang-driven features in Xcode being so helpful.
The difference is significant.
Working outside of Rails, I've found there's actually a fair amount of that in Ruby. And auto-require like functionality it helpful, with little to no downsides.
The same is true of IntelliJ IMO. Some developers prefer Sublime. I find code written in Sublime to be consistently messier, with more of a "this person just kept writing code until they got something that compiled" feel. Instead of having the ability to explore methods at your fingertips just an "arrow down" or ALT+SPACE or CTRL+J or CMD+B away, they use a map and filter where they probably wanted a collect.
I down-voted you just now because you do not make any specific points or claims about Java to disagree with, beyond "bad" and "terrible".
I would be intrested in what his problem is. The only thing that I can think of is subtyping and Im not sure how subtyping helps managing organisation.
Clojures namespacing is pretty nice, it might be a bit to complicated but it does everything you need.
To me, that's part of the problem. The Java ecosystem seems diverse to a fault.
Before down-voting and replying, please, copy and paste examples from the Rosetta Code website, which would prove my statements to be incorrect.
1. Syntactic noise. 2. Verbosity. These gives us lots of cryptic lines of code, full of design patterns and other kluges. This is also related to the two below: 3. Over-abstraction. 4. Everything must be a member of a class. These two are simple and straightforward. These few pages long stack traces is a result of these unnecessary method calls. 5. Static typing makes our code safe. This nonsense results in even more lines of cryptic code ("generics") and even longer stack traces.
I am not talking about XML configs, over-"engineered" components (beans, servlets, etc.)
Here is a lemma: Any algorithm (at least those represented on the Rosetta Code website) could be coded with less lines of code, less words per line, less "special symbols" (with much better readability) and executed with less memory waste (this one excluding scripting languages for obvious reasons) in any other mainstream language. Period.
Sure, Java does not suck. It is stupid us, who are unable to "get it".
Rosetta Code's Java Quicksort: http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Jav...
Not great, that first line is a wreck in particular, but not terrible either.
Compare that to this though: http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#C.2...
Really quite ugly looking code.
Now, this isn't entirely fair; one of C++'s faults/benefits is that depending on your shop and/or framework/libraries, "idiomatic" C++ can vary greatly. Template heavy C++ tends to look like vomit. C++ that uses Boost will typically be more unpleasant to look at than C++ that uses Qt (imho anyway).
Java really comes into it's own horrible self when you get beyond mere algorithm implementation. A quicksort method in Java will tend to be relatively fine, but for projects larger than that it becomes idiomatic to make your java code a real mess.
I love me some Haskell, but this particular example is kind of a bait-and-switch.
The culture and behaviors that have grown up around it though make it easy for people to fall into holes. (Both technical and non-technical, e.g. hiring culture)
It's like if a minefield existed via the path of Java and people said "There's no way through this minefield." And another retorts "Of course there is a path! Just go through it carefully, learn the topology, and it's just as fast as sprinting across an open meadow."
That's very very debatable, don't you think mr. Ward?
I guess I just felt bad to see all those great bulleted itens with some nice phrasing around and then to see my dear Dynamic Typing there, alone, without any adjective. No love, no hate, simply emotionless "Bad" :(
It's always been "Java sucks because it lacks (thing it certainly lacks)" or "Java sucks because it forces you to (thing it certainly forces you to do)", or, closest to this article, "Java sucks because it encourages you to (bad practice, such as those mentioned in this article)". None of these does the article refute.
I've seen places that used Java, and had most of these, and places that used Java and had little of it. I've seen places that used other languages that had all of these, and other places that used those same other languages that had none of it. This seems kind of orthogonal, and as such a bit of a strawman; is it in response to some specific arguments I've just not heard?
Why would someone want to do that , unless its someone's personal project?
No developer should install JDK, it's a mess, madness and risk for crapware. Just use the JDK zip/tar.gz for that one specific project.
Even for distributing java apps I find it much easier to bundle JRE with the app and never ask for the devop or end user install it separately. The license for bundling is quite permissive [1] and bundling can be also used for os x apps [2].
[1] http://www.oracle.com/technetwork/java/javase/jre-8-readme-2... [2] https://docs.oracle.com/javase/jp/8/technotes/guides/jweb/pa...