Edit: im not advocating writing 'ls' in java, and I would also agree that java uses more memory for small programs, so its not a systems programming language probably.
Just use new() it's pretty fast.
Edit: im not advocating writing 'ls' in java, and I would also agree that java uses more memory for small programs, so its not a systems programming language probably.
Just use new() it's pretty fast.
No, people use it because we don't want to reinvent the wheel.
Spring is well documented and Spring Boot gives you a set of dependencies that all work together.
Then you don't have to spend time messing around with things like OAuth and authentication, you can just write the application.
It sounds good but in reality people end up spending time messing around with config files and annotations.
Java is really good. Java developer culture is awful.
If you instead of spring boot just pick a few dependencies you really need, you don't throw the whole Design Patterns book at it just because you can, and you don't try to make everything changeable without recompiling or redeploying, it's pretty nice to work with
But spring boot deps is infamous meme.
> Then you don't have to spend time messing around with things like OAuth and authentication
Yeah. The funny thing is reality is quite complicated and spring supports a lot of (almost) documented cases. But 99% javaspring developers do not care. I met quite a lot of experienced devs and only 2 of them know how to optimize application start or which errors Kafka wrapper would not retry and so on. Half of the non-default situations are solved via reinventing the wheel because of a lack of understanding of nuances. I can't say people are dumb, many of those devs are smart. I tend to say that ultra-framework kills people's expertise and in the long term hardly saves resources.
Someone shared a Job posting which asked for "no java experience". It was funny.
It is not inherent in Java though, and the Kotlin "developer culture" seems to be much more annotation averse (as we all should be).
Thus I'm with you that it's not a systems programming language. It seems good for processes that stay ON, like servers.
But then when compared with PHP, during development you don't need to worry about the server, it just takes the most recent version of your code. Surely hot-reload can be a solution with java, but in practice it's a complication, especially if you're part of a team/project where there is no hot-reload support.
You can use as much of Spring or as little as you want. Don't want Hibernate? Use JDBC template.
I have noticed that people who don't use a framework, just end up inventing their own bespoke framework, which unlike Spring, is not documented and has no help available online.
If you really care about "not reinventing the wheel" there are ready-made paid solutions such as Auth0 and Cognito, plus self-hostable open-source options like Keycloak, Authelia, and Dex.
Also, Spring Boot itself uses third-party libraries for OAuth and Authentication, like Ninbus, which people can drop-in in their non-Spring Java apps.
In the latter case, it may actually mean a significant amount of development orders of magnitude more than looking up how to configure stuff, constant maintainance, etc.
Spring rocks.
For this specific case there's plenty...
You can use the battle-tested libraries wrapped by Spring directly. For OAuth specifically, Spring does very little.
You can use other frameworks that also have those features, in Java or in other languages.
You can use a paid authentication services.
You can use an open source authentication services.
That's not a Java/Kotlin/JVM issue.
Otherwise intelligent devs assume they can do a better job without all the "complication" and "bloat", but then just end up with homegrown unmaintainable crap that does half of what the frameworks offer for significantly more effort.
It's either stupidity or arrogance.
Annotations are declerative shorthands. How is a trivial spring boot endpoint with methods with a single @GET line above them denoting the endpoint verbose?
What about a single SQL query in an annotation above an interface method's name? Will your whole implementation of connect to db, execute query, iterate over the resulting rows, and convert them to some native object/struct shorter than.. 2 lines?
I don't see how you deduct the conclusion of reinventing wheels is the only solution of overcomplex and far from ideal frameworks. But you can categorise this deduction also.
It is obvious that most of the memory and startup overhead in their software comes from Spring, rather than the JVM. The JVM is probably not an ideal platform for writing an Kubernetes infra tool like operator or a sidecar (mostly due to heap size and more a complex binary packaging story), but using Spring Framework for writing these kind of tool is a bigger problem. If they just wrote their initial tool in Kotlin without using Spring framework at all, it would be much faster. They could even have kept Dependency Injection with a lightweight framework like Koin or Dagger (even a reflection-based framework like Guice performs worlds better than Spring).
I would probably still prefer Rust for writing most infrastructure projects nowadays. GraalVM Native Images has similar memory footprint to Go and solve the slightly troublesome JAR deployment story, but with the complex license terms for the enterprise edition (where most of the performance optimizations are), I don't feel safe using it. I also prefer Rust's concurrency model and I find cargo to be a far more pleasant experience than either Maven or Gradle, but in the end of the day, you will not see serious issues if you use Kotlin in a sane way, and you can even save on some Go boilerplate.
the lack of specific mention of scenarios and features beyond dependency injection suggests ignorance IMHO
The first thing they do is create a class and maybe even a Factory or Interface.
You can see instantly where their experience is from and it's hard to unlearn.
Then you have to work to make the libraries all work together. And deal with updates. Spring Boot allows to to update all libraries together, and know that they work together.
In Java, people will pull in a 100MB+ mega-framework for a hello-world REST service. Oh and another 50MB for ORM. Another 25MB+ for nailpolish, etc.
The extreme difference in basic developer culture causes visible differences in performance outcomes. Can't even blame the JVM - it is a superb beast that is overloaded by Java developers putting Mount Everest atop it.
Currently trying to modernize a python project that doesn't use modules, just executable python files that import each other with custom sys.path hackery, which is also used for globals, no type annotations, GLib used for everything including math and string to int parsing.
I just now used https://start.spring.io/ to generate a project using Spring web, Spring security and Spring data JPA (Hibernate).
It generated a JAR that is 52MB.
Spring (besides itself being modular, so you only "pay" for what you use) will solve all of that for me, so I only have to write the small amount of business-relevant code and be on my way. Later on, some other developer who knows spring can join the project and feel ready at home.
Compare it to a buggy, slow to develop, slow to onramp home-grown half-solution, and it's quite a clear tradeoff, unless there are very specific requirements that make the usage of frameworks a no-go.
OR. Are annotations a crutch for something that should be in the language.
Just generally, if some tool has to use annotations, then that is indicator of something that should be in the language.
"PayPal and Wal-Mart have also had high-profile switches to Node.js. Of course, they’re comparing two completely different things to make Node.js look better. In these too-good-to-be-true stories, they’re switching from a gigantic enterprisey codebase to a Node.js app written from scratch. Is there any question that it wouldn’t have been faster? They could have switched to pretty much any anything and gotten a performance gain.
In LinkedIn’s case, they had proxies running on Mongrel with a concurrency of 1. It’s like switching from using one finger to type on a QWERTY keyboard to using ten fingers on a Dvorak keyboard and giving all the credit to Dvorak for a better keyboard layout."
P.S.: Google became so awful that a search for even the direct title of the article does not land it in the top results - just references to it.
If you're trying to write systems code and want to use the JVM, GraalVM can do full ahead-of-time compilation and will get you almost instant start up with all methods natively compiled.
The trouble now it is that Spring Boot allows getting things up and running without having to know anything about what is underneath.
That is great, until you have to change the way it behaves.
On other end
Type annotations in JavaScript. Just use a language with Types.
I don't like commenting in language-war territory things but I found your comment surprising. "Rust or JVM" for infra isn't a dichotomy I would expect.
I mean... https://en.wikipedia.org/wiki/List_of_Great_Old_Ones
Truth to be told, there isn't much difference between Gradle and Gwarloth
In my defense, I had to hack around a different Python library also manipulating sys.path, which nobody likes except this one dev team in a different timezone. They somehow got a director to declare that I would fix this issue they self-created before they woke up in 8h, and I wasn't allowed to rip out the library. So, ugly sys.path manipulation in the exact way that library wants. Not proud of it, but it sounds like you were given time to engineer an actually correct solution.
I once asked the founders why they chose java; it was because it was 2015ish and they had an existing product in java and they knew it. Which makes sense to me. I think there's a lot of path dependence to language choice.
I also think the domain matters. For database based webapps, Java can be great. Lots of tooling and knowledge around it. And modern java is pretty friendly to write. Plus, if you are interacting with something over an API and deploying it via a container, who really cares what it is written in?
For kubernetes operators? Seems like a natural fit for golang. Anything kube really. I had a friend who ran a k8s consultancy for a while and said that they'd prototype stuff in python because it was easy, then implement in golang because that was what was consistent with the rest of the ecosystem.
The result is apps start really fast, can be compiled to a standalone native binary with GraalVM, use little memory, and errors that would once have resulted in a complex exception at startup now yield reasonable compiler errors instead (it has compiler plugins to make this work well).
I can't say I've spent much time messing with annotations or config files in this project. Certainly, what little time has been spent on the framework is more than saved by what it does.
[0] https://discord.com/blog/why-discord-is-switching-from-go-to...
Developers should not be writing code. Period.
Stupidity and arrogance is ruling everywhere.
I have some issues with the Java language (though Java 21? Actually pretty ok!), but there's no question that there's a lot of great stuff in regards to libraries in Java land.
A lot of the stuff that's just built into the JDK is already very good, for example. NIO can be a bit hard to work with, but is generally very good, fast, and reliable. A lot of the concurrency abstractions (e.g. BlockingQueues) are really pleasant to work with for most concurrent programs, the different types of mutexes/locks give access to most of the patterns you want, and the thread-safe collections like ConcurrentHashMaps are very boring, in that they work pretty much exactly as I want them to.
If we extend to third party libraries, it's even better. Vert.x and Disruptor, for example, are downright excellent tools for wrangling concurrency.
The issue is that it feels like a lot of Java developers are stuck in 1999; it can be like pulling teeth to even use NIO, which isn't exactly "new" at this point. When I wrote some stuff using BlockingQueues instead of throwing `synchronized` everywhere, people acted like I was grabbing this was some exotic code from a distant land that had never been tried before, When I imported Vert.x into my project because I needed to run a lot of non-blocking concurrent tasks, it required a lot of justification for using it instead of using threads everywhere.
Vert.x is a lot of fun, and I've gotten pretty decent performance with its SQL libraries in particular, though I'm not sure I'm a huge fan of the EventBus. I've had better luck with LMAX Disruptor, at least for the data-processey stuff that I do.
But as I said, there's a ton of really great libraries in Java. The language isn't perfect, but Java 21 fixes a lot of my gripes, and it's nice to have a ton of really well-tested libraries to minimize how often you have to reinvent the wheel.
I might agree if you're speaking about Java since ~11 or so.
One of my biggest complaints about Java, especially before the lambda syntax caught on, was how many extra files it made me create. I felt like every project had lots of wrapper classes, and people would make a make a file for each class.
You could argue that that was "bad" Java and they should have nested the classes, and that's fair enough, but it certainly wasn't uncommon Java. It artificially makes the language feel way too verbose if you have ten files more than would be necessary in a comparable language.
Once people started to embrace the lambda syntax, I feel that Java got immediately more fun to write; you weren't constantly creating one-off instantiations of interfaces or classes (well, at least not explicitly anyway), and the language felt considerably more streamlined.
Java 21 is actually one of the most pleasant surprises I've had in quite awhile in the tech world, in that I'm actually having fun writing Java. Sealed interfaces and record patterns make some code considerably more pleasant, and I actually have been writing Java in my free time, which is something that I would have said would never happen if you had asked me five years ago.
ETA:
https://youtu.be/jgkEHoc3YUw?t=288 See! I even said I would never enjoy writing Java!
Sometimes --in Spring Boot-- they hook different systems up with eachother: this makes the framework very "magic". I really dont like that: I want to be able to CTRL-click my way to understand how everything works!
I think a lot of people are noticing the changes Java has had in the previous years. The language has made a lot of improvements, and I feel that the mind set of the community has changed. The old enterprise way of factories and unnecessary abstractions have lost a lot of popularity, and is mostly still alive in legacy software/teams and universities who have not yet caught up.
Even Spring Boot is now a valid approach for getting sh*t done for startups. There are of course frameworks that are more light weight, or you can start from scratch and choose your own libraries to keep the size down. But SB is simply good enough for most use cases, and even supports native compilation now.
I use Spring Boot at my day job and write mostly web services. I don't spend time messing around with config files and annotations. When I create a service class, I annotate it with @Service, and that is mostly what I need.
Example:
@Service
public record ItemsService(ItemsRepository repo) {
public void doStuff(String country) {
var items = repo.findByCountry(country);
// do stuff with items
}
}
Later versions of Spring Boot has reduced a lot of the annotations necessary, like @Inject if you use constructors etc. There are of course other annotations and configurations, but 90% of what I do is similar to the example I gave above. Things may have changed since last you used it, but the amount of "magic" and annotations is often much less than what is posted in these types of discussions.But that’s obviously not the language’s fault. There are frameworks in Java that I think are great, like Vert.x; hell even going super low-level with NIO is straightforward enough if I really need control of HTTP stuff.
The stuff I really have the most fun working with is concurrent and distributed programs, and I think Java (or at least the JVM) is pretty hard to beat with that. Vert.x, Disruptor, and even the built-in JVM concurrency libraries (other than synchronized) are excellent; they have a Just Works quality to them.
And nowadays, GraalVM is good enough with its native compilation that you can avoid the long startup times and keep the memory under control, so it even is reasonably ok for custom command line tools.
If you don't want or know how to do this, then there are all the other solutions.
Either way: authentication in a Spring app is the definition of "reinventing the wheel".
To me being able to CTRL-click my way into the libraries is very important. Overuse of annotations (a.k.a. magic) breaks that. It is what monkey patching is for Ruby. The beginning of the downfall IHMO of an otherwise great language.
Luckily Kotlin's culture avoids this.
> It is not inherent in Java though
"Coupling by annotation" culture (which diminishes many of the benefits of using a typed language, as it pushes coupling to runtime and by means of reflection) IS inherent to SpringBoot. Hence my distaste for it.
Java's okay, prefer Kotlin though these days.
I can fully see how and why this might have grown historically in ye olden days of python2, but it's not sustainable to continue adding floors ontop of a rotten foundation. Code needs maintenance like anything else, and far too often there's no budget or time available for it. Even if that maintenance would reduce the overall workload.
Unless you're doing something super weird your infra code is gonna be running for way longer than you spend writing it so who cares if it takes an extra 20%/30%/50%/whatever time to write?
Where are you working that you encounter these people? I've been doing Java for about 15 years now (C++ before that) and as the years have gone by I just don't encounter this stuff. I do work in finance technology, so we're not doing crud apps, maybe that makes a difference. Granted, there is a lot of "C in Java" code around in this industry.
I dunno, some databases and things like Lucene are written in Java.
Isn't async unnecessary now? Threads are now cheap enough that its much easier to write sync'd calls on a thread.