7 ms·
More new programs should be written in Java/on the JVM. Most of the reasons Java dropped out of popularity no longer apply, and at this point it is an incredib
by lukev 1y ago
More new programs should be written in Java/on the JVM.
Most of the reasons Java dropped out of popularity no longer apply, and at this point it is an incredibly stable and mature ecosystem.
I can come back to a Clojure program I wrote ten years ago and it runs great, meanwhile a TypeScript program I write 6 months ago requires a bunch of updating and cleanup.
- wry_discontent 1y agoIn the circles I see, Java isn't popular because it's verbose and boring to use. These days I don't see those as significant issues, tbh. I would prefer a Clojure program, but I'll take Java over Typescript at this point.
- Sohcahtoa82 1y ago> it's verbose and boring to use. Python code that follows traditional Python paradigms is called "Pythonic". Java code that follows Java paradigms is called "awful". To be fully transparent, I've never written Java professionally, only for a couple small hobby projects 10 years ago, plus some while in school, so my opinion isn't worth the pixels you're reading it on, but I look at most Java code with abject horror. Endless levels of abstraction. The apparent inability to write a simple function and instead creating a "ThingDoer" class with a single function called "doThing". Run-time introspection and reflection EVERYWHERE. Stack traces that are just an endless stack of calls to functions like ".invoke" and ".run". I've been under the impression that all of that is a by-product of Java's strict type system, but someone please correct me. Why do Java paradigms seem so awful?
- robmccoll 1y agoI think a lot of it is the people using it and certain parts of the culture. There are a lot of Enterprise TM programmers that seem to believe as many layers of abstraction and as much verbosity as possible with little tiny methods that do practically nothing leads to better solutions. It is totally possible to write concise and pragmatic code with Java. One thing that will be a thorn in your side though is null handling. The traditional approaches increase line count and branching. The newer(ish) Optional-based null handling is quite verbose but in width.
- ifwinterco 1y agoIn my opinion at this point null handling is the one remaining thing about Java that is genuinely bad technically
- munksbeer 1y agoI haven't seen a NPE in the wild for years. We use NullAway in our build - works great.
- johnyzee 1y agoThose are not Java paradigms per se - they're just practices of mediocre enterprise developers, of which Java has many, owing to being such a mainstream platform. As for the language itself, a lot of verbosity has been culled in later language versions, with diamond operators, lambda expressions, local variable type inference, etc. In either case, code is read more than it is written, so if a bit of verbosity makes code easier to read, I'm okay with it.
- microflash 1y agoAs someone who has seen awful code in pretty much every language I've worked with, I'd blame this more on inertia and reluctance to change habits. The bad patterns that have entrenched deep into the ecosystem are very hard to shed even when the language and platform is making progress at impressive speed.
- kbolino 1y agoThingDoer.doThing was often just functional programming squeezed into an object-oriented straightjacket. Java 8 added first-class functions and lambdas over a decade ago, eliminating a lot of the need to turn simple behavior into full-blown classes.
- sorokod 1y agoIt's a culture, not language thing. Here is a JSON parser implementation (part of PlantUML) that lacks endless levels of abstraction. https://github.com/plantuml/plantuml/blob/master/src/main/java/net/sourceforge/plantuml/json/ https://github.com/plantuml/plantuml/blob/master/src/main/ja...
- porridgeraisin 1y agoI'd argue culture solely defines the language. Is there a full library ecosystem of stuff written like the json parser you shared, which is as complete as the enterprisey library ecosystem? Similarly, SO answers? LLM output? Tutorials? YouTube videos? I think the answer is no. It's the same problem with C#. Just adding alternate paradigms means nothing. The only thing that matters is how a majority of code in the ecosystem is structured. In java, that's enterprisey code. Most code is glue code, so you're forced into the majority pattern, lest you want to write endless wrappers... On the other hand, while typescript supports a lot of the enterprisey nonsense similar to C#, the majority of the ecosystem is written with simple functions, callbacks and options objects. Not in an enterprisey way. I don't need to use decorators to use zod. People that eschew enterprisey code and prefer simple code can't switch to java or c# until the whole culture changes, regardless of the kitchen sink of features either language adds.
- sorokod 1y agoI agree with most of what you are saying except for the "solely defines" bit. The culture is a powerful force but individuals are free to make choices and the language allows for these choices.
- Mawr 1y agoSpot on. You can't separate a language from the speakers of it. You can't redo millions of hours of work put into an ecosystem.
- troupo 1y ago> It's the same problem with C#. Just adding alternate paradigms means nothing. C# is still much better because it has a lot of useful DX improvements: from object initializers to IEnumerable everywhere. It keeps the tower of abstractions lower, and makes working with the tower a better experience. Though I've only worked on microservices written in C# in .net core
- cmrdporcupine 1y agoAs others are saying, it's a culture not the language. C++ and even some Python etc written in the late 90s, 00s era has the same pattern-itis. It comes from slavish adherence to the Gang Of Four patterns books and an obsession with OO generally. Also the languages themselves were weak on non-OO abstractions and ways of doing code re-use, so for example it took forever for Java to get lambda expressions ... so people used one-off helper classes with "invoke" methods, etc.
- lab14 1y agoI think it doesn't have to be like that, but it's the way Java code has been written for ages, so those habits stuck. You can see it clearly when you bring a Java programmer to collaborate on a Ruby or Python codebase, if you let them, the will turn your codebase into an enterprise-ready mess with layers on top of layers of indirection in a blink.
- lock1 1y agoAs other sibling comments have said, it's cultural. Fortunately, there's some push toward functional & ADT-style modelling in the Java community and they've decided to call it "data-oriented programming" for some reason. Eh, I don't think Java type system is strict, nor is it the root cause of this cargo cult mess. It's probably due to many enterprise programmers who think design patterns are the building blocks of everything rather than an invisible, emergent structure.
- cryptos 1y agoOne reason for that Java style is that Java was not such a powerful language for a long time. For example lambda expressions were only introduced in Java 8 (2014) and before that developers need to work around this restriction. A common workaround were/are some annotations above of methods and some reflection magic on top. For example a life cycle callback method annotated with @PrePersist is basically the same a registering a _function_. The whole Lombok library is a massive hack to circumvent some inconveniences in Java (and in my opinion no longer needed).
- mike_hearn 1y agoWell, there are lots of people out there who view "Pythonic" as a euphemism for awful tbh. Throughout my career I've seen multiple large Python codebases be rewritten in Java after they turned into a mess, including - perhaps most embarrassingly - Google's internal code review tool Mondrian, which was written by Guido van Rossum himself. One reason Java codebases feel more abstract is that they're attempting to solve problems that the scripting worlds tend to just punt on, or handle in ways that don't scale well. And because Java's type system is nominal, solutions to those problems require names. For example, a lot of the abstraction in Java codebases is to make things deeply testable. That's what drives dependency injection, which is where a lot of BeanFactory stuff comes from. What's the Python solution to that problem? Often they just hardly have tests by the standard of Java developers! This is why Python is big in ML research where codebases are often small disposable experiments, and why after a brief era where Django was popular it sort of died off in the wider server / big data space. Another source of complexity and abstraction is a focus on pluggable ecosystems. Databases are abstracted by JDBC, and then again by an ORM, which then might be abstracted again by Micronaut or Spring, and at each layer there are multiple competing implementations available which implement standard APIs. This kind of thing happens much less in the scripting world. The downside is that scripting codebases are far more locked-in to their choice of libraries. Porting a Java codebase from one database or ORM to another is hugely easier, because the core APIs are all standardized.
- jmaker 1y agoThis is what is very often overlooked - Python and Java have an overlap, but the symmetric difference of their problem spaces is substantial. One can write CRUD servers with any language and this is what’s usually discussed in lieu of a real comparison. But this subset of their intersection is minuscule and is too shallow to hold for a comparison that would have an impact. This is universal across lots of discussions comparing “programming languages” or their “ecosystems” which is hard without material experience in all of them. On the other hand, how universal is the problem of migrating from one ORM to another? Not all problems Java I has been leveraged to solve are relevant today. This is the extra baggage we have to carry forward.
- never_inline 1y ago> by-product of Java's strict type system 1. Lack of first class functions till Java 8 is one reason old APIs are horrible with inheritance and reflection everywhere. You had to extend class and override methods even for simplest of tasks. After Java 11 the code is much more succinct and functional style. But old libraries remain. There are places where the overextensibility these libraries provide is useful. But those are few. 2. the annotation processors were late to the game - so many libraries which need to inspect object structure (such as serialization) were written with heavy use of reflection. I will give you an example of how frameworks designed for "modern" Java look like. Micronaut has something called Micronaut data JDBC - in which you just declare methods with few annotations eg `List<Book> queryTop10BooksByYear(int year)` and it will auto generate the JDBC + SQL code and handle injecting it into your service. The returned object can be a POJO without all the Proxy object circus ORMs come with. I haven't seen something as easy in Python yet. And all this happens in compile time with an annotation processor.
- AzzieElbab 1y agoIt is probably more related to people replacing multithreaded services with single-threaded workers.
- palata 1y agoI'm secretly hoping that Kotlin and Compose will bring back Desktop apps on the JVM :-).
- jareds 1y agoI'm rooting against Kotlin since it appears to be only usable with the JetBrains ide. I'm totally blind and Jetbrains tools are not nearly as accessible or easy to use as VS Code with all the Java extensions in my experience. At all the jobs I've had no one cared if I didn't use Idea, but considering it looks like there's no good VS Code tooling for Kotlin if I have to use Kotlin professionally it's going to be painful.
- ohdeargodno 1y agoAs of somewhat recently, Kotlin has a language server: https://github.com/Kotlin/kotlin-lsp https://github.com/Kotlin/kotlin-lsp Using it in vscode, while not perfect yet, is starting to be alright.
- jareds 1y agoThanks, I've starred the project so I can keep up with it. I don't currently have any plans to do anything with Kotlin but will look at this if I do in the future.
- palata 1y agoOh I didn't know about that. Is JetBrains improving on accessibility, at least, or not really?
- mdaniel 1y agoWhat's unexpected about that observation is that they have actually completely separated the presentation layer from the business logic because such a thing was required to have "Code with Me" and their "projector" project wherein one could use IJ from a browser https://jetbrains.github.io/projector-client/mkdocs/latest/about/usecases/ https://jetbrains.github.io/projector-client/mkdocs/latest/a... But, I am fully talking out of school because I don't know what the actual, no kidding, accessibility hurdles one faces when trying to do work in such a setup, nor what concessions VS Code has made to fix those problems But I do know that YouTrack has a dedicated categorization for accessibility reports and I am sure they would welcome hearing about how they could win back those audiences https://youtrack.jetbrains.com/issues?q=%23%7BUI.%20Accessibility%7D https://youtrack.jetbrains.com/issues?q=%23%7BUI.%20Accessib...
- cgh 1y agoJava is hugely popular and widely used on large backend systems. I guess a lot of people here don't work on such systems? I'm always surprised when I see comments like the parent, since in my career exposure to Java is near-ubiquitous.
- SoKamil 1y agoI suppose we are talking about user-facing desktop software.
- belter 1y agoMost of the largest cloud was built on Java....
- Noe2097 1y agoThere has been a move in the past 8 years away from Java on the back end, notably to Go, by several large engineering organizations, which made the move, "motivated" by the example of companies like Google or by projects like Kubernetes, and seduced by the promises of a language simple to learn, build, and deploy.
- p2detar 1y ago> seduced by the promises of a language simple to learn, build, and deploy That's actually quite correct and I'm saying this as someone that does Java on daily basis. Go is in fact superior in terms of deployment. I would rather deploy a Go-written service than a Spring Boot one. That being said, I love using Java for monoliths - large code bases crammed with business logic. I personally don't see Go doing very well in that direction.
- fnord77 1y agoI think Java is the best language for most medium to large projects or anything that requires threading or complicated/optimized IO Especially now that hardware architectures are getting fragmented again, I hope it becomes more relevant. I think Springframework is dragging Java's reputation down. I know Spring boot is better but it's such a monstrosity. I feel like sadly Python has won the war, though. Good enough for most things even though it is pretty rubbish. I see people trying to use Rust now for prod AI systems.
- lisbbb 1y agoWith over 20 years working with Java, I'd much prefer working on Python for lots of reasons, but a big one is that the kinds of projects that involve Java are always involve the same stupid politics and organizational struggles. I've noticed that projects involving Python are way more enjoyable with less friction, likely due to the organizations themselves being more open-minded and maybe younger. I don't know. At some point, every Java project at every Fortune 500 company I worked with was the same damn hellish mess and I had to get away from that.
- re-thc 1y ago> I think Java is the best language for most medium to large projects With this in context... > I think Springframework is dragging Java's reputation down. I know Spring boot is better but it's such a monstrosity. Is that really so? Spring's not the best, but it's definitely better in medium / large environments than a lot of other 1s. There are way more train wrecks to maintain that especially don't have any documentation or the libraries have gone dead.
- pgwhalen 1y agoJava's biggest risk towards continued adoption, by far, is the culture surrounding it - old Java programmers and old Java programs continue to be needlessly verbose, even if the language now has the tools (pretty much) to be as terse as other popular, modern languages. It's an uphill battle, but it might just climb the hill because it's still such a behemoth.
- eastbound 1y agoIt all failed when .stream() appeared. Why make people use .stream() for functional programming, plus streams aren’t even reusable, I almost wish they invented a new operator based on an exotic UTF-8 character than those 9 extra characters. Fonts should have a ligature for .stream(). And now let’s talk about .collect(toList())… And records which look like ugly beans… Java is the land of the verbose. But it can probably be solved with 9 extra characters on every line.
- never_inline 1y agoIt's very difficult for a language designer to satisify the aesthetes.
- erkkonet 1y agostarting with JDK 16, Stream has .toList() that will save you ten characters for the .collect()
- lenkite 1y agoNobody complains about the Rust turbo-fish operator which is pretty verbose too. Java has already has introduced a direct toList()/toArray() anyways. let v = (1..5).collect::<Vec<i32>>(); // Cool Rust
- eastbound 1y agoStreams should be built in collections, not a .stream().map(…).toList() convolution. In know its incompatible with weird frameworks who already overloaded the .map() method, but well… let them recompile. That was in 2008, we’d be happy by now; and Java had no qualms asking everyone to change the package names from javax’ to jakartax’ in Java 21, so they should have issued a java.collections package and deprecated the lists i java.utils.
- Foomf 1y agoOracle makes me too uneasy. Can I use Java without the worry of incurring Oracle's wrath? Maybe, if I make sure I use openjdk/jump through some hoops I'll be fine. Or, I could just use any other language and not have that worry looming over me. C# is right there if I want a java-like experience without the anxiety of Oracle breaking my kneecaps. I don't know how to use java and not violate one of Oracle's EULAs. I could read about it and figure out how to do it safely, or I could just not use java. Java isn't essential (for greenfield projects). There's lots of good alternatives, so I'd rather do that.
- thfuran 1y agoYou don't have to jump through any hoops. If you don't want to deal with Oracle, don't be an enterprise customer of Oracle and instead just get some openjdk distribution.
- brunoborges 1y ago> just get some openjdk distribution From several sources: - Oracle themselves, at jdk.java.net - Microsoft, at microsoft.com/openjdk - Red Hat ... - Azul Systems ... - Amazon - Bell Soft - Canonical (Ubuntu ships OpenJDK binaries built by them) - build yourself?
- lenkite 1y agoJust go to https://openjdk.org/ https://openjdk.org/ and click on the "download" link. Or use your OS package manager and <pkgManager> install openjdk. Problem solved. Just like any other software, you know ?
- brunoborges 1y agoThat download link takes you to jdk.java.net, which hosts OpenJDK builds built by Oracle.
- ohdeargodno 1y ago
- Decabytes 1y agoMy biggest Issue with Java, is that it isn't streamlined. There are multiple implementations of the jdk that could be used, Many different build systems, etc. The C# ecosystem is smaller for sure, but it is much more streamlined
- waldarbeiter 1y agoThe different JDK builds are almost all built from OpenJDK. Maven and Gradle cover nearly all use cases. The complexity is not that high.
- giobox 1y agoI think it is quite high, especially for newcomers to the ecosystem. The popular sdkman CLI tool for managing JDK installations provides 17 different JDKs to install: https://sdkman.io/jdks/ https://sdkman.io/jdks/ With the DotNet SDK for comparisons sake, there is but one provider, and package management is provided as first class citizen in the compiler CLI, removing the need to even pick a "gradle" or "maven" style build tool in the first place for almost any project.
- Eldt 1y agoAt the very top of the page it mentions a default which kind of negates that issue...
- giobox 1y agoIt doesn’t negate the issue at all, especially as sdkman is an optional extra tool. If working with others, that default is not always going to be the one your team develops against either. If you are just trying to pick a jdk and don’t even know sdkman exists, a sensible person will rightly wonder why the ecosystem has fractured into 17 JDKs, or you won’t notice at all and blindly pick a download from the oracle website. I’ve seen it cause confusion many times for new (and old!) Java developers. Checking a new developer has actually managed to install the correct JDK for a given project is still a thing I have to do, all the time. Sdkmans docs also have no bearing on the multiple build systems in the java world too, which again simply a non-issue in DotNet and many others.
- AlienRobot 1y agoI've been trying Java recently with IntelliJ and it's been funny watching Java's evolution from the IDE's suggestions. In Java a lot of code looks like this void foo(Bar bar); where Bar is an interface, and in many cases it only has one single method, so it looks like a callback that must be wrapped inside a class. Fortunately, Java lets you create anonymous classes to use these methods. void foo(new Bar { @override boolean baz(Fish fish) { return false; } }); I assume because this paradigm is so common somewhere along the way Java introduced "lambdas" that look like this (I learned this from an IDE hint) foo((Fish fish) -> false); But what if you have a class that has Bar.baz method signature but it's called something else like fries()? Turns out you can do this (another IntelliJ hint): foo(this::fries); This feels like a complicated way to declare a callback, but it means that if you do implement a method with the same name, you can just pass the instance, otherwise you can use the syntax sugar, e.g. saveMenuItem.registerMenuClickListener(myMenuClickHandler); saveButton.registerClickListener(myMenuClickHandler::onMenuClick); There is a lot in Java that just feels weird, though. From the top of my head: 1. No unsigned integers. "byte" is -127 to 128. I believe this means it's not straightforward to make a 32-bit RGBA structure since you options are either using a signed "red" or using a 16-bit integer to store the 8-bit values. by the way I tried to benchmark how slow Java was compared to C in a simple test (I had arr1[] with indexes of arr2[] which contained values and I created arr3[] by resolving them) and it seems to be only half the speed of C which is probably fast enough for some basic low-level 2D graphics. 2. String.split takes a regex argument and there is no standard way to split without a regex. This was really confusing to me, but fortunately it's very easy to write your own .split, so it's not that much of a big deal. 3. You can call a different constructor with this(), but it has to be the first statement in the constructor. This one is pretty crazy! It would make sense if you couldn't access member fields before calling the constructor, but having to be first statement means if you want to calculate the argument for one constructor based on an argument passed to another constructor you need to do it inside the parentheses. So far there is only 2 things I wish Java had. First the ability to implement methods in interfaces so you could use them if you have an interface instead of using a static method. Second I wish @NotNull was the default. This is a problem that Kotlin fixes so I think if you like Typescript for tis type-safety learning Kotlin would be a good idea.
- 1y ago
- iLemming 1y ago> I can come back to a Clojure program I wrote ten years ago and it runs great Is that thanks to JVM or due to the way how Clojure works? Because I can share the same anecdotes for my Clojurescript projects. I can grab any old nbb script and things just work off the bat - sometimes I have to update some npm dependency, but most of the time, things simply aren't horribly broken. Meanwhile, I just spent half a day jumping around for weird Python dependency and venv magic dance, just for the sake of running five interdependent scripts.
- devgoth 1y agoi think this is because of Clojure's mentality on backwards compatibility and not the JVM specifically. please someone correct me if im wrong tho!
- iLemming 1y agoI feel there's much more to it. There are so many pieces in Clojure that just feel like they're done right. Even after a decade of using it, I remain happy. Not a single other language (and I tried more than a few) has kept me happy for so long.
- kccqzy 1y agoIt's not clear whether the author built the Clojure program into a jar or not. If so, it would be thanks to the JVM. In any case, the dominant way people build Clojure has changed. Ten years ago it probably used lein. Nowadays a new project will probably use deps.edn.
- sunshowers 1y agoJava has the same problem most imperative languages do, which is the lack of clear separation between mutable and immutable state, rigorously enforced by tooling. Many large-scale Java programs try and work around this by using immutable collections, which certainly makes a difference but can only go so far. Java has the additional issue of being object-oriented, which leads to spaghetti parent-child relationships under stress.
- symaxian 1y agoValhalla should be able to address this to some extent with immutable value classes.
- lisbbb 1y agoAfter working with it for over 20 years, I think it's time has come and gone and that it's not the most efficient way to build enterprise applications anymore. You're lucky that Clojure program still works on the newer JVM because many of the applications I worked on, which were very large, could not be migrated to newer versions of Java. In fact, that experience repeated several times for me. I barely ever worked on anything that used the latest versions of the JVM, every place I worked was always on things like "Java 8" and crap like that. It was infuriating, but the situations were not unique at all.
- tpm 1y agoWe built an app in Java 8 a few years ago and are updating it for each LTS version, currently 21. Except for a few issues like the renaming of Javax packages to Jakarta it was pretty smooth so far.