The Reason Java Is Still Popular
debugagent.com
debugagent.com
If you only work with SQL Server then it is probably best you use SQL Server Management Studio. If you use different databases you will need a different client and I find with JDBC based clients you can use one client for to connect to many databases. I have seen many here complain that the Java tools are slow and bloated and look ancient. From a looks perspective you can use FlatLaf themes which look good to me. There are some nice dark themes to chose from.
[0] https://dbeaver.io/ [1] https://www.sql-workbench.eu/ [2] https://github.com/squirrel-sql-client
Working with pg in nodejs was frustrating in comparison.
Where I work now the the "Java" devs code about 80% Kotlin and 20% Java.
At my previous job we were mostly Ruby except for a service that relied on a Java library that connected to some obscure systems that no other language had a library for. Yeah, we used Java, but it was because that was our only option.
you still have to deal with all the controllers, etc.
on reddit, one of the arguments was interesting - the biggest value of kotlin in backend is using var/val instead of types and making everything public (instead of getters/setters).
would that be correct ? Lombok doesnt fix this ?
That reflects my experience
Java devs seem to be moving to Kotlin, or as some would say JetBrain's C# hehe
Stuff he gets right:
* Getters/setters is a nonissue
* Operator overloading is a nonissue. I did like how Ceylon handled it (operators are aliases for normal spelled-out methods) but honestly overloading is not something I ever miss. And it was a minefield back in my C++ days.
* Dependency management in Java is decent. It's worse in every other ecosystem I've encountered.
Stuff he gets wrong:
* Checked exceptions are horrid. The people who hate them aren't driven by laziness, they're driven by the desire to use standard interfaces - especially now that we have lambdas. You can use `Runnable`! Unless your code throws a checked exception... in which case you have to go through the ceremony of wrapping it. This is stupid. You can have standard interfaces, or you can have checked exceptions, and standard interfaces are vastly more useful.
why getters/setters.
Most frameworks (and not languages) use everything public. Rails, React, golang's frameworks, flask/fastapi. Code has generally not suffered from being public.
Would you not accept a Java framework with everything public ? i asked this question on /r/java some time back and got badly flamed. So im trying to understand this. This seems to very philosophical...but then most other frameworks in other languages dont carry this philosophy.
Every so often I want to change the behavior of something, and it's a big PITA. For example, maybe I'd like to ensure there's a default value for something that is sometimes null. If access was via getter method, I can just override the getter:
class Foo {
private final String name;
public String getName() { return name == null ? "Default" : name; }
}
No need to change the hundreds of places that call .name or .getName().This kind of thing happens often enough that it really should be baked into the language. Lo and behold, most post-Java languages support it, including C# and (modern) Javascript. Java is a bit stubborn in this regard, but Lombok solves the problem in a way that is almost language-native.
this is so cool! thanks for sharing that anecdote. trust me, ur the first person who has ever written this publicly.
so I hear your argument for getters/setters. And IMHO, all paradigms do have their usecases -probably so do CQRS and everything else.
But ultimately, you can refactor using the tools available today. I would (politely) argue that your example is also a notnull situation and perhaps i would have solved it on initialization, versus the way you did it.
Ultimately, you can create getter/setter structures in python as well. But in most large codebases, it still ends up being unnecessary.
Sometimes. You can refactor your own codebase. If you're working with independent modules, or building libraries that you publish to the world, refactor tools will not help you. You can't refactor other people's code.
Even in your own monolith, this kind of refactor is not great. You've turned a 1-line logic change into a patch that spans potentially hundreds of files. Reviewers hate that.
> a notnull situation and perhaps i would have solved it on initialization
You don't always get to decide that. The data may be serialized in from JSON, loaded from a database, imported from some weird EDI system, etc. Maybe the initialization process is not so simple, and spread out all over the codebase (or even just dozens of constructors).
> you can create getter/setter structures in python
Python is extremely dynamic and while I can't remember how offhand, I would be surprised if you couldn't simply override variable access the way you can with Javascript (eg, add a `get fieldname()` method). So you don't need "getters" the way you do in Java, which makes a distinction between field access and dynamically dispatched functions (and has performance benefits).
So this is the thing - that there is nothing in python at a language level that enables/disables this. it just doesnt give a private construct. same as in javascript. you can add getters/setters if u want. in fact ECMAScript introduced getters/setters - https://www.w3schools.com/Js/js_object_accessors.asp
But the thing is, huge huge codebases exist without private.
There's nothing that i can see in java that requires private. not to say, ur not wrong...but so it is with almost all patterns. even CQRS. There is a certain level of complexity when it makes sense. The question is - how early do u enforce this ?
Yes, there is. `@property` allows you to change a vanilla field to a getter/setter without modifying client code.
>> override variable access the way you can with Javascript (eg, add a `get fieldname()` method)
> in fact ECMAScript introduced getters/setters
That exchange was weird.
> huge huge codebases exist without private
I'm honestly not quite sure where you're going with that. Huge codebases exist in COBOL too.
It sounds like you're trying to argue that the software world doesn't need encapsulation. I disagree. Maybe you took my comment "99% of the time it's fine" the wrong way - 99% isn't good enough. The 1% wastes a lot of time and energy, it's better to have language support for encapuslation.
Java's support for encapsulation (getters) is pretty tedious. Lombok and records (too modern for this codebase, unfortunately) fix that. Thus "getters/setters are a nonissue".
Not just for existing developers, but also people who are new to the language and are doing the old golang vs java eval.
https://github.com/gwizard/gwizard
I wrote it, so feel free to consider me biased. That said, "wrote" is a strong word, it just glues some other projects together with Guice. Not much actual code there. Which may be the answer to your question - if you asked me what's wrong with other frameworks, "too much code" is a decent answer.
I have been wondering something - wiring different components together and building "up" something.
versus
take Spring Boot and create a DSL/Lombok-like layer on top which abstracts out the "too much code" and unpleasantness. Like a Nextjs that builds on top of Reactjs.
Why the first and not the second ?
I greet your suggestion to add another layer of abstraction on top with great skepticism.
Foo class can only contain something, but not make any decisions, no matter how small, because it's not obvious whether a decision is still small or not anymore.
Getters are still useful though, for example:
class Foo {
// all contents of Foo, but we want to keep it serialized for performance reasons
private ByteBuffer bb;
public Long getId() {
return bb.getLong(ID_OFFSET);
}
}> You don't always get to decide that. The data may be serialized in from JSON, loaded from a database, imported from some weird EDI system, etc. Maybe the initialization process is not so simple, and spread out all over the codebase (or even just dozens of constructors).
Real-world codebases (the ones out there running profitable businesses, built by programmers that have come and gone) are rarely so clean and pretty that you can say "well, you just should have initialized it properly in the first place!" To that, I offer you Mike Tyson's incredibly apt programming advice: "Everyone has a plan until they get punched in the mouth".
Since Java 17 there are records.
Meaning, your framework users can depend on any implementation detail and if you change that detail, the framework will break for these users. They will be disappointed since they didn't know they were doing something wrong (all is public and thus available to use).
Which is where a lot of the JS/Ruby/Python frameworks operate. You're not wrong - my point is that a lot of places, it is not necessary.
For the price of increased breakage rate.
And then people still wonder why many big projects keep choosing Java instead of Ruby.
I spent 10 years suffering under a ruby app where literally every interface had to be considered public because someone might have gone code surfing and decided to be clever, so literally nothing was a simple code refactoring of private interfaces that nobody should touch.
I don't understand what kinds of software people who make this argument write, but I assume it has to be something like web services where the http routing layer is the actual public interface definition and so you're benefiting from strong encapsulation at that layer. Yes, in that case the language doesn't need strong encapsulation because your external framework already provides it for you.
this is actually one of the best ways anyone has put it. You may be right. I have often wondered how does the huge amount of Ruby/Python/JS work in building large companies and products, when Java mandates all this amount of massive complexity.
You may be right here - in the web services world, the hard contract of the API layer makes up for less strict encapsulation everywhere else.
Records are imo a really great addition, making the difference explicit.
As for why private fields are important, think of a class implementing a circular buffer with a fixed-size array. Here, the start and end indices used are private state, which is a must for proper OOP — without it it couldn’t enforce class invariants.
You would not break the contract of maliciously trying to access variables that shouldnt be accessed.
For example, a popular convention is to have underscored variable names (__thisisprivate). Works perfectly OK.
99% of getters/setters dont do anything more. They do exactly this. No validation, nothing. So I'm questioning the ordinary....not the special cases.
You wouldn't. Someone else would. Without fail.
But at this point with records... I don't care. I declare a Integer 'bla' and a 'getBla()' is made available by the IDE right way. Sometimes the records fields end-up being accessible without the getter. ( declaring the record in another class for instance...). But that is also a moot point : all the data they are holding is final and I know what can be null or not.
Culture, I guess...
It's not my favourite language, I've worked with quite a few others, Java has just been the most consistently less painful than anything else. Ecosystem is pretty good, dependency management works; refactorings are easy with modern tooling and the typing system also works fine.
Yes, it's verbose as hell and you definitely will depend on some basic tooling to be productive, I've worked in monstrosities that we managed to strip out piecemeal and get the codebase in good shape and modernised, it does require time and an experienced team though.
Like you mention, the systems keep chugging along, in places with good engineering practices it's also a given to keep updating those codebases, simplifying and it happens organically when systems are running for 8+ years with 20-30 different engineers rotating in/out during this time.
It works, it's not beautiful, it's not concise. It has quirks and gotchas as any language, and requires tooling, but it's quite mature and modernised enough to be a safe bet for bigger projects. Better than any alternative I've had experience with at scale.
Came here to say exactly this. Exceptions are a poor-man's implementation of an error-handling applicative or monad type. Checked exceptions are especially terrible because their usage forces handling of exceptions in every layer of the call stack above the point where the checked exception might be thrown instead of simply writing a single exception handler at an appropriate layer.
Here are my reasons for thinking so: https://news.ycombinator.com/item?id=32944346
True, but in those languages, exceptions can be thrown from anywhere anyway.
> Checked exceptions are especially terrible because their usage forces handling of exceptions in every layer of the call stack above the point where the checked exception might be thrown
That's not true. Handling a checked exception in one layer means you don't need to handle it in the above layers.
For a lot of things, it's fine. And there certainly are potential problems with operator overloading. But the experience of, say, reading/writing, linear algebra code using a C++ library with arithmetic operations on vector and matrix types vs using its java bindings where that's all done through explicit method calls wildly favors C++.
As a language feature I can't feel more than ambivalent about operator overloading. Kotlin has it, Java doesn't, I'm ok either way.
Java the language is really coming along nicely. With records, pattern matching, string templates, virtual threads, value types (in the work), and more, it's shaping up to be a top notch development language.
The user base kind of helps the developers find the fixes way too easily compared to any other language.
I doubt it is ever going to lose it's popularity as Java is very good to accept good changes(although slowly). The best thing about java is it provides code stability and backward compatibility and this is the reason it will thrive even more.
Similar to C++ getting replaced by go and rust everywhere, Java's time has gone. It's just running on momentum at this point.
The JVM will likely continue on though
You are either wildly exaggerating or living in a bubble.
There's no value in using it for future projects other than a wider pool of developers to source from... a network effect that will diminish with time.
Java is objectively dated in so many ways, it's not really defensible to say otherwise. Tons of unnecessarily verbose and boilerplate aspects of the language.
Ignoring network effects and existing libraries, which language feature of C++ makes it better than a Go or Rust for similar use cases? Which language features are more concise and easy to use? What objective traits of the language make it superior?
In general, I'll take a somewhat mediocre tool where I can look up examples/libraries to do everything I need, with a large pool of competent developers to hire from, over an excellent tool that may or may not do everything I need at the level that I need, that relatively few people know how to use.
Of course, standards can change. But Go and Rust have a long way to go to build the network effects/libaries/ecosystem equivalent to that enjoyed by c++. I'll let the enthusiasts figure that out while I build things that get deployed, I look forward to the day it's ready, lot of promising features in those languages. Thanks in advance!
In 20 years Java will not be the default choice for the vast majority of projects, just as C isn't now, despite being so in the 80s... it's obvious from the verbosity of the language. Network effect will fade over time.
Kotlin is already a drop in replacement for Java that is less verbose, more ergonomic and still compatible with the existing ecosystem. Why would anyone use Java over Kotlin on a greenfield project aside from prior familiarity? They wouldn't
Prior familiarity is a very good reason to pick an option for a greenfield project if you're operating on any type of serious budget (time or money), especially if you need to hire others to help out. There's also the annoying reality that most libraries for new/up-and-coming languages are simply inadequate, despite whatever claims they make.
For instance, one of my personal side projects involves getting familiar with WebAssembly (note: not on a serious budget), and I'm using emscripten to transcode because that's what the internet seemed to think was the closest thing to a standard toolkit. I found a bug simply by combining two pieces of example code from Emscripten's own documentation (you'll note I'm transcoding from c++ due to prior familiarity): https://github.com/emscripten-core/emscripten/issues/17143
This is not a dig on emscripten, merely pointing out that it's probably not mature enough for the stress of corporate-scale development, where you encounter all sorts of crazy edge cases well beyond the sample code. Java over the years has obtained that level of maturity. The edge cases are largely solved or at least known, and there's an army of experts and consultants ready to help if there's a problem. When time is money, that matters. It determines the risk profile of any project, greenfield or otherwise.
Java's momentum hasn't stopped, at best it's simply slowing. And at this rate it'll take decades to come to a stop, and decades more to recede to any meaningful degree. I'll also point out that C is very much alive and well in the embedded world. Plenty of job postings looking for C experience explicitly, for new products as well as legacy.
aka Ignoring the fact that it's easy to hire developers that already have widespread experience in C++, and ignoring the cumulative effort that thousands, if not millions of developers have put into writing and testing code that I don't have to... wait, why would I ignore both of those things?
If I'm creating software in a vacuum, such that I don't have to think about things like developer experience or time-to-market, then sure, let's say that Go or Rust is definitely better for many use cases. Very few people create software in a vacuum!
C++ is in a state where it's good enough and slowly getting better. The enormous ecosystem, from libraries to game engines like Unreal, means it's not going anywhere for decades. New "greenfield" games are being written in C++ every day.
False.
> There's no value in using it for future projects other than a wider pool of developers to source from
Well, you know, that is value. And there's value in being in the same language as the libraries you use. And there's value in C++ in the embedded space. And there's value to being able to control memory alignment in the high performance space. And...
If you're writing some generic web service, sure, there's no reason to write it in C++. Your statement was far too broad, though.
Obviously wrong, but sure, go on.
> Java is objectively dated in so many ways, it's not really defensible to say otherwise. Tons of unnecessarily verbose and boilerplate aspects of the language.
What Java are you talking about? It might have been true in the past, but modern versions of Java are just normal Algols. It's on par with C++, C# and Go, the other mainstream options you'd have for a project you'd write in Java. Sure, it's not as terse as Python, but neither is C++ or C# or Go.
Which aspects of C++ are superior to modern equivalents, ignoring ecosystem and network effects which aren't facets of the language.
That was the claim. Between "Rust exists" and "the only reason C++ still exists is existing projects were written in it" there's still a fair amount of ground for you to cover.
You said that Rust is more memory safe. Hard to argue. And more concise, about which I have no information. Those are good things. But, as I brought up elsewhere in this thread:
Is Rust as easy to use in the embedded space? Is it available on as wide a variety of chips?
Does Rust make it as easy to control memory alignment, for those who need it?
Does Rust make it as easy to interface with libraries, many of which are written in C++?
Memory safety is good. Conciseness is good. Those are not the only reasons one might choose a language.
There are many modern languages that are more ergonomic and just as fast.
What matters most in high-performance computing? The algorithm, sure. What's in second place? Memory alignment.
Memory alignment determines whether or not I can use SIMD. It also determines how many cache misses I have.
Can I fight that battle using Rust? Maybe. Is it as convenient as in C++? Is any other language? as convenient as C++?
COBOL was used for a long time for various business backends... did that mean it was a great language that was going to be used in perpetuity? no. And I assume the majority of those don't exist anymore, despite existing as recently as the 2010s
Additionally, what is replacing Java in the finance space? Genuinely asking, because I have no idea, and can you point me to some companies using the stuff that's replacing Java for banking/finance/etc?
So too will Java's. The language itself is objectively more verbose than many modern equivalents. Network effects and existing libraries aren't facets of the language and over time the gap will narrow
+ I am actually not sure whether even that is true. With how great intellij is, I would honestly wouldn’t be surprised if writing a java program would come out as less keystrokes than the equivalent program in a less verbose language.
Additionally, "the gap will narrow" is not the same as "Java's time is over", which is the only thing I'm having an issue with. Over implies that the gap is already closed, but I don't think it is, and if I'm wrong I sincerely want to know about what the new language du jour of a major employment field is.
If anything, the field will fragment a bit more, but java likely never gonna die — cobol and fortran often run in VMs due to the hardware not being as long-lived as them, due to the JVM model, java is not even weak to that.
C++ as well, but especially Java likely has multiple times as much projects than all the smaller languages summed. They are ain’t going anywhere anytime soonz
No
> So much code fails unexpectedly. When you want to build a professional application you need to handle every error.
Yes
> Checked exceptions help you avoid that nonsense.
Wrong
> People hate checked exceptions because of laziness. Java guards you against yourself.
Wrong
Java checked exceptions are almost universally regarded as being a mistake because they don't actually solve the problem they were meant to solve, and they make the code extremely hard to work with.
See this post from Roman Elizarov: https://elizarov.medium.com/kotlin-and-exceptions-8062f589d0...
1. C-like language - Flip between C, C++, Java and JS with minimal thinking about syntax.
2. Build once - I can build locally and deploy the byte code straight to production. I don't need to worry about the production server having the right packages as long as everything is bundled in my JAR.
3. Libraries just work (mostly) - It doesn't matter if the library was written yesterday or 10 years ago, as long as it was written sanely, it should just work.
4. Garbage collector - Really in top class. I can create and throw away huge amounts of RAM and not have to worry about leaks and have it dealt with realitively little performance impact.
5. Memory safety - Never having to worry about pointers, segmentation faults, etc.
6. Exception handling - And if all else fails, Java will ultimately give you the opportunity to recover from many different scenarios. This may seem like lazy programming, but actually it's for the edge cases you can't think of. If your program does happen to crash, you get a very good stack trace.
Java may be cumbersome and repetitive is some areas (and perhaps the newer additions to the language deal with this), but I would take them every day of the week.
The only thing that has really left me wanting is C-like performance and networking capabilities. Most other things I want to use are very well implemented.
Well, it is basically there in hot loops. Not necessarily with idiomatic Java, you do have to use primitives but it is absolutely achievable.
Also, what do you lack with regards to networking?
Not quite in my opinion. Not bad, but it can be half performance at times.
> Well, it is basically there in hot loops. Not necessarily with idiomatic Java, you do have to use primitives but it is absolutely achievable.
Setting more intricate TCP settings, or sending ICMP, or essentially anything advanced.
Modern Java isn't really any more verbose than other languages it gets compared against. It is very nicely balanced between expressiveness and readability.
Extensions that offer syntax highlighting, debugging, refactoring, code inspection, command line integration, dependency management, etc. How is that different from an IDE?
That is such bullshit. There are plenty of very functional libraries written entirely in Java, it has a surprisingly adapt type system that makes plenty of things expressible (not monads themselves, but you can almost get there with purely generics). Vavr, jool, immutables.
And what exactly is complex? Java is on the leaner end of language complexity, just compare its number of keywords to.. any other mainstream language.
Especially the conceptual overhead of DAO/DTO, etc seems very religious in nature.
I worked on several golang projects where protobuf was used, and the same dichotomy showed up in the code. There were three types even, protobuf types, internal types, and DB types, with manual mappers and validators having to be written between them. Quite a bad, verbose, and error prone experience, especially that golang itself is quite verbose.
its the front loading of a huge number of patterns which ends up being the barrier. An argument is made for "future proofing". Its not unlike Python whitespace indentation or golang's unused variables restriction.
But the design pattern complexity is far more harder than all these things.
There is a certain degree of complexity when all of this starts making sense. Or maybe do what Redux did ... and abstract everything out to somewhere else.
u used the word "viewmodel", so are we talking about android ?
try {
// do stuff
} catch (SomeException e) {
// do nothing, maybe log it
}
I strongly agree the verbosity is a non-issue. Any modern IDE just fills this in for you. Yes more verbose syntax for getters/setters would be nice but it's not a big deal.But there's one point I wanted to highlight. Every language that comes after Java should've learned Java's lessons and some didn't.
C# quite famously did. C# really is Java 2.0. No checked exceptions, reified generics (rather than type erasure) and some cool stuff too (eg LINQ, partial classes).
Other languages (eg Go, Rust) largely moved away from exceptions entirely. Personally I agree with this. Exceptions are a false economy that devolve into control flow that's hard to follow (eg Java has a parse number from string that throws a ParseException if the parsing fails and that's just not an exception).
But the big one is dependencies. Every external dependency system that came after Mavaen should be at least as good and many aren't. I'm looking at you, Go. This was a shocking omission for something aimed at being a better systems programming language (which it never would be as a GC language but that's another story).
But Java is proven, mature and sufficient. That's why it's still used.
I don't really think that Go was intended to be a systems level programming language, I've never used it that way personally. I think of it as specialized towards being an excellent applications level programming language with rich-enough system level interfaces where necessary. People who do stuff like programming a bootable OS in go aren't doing it because they intend to develop it into something everyone will use, it's done more like an exercise.
Basically, checked exceptions could have worked, if they were the only type, and had better ergonomics of use, and a language culture that emphasized correctness more.
Checked exceptions were wrong for Java, but that does not mean they are wrong universally.
throw checked new Exception();
Then the caller knows there is a special reason to handle this exception, and it's also easy to write a tiny wrapper to neutralize the check, if needed.For example: failure to open a file could be nothing major in one case (just return null), needs to be handled in another, or should cause the entire application to exit. This depends on what file was opened - but it does NOT depend on the type of error.
I’m not claiming that Java’s execution of checked exceptions is good, it unfortunately does have a few inconsistencies (lambdas don’t operate well with them, also inheritance is not a good match for exceptions), but it was pretty universally ditched and I think it very well deserves another chance.
I think they can have its place but operating well with lambdas would be a must... If Java supported a multi-value return, like Go and Python do, and control flow was based on `var a, err = obj.exec()` or some other syntax that could work nicely with Streams and the functional features of Java I wouldn't have an issue with checked exceptions. A multi-return for errors with checked exceptions would even allow the compiler to narrow down all the possible `err` types you could get, automatically generate a Java 17 `switch()` to parse through all the possible cases of checked exceptions. It could help a lot with error handling.
I’ve been writing java code since about 2001 and up until Java 8 this was fairly true, and definitely a fantastic thing.
However the leap from 8 to 11 or 17 (all LTS releases) is a painful process. We are moving from 8 to 17 at work, but the number of issues we run into with incompatible libraries is a right royal pain. Especially when it’s down to the (imo) silly decision to rename the java EE packages to jakarta. A pointless exercise (imo) that has held back a lot of organisations from upgrading sooner.
This is his conclusion, and I, well, agree. While I was well versed in Java, once I started playing around with Kotlin (which was around the time Java was stagnating), I never really looked back.
Because coming from the flask, go, jsapi ecosystem...it was very hard for me to be productive in the jvm world (kotlin or java), cos of the frameworks.
But from a language aspect alone, I’m just so much more productive when cranking out code in Kotlin compared to Java.
WASM might shake this up in a few years. We'll see.
Not if you're trying to work with other algebraic data types.
> If I see a + b I know that this is either a string or a number not some hidden method.
Great if your world only consists of numbers and strings.
And really in this day and age with strongly typed languages your IDE should be able to easily tell you if someone is doing something totally insane with any given operator. In most cases, they won't be and it'll be easy to decipher exactly what they mean.
Stop trying to prevent everyone from being able to do useful things just because some people write crappy code that abuses language features.
what would make you choose java :
1. is it a better framework than spring boot
2. is it a better tooling like heroku or something for java
3. is it better community & programming paradigms ? I once asked a question "can i write a java api using all variables as public" and got flamed pretty badly. Do people want an alternative to the MVC/DAO/DTO structure ...where the community doesnt flame them ?
4. is it something else ?
Because based on docker pulls, java still is probably just as popular as nodejs or something.
what would make java sexy again ?
I'm less than enthused by the spring ecosystem. It does help you start quicker than you would without it but while running it in production over time I think it has costs I'd rather not pay so I suppose a better framework would excite me too.
Java as a language is fine and I have no real complaints there.
can you elaborate on this ? really have been considering spring boot, etc. But coming from the python world ...i feel it cognitively very hard to get through. But im super keen to know what issues come in production.
Most of us were under the impression that Spring in production just works.
>so I suppose a better framework would excite me too
especially from this perspective. What would you want ?
We have a saying about these types of frameworks: They are a great way to turn compile errors into runtime errors.
When you are just starting out on a project it's great. You get up and running fast and as long as stuff doesn't change too much you are probably fine. But when your codebase reaches 5+ years of age it's highly likely to see a spike in "runtime errors" that potentially could have been compile time errors every time you release and releases get nerve wracking for a bit until eventually the codebase get's frozen in stone and someone starts suggesting we rewrite it.
1. is it a better framework than spring boot
Dropwizard has a refreshing approach.
2. is it a better tooling like heroku or something for java
Working with kubernetes is seamless. Lots of ready made hooks to your JVM and your application
3. is it better community & programming paradigms ? I once asked a question "can i write a java api using all variables as public" and got flamed pretty badly. Do people want an alternative to the MVC/DAO/DTO structure ...where the community doesnt flame them ?
There is a strong push toward immutable everything and final all variables. It's ugly like often with java, but it's attainable by settings the linter to the max and adding yet another annotation ( to the package folder itself, and it's not enforced by the compiler unless you ask for it... )
4. is it something else ?
At this point I can crank out things fast in functional & immutable manner. Tests write themselves. JVM is rock solid.
It already has loom in preview which will make the whole previous thing suddenly non-blocking (this is uniquely possible with java due to the ecosystem being 99.9+% purely java, no FFI).
Once value types arrive, I will honestly see no niche other than embedded/lower-level not served by this platform. Oh, and there is of course Graal which will bring all these capabilities to even polyglot code bases, you can just execute some python script on basically java objects with java’s speed!
just curious - i have heard comments of people looking for a simpler framework. And especially cloud integration/deployment.
I do miss the nice IntellIJ java features.
We also needed fast start times and hopefully graal continues to mature. We also worried about graal costs given oracles history.
We've seen the hoops that people had to jump through to get golang GC to work properly once they hit a certain scale.
The GC benchmarks we did showed that Go would work as well, so we begrudgingly moved to it.
i thought the JS ecosystem was crazy full of packages.
I have spent a long time as a Java dev using Maven, and the past few years floating around some other projects (C#, PHP, Python, a tiny bit of NodeJS) and continually find myself wishing to have Maven back, so I suppose YMMV.
Now let's munge in plugins and plugins of packages and it gets messy real fast. Outside of the outdated XML, is there a way to deal with these problems cleanly?
But Maven doesn't need a "lock" file, and can still download a reproducible tree of dependencies just fine, so that's a win in my book!
Yes, there's been jlink for a long time, but it still generates a folder, not a single file.
There is jpackage, but it generates installers for various platforms, not an executable binary.
Doing more work at scale these days and running into Elasticsearch, NiFi, and so forth.
I don't have to like the fact that java has to have its own keystore, and that the elasticsearch.service invocation has 35 (!) arguments by the time it reaches its launch. But these enterprise tools provide a methodology for getting granular when it makes sense.
The annotated version is more terse because he's showing its usage. For the non-annotation version he's showing the implementation.
edit (because I forgot to quote the article directly):
The syntax is more tersex.get(y) x[y]
I'm counting 4 charcters.
I think this is a bad approach. Developer should know his components, and adding one shouldn't be a frequent event.
Adding components is about reusing code while replacing them is about having to track security issues (which is very good now, via maven) and new functionality being added (which you may or may not want). Same as NPM or any other package manager that existed.
In the NPM world there are too many small libraries that create a dependency graph that's impossible to parse mentally. No one knows your true dependencies and that created many problems.
In Maven libraries are sometimes too big. That's true. But most of them are closer to the size that gives a library a bit of "meat". Obviously YMMV.
ResultSet rs = DB."SELECT * FROM Person p WHERE p.last_name = \{name}";
This when it becomes valid java will not allow an SQL injection attack. The name part would be properly passed as a parameter. Not a string concatenation. Per https://openjdk.org/jeps/430
If that was not the example you where thinking about, sorry :)
Otherwise yes don't build parameterized SQL out of strings !
So DB."SELECT * FROM Person p WHERE p.last_name = \{name}" would basically be a function call like DB("SELECT * FROM Person p WHERE p.last_name = ", name), which would do the right thing to parameterize the SQL.
It doesn't. That's not a plain string replacement...
Second, the author was using that as an example of Java showing a pattern of adding syntax improvements, which again might be something that maintains popularity.
Finally, from the article:
But let's talk about the Java we have today, not the one coming in 6 months.
It was just one talking point. Did you even read the article?- use a library that implements RFC 5322 properly.
- don't validate the email address (that is, don't try to reject most invalid addresses) and just check that the field contains at least one `@` to be sure the user didn't enter something else than his email address by accident.
Tying to perform email address validation with regex you're writing yourself is the best way to reject perfectly acceptable email address and get frustrated users.
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...
The format for emails is surprisingly complex, and while you can use a regex to catch 99% of the right values, it's very difficult to get it 100% right. Often the best thing to do is just to try and send an email to the address a validation link.
Check that its a string containing '@' with at least one character before and after the @ symbol is usually the only sensible thing to do.
This is exactly what the regex in the example is doing.This would reject valid email addresses using quoted parts like john."@".doe@valid.example.
Edit: Looking at it closely it looks like the attempt is to reject anything with an '@' in the user part, which would be an error (e.g. john."@".doe@valid.example). Except since "\S+" also includes '@' this regex will still work, but by accident. It would reject the valid email john."\ ".doe@valid.example
/^[^@\s]+@\S+$/.test("john.\"@\".doe@valid.example") == true
Edit: Hmm, I see what you mean. At first glance I thought it was just checking that it didn't start with @ or whitespace."new" keyword is basically introducing side effects, everywhere, making Java more difficult to test and confusing generations about how to do testing.
The primitive/object combination of int/Integer, et al is noise.
The reliance on annotations for modern development and the reluctance to put syntax in the language to codify obvious things. Basically requiring a pre-processing language (Spring) to do basic tasks, making development slower and more error prone.
The final keyword. The idea that you should sometimes take away developer agency, because you know the future, better than anyone. Classy.
The combination of Class Access Modifiers (which are for mixin property selection) with interface definition (what's this object's interface?).
The much acclaimed "java ecosystem" reinforces bad practices. 10 years later, PHP is derided for bad language choices but bad Java is handwaved as a series of missteps that has been corrected.
"new" keyword is basically introducing side effects, everywhere,
I don't think that's what it does. Unless you're talking about putting side effects into the constructor? confusing generations about how to do testing.
Doesn't follow from the first part. The primitive/object combination of int/Integer, et al is noise.
Somewhat agree. The reliance on annotations for modern development
Sure, the Spring ones are horrible, but the Lombok and Jackson ones are pretty decent. put syntax in the language to codify obvious things
What new syntax would you want? I guess I'd want to clean up the flatMap mess with some nice do-notation and <- arrows. The final keyword. The idea that you should sometimes take away developer agency, because you know the future, better than anyone. Classy.
Final as a method keyword? Fair enough, but I don't think I've ever come across a method that I wanted to override but couldn't (I hate inheritance)..
Final is also to try to make things immutable, but making things immutable in Java also takes more care than it should. The combination of Class Access Modifiers (which are for mixin property selection) with interface definition (what's this object's interface?).
I don't get this at all. The much acclaimed "java ecosystem" reinforces bad practices. 10 years later, PHP is derided for bad language choices but bad Java is handwaved as a series of missteps that has been corrected.
Maybe the language, not the ecosystem?>> I don't think that's what it does.
From a java testing perspective, it does. There is no way to mock something that is new'd. This is a failure of the language. ie Python, p1 = MyClass() Now you have something mockable.
> the Lombok and Jackson ones are pretty decent.
They are, but they aren't in the language because Oracle (and the existing language development practices). Actual improvements are haphazardly added to java because 3rd parties already did the work, so why should they make the language better? Just use the increasingly obscure set of 3rd party additions.