5 ms·
Tooling is extremely important. However there’s one thing I think is worth mentioning: Java tooling (IntelliJ and Lombok) is incredible. Yet Java is still on t
by armchairhacker 4y ago
Tooling is extremely important. However there’s one thing I think is worth mentioning:
Java tooling (IntelliJ and Lombok) is incredible. Yet Java is still on the most dreaded list.
Why is that? Honestly I don’t know, and I actually think Java is a good language exclusively because of its tooling. That being said, current tooling doesn’t fix all of Java’s flaws.
- Gradle and maven are reliable like npm and cargo, but super verbose and confusing
- Standard library has some issues and quirks. Like URL#equals sends a network request, apparently that will never be changed. Some other packages (log4j, JAX) are similarly bloated
- The “billion dollar mistake” untyped null. People tried to fix this with @NonNull annotations but it’s not far enough.
- Java is in a lot of legacy software, which often cannot use Lombok and requires Java 8 or even Java 7.
- I just have to say, IntelliJ and Lombok really do fix Java’s verbosity. Both reading and writing. Indeed, tooling is the new syntax. But maybe some disagree.
- ModernMech 4y agoBecause Java is taught to kids as their first language in high school and college. It’s associated with homework, exams, and boring corporate jobs.
- celdon25 4y agoNo. Edit: apparently some people think I am disagreeing with the statement in and of itself. Yes, Java is a homework language, but it’s real problems are far worse than that. Worst of all is the generation of developers that it produced.
- ModernMech 4y ago> Worst of all is the generation of developers that it produced. Care to expand on that? Interested to hear more of what kind of developer you're thinking of.
- kabdib 4y agoJava was my first introduction to full bull-goose, consultant-class enterprise architecture, where I think that salaries and hourly rates are proportional to the number of cascaded factory classes your solution requires. At least four or five, or you're bush leagues. Wait, am I sounding shocked, wounded and bitter again? "This thing is so enterprise-y that the documentation alone can send email."
- SNosTrAnDbLe 4y agoI would argue that any language that you use for enterprise-y program will always result in similar code bases. These always a lot of standards to satisfy and eventually this results in people coming up with leaky abstractions for incorporating those policies. All business logic cannot be nicely boxed into clean code as much as we would like to.
- deleted 4y ago[deleted]
- shepherdjerred 4y agoMy first introduction to Java was via Minecraft. Afterwards I used it extensively at AWS. It's not a boring language, but it is often used in enterprise which gives it a bad reputation.
- deleted 4y ago[deleted]
- twic 4y agoAgreed (although i hate Lombok myself, as being altogether too much magic; happily, standard Java language improvements now provide a lot of the comforts that Lombok does). But other languages have quirks on a par with Java. JavaScript is quirkier, and Ruby is basically a DSL for composing quirks. I see two areas where Java fell more dynamic competitors. Firstly, Java does not have a great story about being able to open up an editor, write some code, and ship it. Using a simple text editor is too tiring, and the extremely sophisticated IDEs take a lot of learning. Java has never been well supported by the middle ground of Sublime Text-esque programmer's editors. Meanwhile, the standard tooling (javac and jar) is simple, but using it to get to production is cumbersome, and the more sophisticated build tools are not standard, and either verbose and maddeningly inflexible (Maven), or crammed with arcane secrets (Gradle). And none of them make starting a new project as easy as 'rails new' or 'npm create-react-app' (Maven has archetypes for this, but i don't think they ever got really popular). Secondly, Java does not have a really good framework for being highly productive at building webapps right out of the gate. By which i mean Rails. There's absolutely no technical reason you couldn't build a Rails equivalent in Java. I am astounded that (AFAIK!) there was not an urgent effort to do a straight port of Rails to Java once it became clear that Ruby was eating Java from the bottom up. Meanwhile, Java had Spring, but until Spring Boot, Spring was nowhere as easy and consistent to use as Rails; Spring Boot has helped, but by slathering another layer of even more complexity on top. I have never used Dropwizard, but maybe that's closer to the Rails spirit. The more 'sophisticated' frameworks like Play and Vert.x are not the answer, because they're so tied up with particular overly clever concepts.
- rightbyte 4y ago> There's absolutely no technical reason you couldn't build a Rails equivalent in Java. Groovy with Grails? Never tried Grails so dunno of it was mature enought.
- the_only_law 4y agoWhat ever happened to those, I remember years ago Grails was pretty popular, and groovy was one of the premier alternative JVM languages. Then it felt like it just disappeared after some years, no one mentioned groovy or Grails anymore.
- rr808 4y agoJava is great, I think many wrinkles need some active deprecation. Its interesting that the blog likes the extensive standard libraries, but Java is littered with old APIs and language features that aren't used or liked any more. Newer languages avoid having these old warts, its only matter of time though.
- adamgordonbell 4y ago> Newer languages avoid having these old warts, its only matter of time though. That is sort of the summary of the post.
- Banana699 4y ago>Honestly I don’t know I do, because I'm a Java hater. Here are the reason I hate it for - Baking the difference between primitives and objects into the language itself : an ugly mistake with far reaching consequences, made by a language designed in 1995 while another designed in 1980 (smalltalk), in 1991 (Python) and 1995 (Ruby) all didn't fall for it. The difference is an irrelevant VM-level optimization detail, there is no reason to uglify the human-level language with it. Once the initial mistake has been made, the correct response was NOT to make the even uglier hack of wrapper classes, but to make the primitives objects in the newer releases of the language, this won't break old code, as valid uses of objects are a superset of valid uses of primitives, except perhaps that objects need to be allocated explictely with "new", but this can be a special case for primtives (i.e. "int is a special kind of object that you don't need to allocate explicitly"). The compiler can figure out whether it needs to be represented as objects or as primitives, you can leave hooks and knobs for people to tell the compiler they need to the primitives to be represented as primitves, but it shouldn't be mandatory. - Baking in choices about object representations : Like the fact that objects are always passed by reference, or that they are always allocated on the heap. Why the "always" part ? why not give developers the choice between pass-by-value and pass-by-reference like C# does ? why not give developers the choice to allocate on the stack (and complain as loud as you want when they want to do something unsafe with it, like escaping from methods), which, unfortunately, even C# doesn't ? Everytime you see something like "foo deepCopy()" that's a failure of the language, forcing you to explicitely pay attention to the fact that foo objects need to be copied deeply everytime they are copied, instead of just once when you define the object by marking it as a "struct" or whatever word to signify that object has value semantics, and then deep copy is just assignment or passing as a parameter. Why make it the default to be inefficient with the heap when it's very easy to give developers the choice to be efficient in situations where it's always safe ? - No operator overloading : I get the hate, it's a powerful tool. But it's misguided to ban it, operators should not be special, languages like Haskell and Raku go even further and allow you to define new operators entirely and control their predence and other things. You don't need to go that far, why can't objects use the already built-in symbols the language support ? because it might be confusing ? anything can be confusing, you can write assembly in any programming language, and it will be even worse than assembly because of the more powerful and obscure abstractions. - Generics : The overall theme of forcing you to do things its way seems to a staple with java. Why do I need to use type-erased generics ? why shouldn't I get the choice to specify whether I need a new class generated for runtime efficiency or use the type-erased catch-all for size efficiency? there is no need to bake VM-level support for this, it can all be done at compile time (possibly with help of additional metadata files or special fields in the .class of the generic type). - Overall verbosity : Why "extends" and "implements" ? do you really need to know whether you're inheriting a class or an interface ? and can't those be lighter symbols like "<" and ":" perhaps ? why is "private/public/protected" a must in front of every method and field ? most people align fields and methods by their visibility, C++'s way is that you declare "public:" and then everything declared below that is public. In the worst case you can always recover Java's way by "public : <method> ; private : <method> ; public : <method>" and so on, but it's nice to at least have the choice of not repeating yourself. Why aren't any constructors generated ? there are at least 2 very obvious ones : the empty one, and the one that assigns all the non-defaulted fields (and can take optional arguments to override the default fields). Why aren't generated getters and setters available with a small and light request, like C#'s "get ; set ;" ? Java's design is just full of things like this. It feels like a weird sort of disrespect for your time, "yeah you must write those routine 25 lines of code all by yourself, you have anything better to do?", how about actually writing my application instead of pleasing your language with weird and unnecessary incantations ? It's like a modern COBOL. - Horrible OOP excesses : Not really the language's fault (except that it encourages verbosity and loves it) and already mentioned, but worth mentioning again. Overall, I treat java as assembly. I write kotlin in my spare time, and whenever I'm confused about the semantics of some construct I make intellij show the bytecode then hit "decompile" to see a Java rendition of the code, the exact semantics will be obvious but verbose. A language that took this literally is Xtend, a high-level augmented java which transpiles to java and is a strict superset of it, but with option that the Xtend compiler figures out all the verbosity for you. Groovy also takes the "Superset and Augment" approach but doesn't transpile. And off course Kotlin is very good with it's interoperability, every JVM language is but Kotlin's mixture of being close to Java semantics (unlike say, Scala or Clojure) and Intellij excellent support for mixed projects makes it at least somewhat special. I like the JVM and it's cutting edge research and performance, and these days the Java standard writers seem to show signs of finally waking up to reality after years of being behind every mainstream language, and they regularly augment and modernize the language. But you can't undo 20 years or so of bad design, not easily and not painlessly. >Indeed, tooling is the new syntax. Very much agreed, long long gone are the days when a compiler or an interpeter is the only thing expected out of a language. But it's not a panacea to treat any bad design, at best it's just a band-aid for bad designs that makes them barely berable. The language has to be designed from the start with the knowledge of "this is going to run in an IDE" baked in to make full use of the full range of fantastic things an IDE can do. [1] https://www.eclipse.org/xtend/ https://www.eclipse.org/xtend/
- puffoflogic 4y agoBad languages leave lots of room for tooling. Good languages leave less room. Only the deluded run ubsan/asan/tsan on safe rust. Does that mean safe rust has less tooling than other languages? Well, yes, because that tooling is redundant and irrelevant.
- 62951413 4y ago* I find it hard to believe anyone with experience on the JVM would choose Java over Scala or Kotlin. The latter actually addresses most of your concerns. The existence of Lombok is a strong argument in favor of a more modern language. * I'd violently disagree with anyone grouping gradle and maven together. One of them is declarative the other is a mess surpassed only by SBT. * I don't get why nulls are so hated by people who are not real FP purists. How are they different from ", err := .. if err != nil .." in golang which people do a lot and seem to enjoy (in comparison with exceptions and even Optionals)? NPEs are not common in development and very unusual in prod. I'm not sure I like how much ceremony there's in Kotlin to keep track of nullable things. * I hate to break the news but log4j was dropped in favor of slf4J&Co a decade ago. There are better restful frameworks such as akka-http and sparkjava.
- shepherdjerred 4y ago* I'd prefer Java (with Lombok) over Scala or Kotlin * How often do you see both Gradle and Maven in a project? Not often. They're similar tools. * [0] * This is completely untrue. log4j is still widely used, even in new projects. sl4j is simply a universal API that allows applications to choose their logging backend. sl4j and log4j aren't mutually exclusive. * I was going to say that spark hasn't been updated in years, but it looks like they posted a release [1]! [0]: https://hackernoon.com/null-the-billion-dollar-mistake-8t5z32d6 https://hackernoon.com/null-the-billion-dollar-mistake-8t5z3... [1]: https://mvnrepository.com/artifact/com.sparkjava/spark-core/2.9.4 https://mvnrepository.com/artifact/com.sparkjava/spark-core/...
- Tainnor 4y ago> I don't get why nulls are so hated by people who are not real FP purists. How are they different from ", err := .. if err != nil .." in golang which people do a lot and seem to enjoy (in comparison with exceptions and even Optionals)? NPEs are not common in development and very unusual in prod. I'm not sure I like how much ceremony there's in Kotlin to keep track of nullable things. Disagree that NPEs are a rare occurrence, that Go-style error handling is universally enjoyed (I would say it's one of the top complaints people have about Go) and that Kotlin null handling uses too much ceremony. And as for that last point, idiomatic Kotlin code (or, indeed, code in any language that has null-safety) will tend to eliminate nullability from types as much as possible, it's not really the case that most function arguments, return values, etc. really need to be nullable.
- anonymoushn 4y ago> Java tooling (IntelliJ and Lombok) is incredible Until a Java IDE can jump from an annotation to all the code that actually processes that annotation in the context of the current project, Java tooling lags substantially behind ctags. > - Gradle and maven are reliable like npm and cargo, but super verbose and confusing At one recent-ish job, I wrote some scripts to download gradle dependencies via wget and stuff them into gradle's cache because gradle was incapable of resuming downloads and multibillion dollar companies are incapable of running maven repositories on the same continent as their developers or delivering HTTP responses from maven repositories across oceans. The resulting amalgam of bash, wget, and gradle was still quite slow because it takes forever to run gradle long enough for gradle to tell you what it failed to download. > - Standard library has some issues and quirks. Like URL#equals sends a network request What. > - I just have to say, IntelliJ and Lombok really do fix Java’s verbosity. Both reading and writing. Indeed, tooling is the new syntax. But maybe some disagree. It may be useful to compare an "idiomatic Spring Boot" implementation of a small collection of related REST endpoints for a moderately complex model to an implementation in any other language and calculate how many times more files and how many times more lines of code you end up with.