There are tons of Java and JS full-stack jobs. At all the companies I ever worked at we never had enough people. Sure Java is not at the backend of all the tech giants, sure Java is not the most popular language in your Twitter following but Java is the language that powers a lot of internet. Your online banking probably runs on Java, your favorite online magazine as well.
Java in full-stack
In the past, there were apps fully written in Java and it's related technologies. All the views are done in JSP, if there is Java Script it's probably jQuery forced into the JSP. There is heavy use of such monstrosities such as DWR remoting or any other framework that allows you to do stuff in java that is supposed to be done the other way.
And I will not lie, you will probably encounter some of these projects but the role of modern Java is to be a server-side api. Java frameworks are changing to support this. With Spring Boot it's incredibly easy to get started with database connections. With awesome state of the art support for tools like Solr, Elastic Search, etc.. it's incredibly easy to accomplish anything. With battle-tested language, that feels more and more modern. Thanks to it's new rapid release cycle.
But Java is slow
Yes if you take a traditional Java web app and run it through a bunch of benchmarks, it will probably be slower than the same code written in Go or whatnot. But you are not Google, almost nobody is Google so that you would need to care about nanoseconds. And if speed is your thing look at stuff like Quarkus it super fast and small. It's super suitable for AWS Lambda for example.
What about frontend
Learning Java for web development in 2020 is definitely a huge advantage for you in the job market. Java/TypeScript full-stack is the best of both worlds and you cannot do wrong.
If you agree or disagree you can follow me on Twitter and reach out to me.
Top comments (17)
Whether Java is slow or not depends on what to comparw it with 😀 Java is slower than C++ but, unless you write high frequency trading bot, it doesn't matter. Java is waaaay faster than JS; javac is faster than TS compiler — and that usually matters. That's why — yes, agreed, Java backend and JS frontend is very convenient and reasonable.
Totally agree with you. And when thinking a little further, I definitely hope Kotlin will be mature enough soon, to be able to write frontend and backend in the same language. :)
Kotlin already made so many mistakes in design that I don't believe it ever be a replacement for Java at backend.
Interesting, what mistakes are you referring to? At least frameworks like Spring put a heavy focus on Kotlin now, so they are obviously convinced of it. Not to forget improvements compared to Java like Kotlin-Coroutines...
Well, answer will be long, but since you're asking...
Few assumptions: applications are living for long time, teams rather big, devs who create, maintain and extend the app often are different people. This is pretty typical for enterprise apps.
In this situation Kotlin's obsession on conciseness strikes back, because Kotlin code is much harder to read and follow than Java code. To read Kotlin code developer is ought to navigate back and forth much more often. Kotlin's conciseness is achieved by throwing out significant portion of context.
Next, 'var' and 'val' quite hard to distinguish at first look.
Next, optional chaining and elvis operator are easy to write but hard to read. This is if to ignore the fact that they're impeding the transition to functional style since they don't compose.
Next, extension methods, without strict policies and best practices tend to spread across the whole code base, blurring class API and often cause code repetition - different devs may add similar extension methods. I saw this happening even in teams consisting of just three devs, needless to say that larger teams suffer much more. As mentioned above, this can be mitigated by strict policies where and when extensions methods can be placed. Unfortunately more rules/policies/best practices results to more mental overhead and worse productivity.
Next, freedom to place any class in any file quickly results to complete mess in the code. Again, this can be mitigated by policies, which, most often are indistinguishable from rules set by Java (one class - one file with same name) except there is no help from the compiler. See note above about mental overhead.
One funny observation, which less belongs to the above but illustrates how poorly Kotlin is thought out as a language: if you have 'DSL-ised' code often, when you try to improve readability by wrapping and indenting long line you may make it non-compilable. Consequences of the optionality of the semicolon after expression.
And here you can find another similar opinion (notice that this is also enterprise experience).
About coroutines. Citing JetBrains blog:
They're trying to address the issue, but so far coroutines are not yet usable for enterprise apps. In other words, they are about as usable as Project Loom. Frankly, I see no improvement over Java.
P.S. Kotlin has one idea (not feature) which actually is very useful - separation of nullable and non-nullable types. But this idea can be easily adopted in Java code as well (with Optional).
Ok, this is truely a long answer :D
So to begin, I definitely see some of your points: conciseness sometimes comes with the loss of understandability. Since there is plenty of syntactical sugar in Kotlin, it'll probably happen that one over-engineers parts so that they become hard to follow. On the other hand, conciseness sometimes allows to grasp the overall idea of a code snippet more easily since you don't need all the ceremony.
Some of your arguments sound more like a matter of taste (readability of val/var, chaining, ...). But on extension functions I definitely agree with you, that they could easily create a mess. At least, the suggestion utility of your IDE finds them and gives you the chance to discover whatever your colleague might have already done. And they are definitely an improvement compared to Java's infamous *Utility classes.
Besides from being good style or not, multiple classes per file are also allowed in Java: stackoverflow.com/questions/233669...
I don't get your point about DSLs: a lambda needs curly braces, so your scope is limited. So what has this to do with line wrapping?
About coroutines: it's true that it's still evolving, but at least on JVM they are ready to be used. Frameworks like Ktor are built on them and Ktor claims itself to be ready for enterprise apps.
And last but not least, on nullability:
Optionaldefinitely doesn't provide any of the comfortability you have when dealing with Kotlin types. And afaik, it is not planned for Java to introduce the same concept inherent to the language.
So all in all, I would argue Kotlin is definitely ready to replace Java (while not necessary in all places), plus you have this nice multiplatform aspect which enables you to share code between front- and backend.
Agree, sometimes conciseness is convenient. But this type of conciseness is available in Java as well.
It's not about over-engineering, but rather loss of information. There is often a need to refer to declaration to clarify types, for example. This creates constant "go to declaration and back" navigation noise during reading Kotlin code written by other devs. I've observed this noise even with seasoned Kotlin devs.
Extension methods are not replacement to utility methods and Utility classes because they cover only tiny subset of possible use cases. In many cases extensions methods are attached to particular class just because so happened that they have first parameter of this class type.
var/val are not matter of taste, it's a real problem. Any editor (person, not software) or UX expert will point on this pair as a potential source of user mistakes.
Yes, multiple classes are possible, but only one public class is allowed. And, frankly, I never saw any real use case in enterprise apps code.
Under "DSL-ised" I did mean code written with infix functions.
Ktor claims nave nothing to do with everyday enterprise reality. Selection of any technology (even version of technology) in big companies are often based on risk assessment. Immature technologies like coroutines or fibers or Kotlin version 1.40-RC are of high risk and avoided at any cost.
Optional easily can provide perfectly fine level of comfort except without drawbacks of optional chaining (i.e. lack of composability). As an additional benefit, "monadic mindset" (aka "do when/if value available") has much wider application than optional chaining. For example, it allows writing asynchronous code indistinguishable from synchronous.
Taking into account that Kotlin didn't yet provide any sensible advantages over Java for enterprise environment, I see no reasons to wide adoption of Kotlin in this environment.
To make it short: I totally see most of your points, you convinced me that Kotlin has yet a long way to go before being ready for enterprise environments. Hence, only time will show, whether Jetbrains manages to reach their (assumed) goal of replacing Java or not.
You can use Clojure for that ;)
It does indeed. You can even write code that is shared between both ClojureScript on the browser-side, and Clojure on the JVM server-side. Fulcro makes extensive use of that.
I think the biggest advantage of Java is that it is around for years and there are tons of libraries written on it that are available on maven. That said, because it is an enterprise language, it requires retro compatibility and some mistakes made on Java 1.0 are still around on java 14 or whatever version they are at. If you wanna take advantage of the JVM infrastructure and libraries written in java you can also try languages like scala, that compiles to JVM and allows you to use Java libraries oob.
Java app will be very fast once you remove spring out of it. Just look at Techempower benchmark and notice that Java frameworks are among the fastest. But Spring not in this part, it resides among the slowest ones. And I completely disagree that this is irrelevant. Since majority of Java applications deployed in cloud, bad performance directly translates into higher expenses.
The job of server side languages is to glue the front end to the data store. It matters very little how fast of a language you use. What does it really do? Parse a JSON message, issue some SQL queries (with a LIMIT clause), correlate the result and generate some JSON. Then put it back on the wire. So you need a fast HTTP parser, fast JSON, and fast database driver. That’s about it.
I nearly picked up jWebAssembly today as an excuse to learn java, I want to write a game perhaps. Anyway thanks for sharing.