What I've discovered that has changed recently is that the Graal-compiled Closure is now as fast as other tools, but also that other tools seem to produce about as good of code. I suspect J2CL might particularly benefit from Closure in that it likely generates a lot more dead code.
While I suspect this could be much better than Google Web Toolkit the same problems will continue to exist. The primary problem was Java developers compiling code where they had no idea what the output was doing, which becomes a problem when they encounter a defect or fail to achieve a business requirement. The added problem with GWT is that no JavaScript developer wanted to touch that garbage code.
Many Java developers I worked with in the past had no understanding of callbacks, asynchronous logic, events, recursion, scope, closure, array notation (Java has this), or high speed data via random access hash maps (Java has this too). This becomes problematic because some Java concepts do not exist in JavaScript and some JavaScript concepts do not exist in Java. Often times the Java developer will still need help from a JavaScript developer to achieve basic business requirements.
Also calling Closure Compiler generated code the best of JavaScript is highly debatable.
If as a Java developer you want greater expressive freedom and more functional code like you can do in JavaScript, without sacrificing performance, you are better off writing your code in Scala. If as a JavaScript developer you want a compiler to validate your code against strict type checks you are better off writing your code in TypeScript.
In the past the only business objective behind GWT was solving for labor shortages. Java developers were common and typically competent. JavaScript developers were often less trusted or harder to find. I wonder if this is still a factor.
J2CL attempts to solve a much different problem than GWT. It does not try to replace js or js developers.
J2CL is designed for cross platform code reuse. For example, the code powering Google Docs front end needs to be written for web, Android and iOS. J2CL does the transpilation of all document manipulation and rendering logic from Java -> JS (and accomplishes this with unprecedented js code size). The UI is still written in JS.
Depends on the project. Google 'Apps' use J2CL for shared business logic between platforms, but the UI on each platform is handmade. For the Web, Soy templating is heavily used (known externally as Closure Templates IIRC), along with Closure library primitives. Style Sheets are written in Closure's style sheet syntax and compiled and optimized as well.
With the Elemental2 library and JsInterop this could easily be written in Java "to the metal" as well, but so much of existing Web code is already in Soy and JS, it makes more sense to reuse that.
We are currently looking on what to do with our quite massive GWT app. Already in the process of RPC to REST switch, with Angular, AngularDart and GWT3 (depending what it would end up to be) as options.
Just wanted to check if we are missing an alternative
Any Java developer who doesn't know about callbacks, async logic, recursion, event handling, etc isn't much of a Java programmer and sounds more like someone out of a IT-Mill shop.
I mean, come on, Java's platform APIs are full of callbacks, java.util.EventListener has been around since JDK 1.1. java.util.concurrent was introduced in Java5 which introduces a bunch of async/callback interfaces. Then there's Guava, the most popular add on library, which itself introduces a lot of async primitives. On top of that, a lot of mobile developers on Android use RxJava, and Java8, both of which heavily rely on lambdas, and introduce stream processing APIs.
The only real issues seasoned Java developers run into on the frontend is having to deal with CSS, Layout, Paint, and cross browser issues. I have never encountered a Java programmer who didn't know what recursion was. Javascript doesn't even have tail call elimination, so there's no reason why a JS programmer should be expected to have some kind of advantage in that category.
At the time GWT was created (2004), the Javascript ecosystem was absolute garbage, and jquery was pretty much the primary way most people got anything done. By contrast, GWT and Closure Compiler, enabled very large SPAs to be constructed, as well as code splitting, something that took years to finally arrive in the JS ecosystem, and even today, the code splitting I see in the wild still is inferior to what Closure's cross-module method/code motion does.
It is certainly true that the Javascript ecosystem has come a long way since ES3, IE6/8, browser compliance to the HTML5 spec has converged, and that GWT's layering over the DOM/UI is no longer needed.
But that's not what J2CL is for. J2CL is about sharing business logic between platforms. For example, Google Inbox was what J2CL was created for, 75-80% of runtime code and unit tests, are shared between Android, iOS, and the Web. On Android, the code has no impedance mismatch, and on iOS via j2obj and JS (via J2CL) the impedance is very low thanks to almost zero-overhead interop layers. J2CL is not meant for "write once run anywhere UI" The philosophy of using it is that you can, and probably should, write the UI code in the 'impedance matched' language for that platform (e.g. ObjC/Swift for iOS, Java/Kotlin for Android, ES6/TS for Web)
By contrast, approaches like React-Native to construct large cross platform code sharing are fraught with problems, from trying to share UI code, to running in resource hungry, battery draining, poor performing JS VMs.
I'd say if you're a Java programmer who wants more expressiveness AND an impedance match for the primary ecosystems Java lives in, Kotlin would be a much better target. Kotlin is dramatically simpler than Scala, has a faster and less buggy compiler, and competitive with Typescript in terms of expressiveness.
There's even Kotlin->JS, Kotlin->WASM, and there's even been some Kotlin->J2Cl prototypes.
I take it you work for Google or contribute to projects under management of Google. Perhaps Google is more selective in their hiring. My claims about Java developer generalizations comes from a decade in the travel industry with 4 of its largest corporate brands, each (at one time) employing thousands of developers. This is the reality of big corporate software development.
Take a look at any major corporate brand presence with a website and notice how many megs are downloaded for small amounts of content and tiny interactions. Consider that content quantity served on webpages has not dramatically increased since the 90s and the interactive experience has gotten better since the 90s, but not by orders of magnitude. Yet, despite high speed connections it takes longer to load most corporate websites now than it did back then.
It seems, from the bloat, exchanging developer competence for tooling and ecosystem advancement has a had a negative correlation on performance and code quality. I completely understand this is an over simplification, but most problems solved by ecosystem advancement aren't problems related to any business requirement or user concern. Most of those problems are things only developers care about. The changes to the platform that actually do relate to business concerns are generally addressed as enhancements to the technology standards that comprise the platform.
If you do work at Google you have access to economists and can get their opinion on this matter.
I do work for Google, but I've also worked at Oracle, IBM, several startups, and in enterprise consulting.
Yes, Enterprise software is full of very low quality development, but this is language independent. I have seen plenty of web developers in enterprise whose sole skill was cut-and-pasting jquery snippets from web searches and tutorials and using jquery plugins. I've also seen some pretty terrible Ruby-on-Rails stuff in the enterprise. Actually, Obamacare's launch was stymied by poor Ruby code, and I hear Square at one point had problems with their Ruby, hired a bunch of Xooglers, who redid everything in Java. (and released some kick ass Java open source libs, like Retrofit, Dagger, etc)
The common variable isn't Java, or Javascript, or tooling, it's Enterprise IT hiring inexperienced or unqualified engineers, often consultants, some of whom don't have degrees in engineering/CS, or are from body shops.
Once enterprise switches most of the legacy systems from Java or Ruby to Node, you're going to find exactly the same people writing horrible code. You can already start to see it in the Node ecosystem, and in Kubernetes (go ecosystem), with people piling high on dependencies and frameworks, layer upon layer, of new-fangled tools and magic that will solve your enterprise problems, but what it ends up doing is creating a brittle system of crushing complexity and bloat and silos of IT department people who have narrow specific skills as opposed to general purpose engineering skills.
The big tech companies in the valley don't look for candidates who have acronyms on their resumes "Java/Javascript/SQL/noSQL/RDBMS/J2EE/XML/SOAP/...." or professional training certifications, they look for people with general purpose engineering skills who can learn any language needed, and who generally adhere to good practices and habits.
Back in the 90s, I taught retraining courses to enterprise and government workers. Many of them had never done coding before outside some basic Office or Lotus Notes scripting, and some of them were former COBOL users. A lot of them were reading books like "Perl, CGI in 21 days" or "Java in 21 days". And that's the problem, because the proper way to retrain your employees isn't to send them for a crash course. It's to hire some very good engineers and engineering managers, and let them learn as apprentices having their code reviewed by them.
I don't want to bash all enterprise developers, there are some excellent companies out there doing good work. But my general impression from years of cleaning up messes I encountered in consulting, is that corporate IT departments don't care about things like code health or tech debt. This isn't a Java specific problem, it was there with COBOL, and it's there with Ruby, and it'll be there with Node. It's just whatever is Enterprise's favorite fad du jour will eventually be given a bad rep. If enterprise was using Haskell, even Haskell code would come out with a bad rep. :)
To be fair, plenty of Googlers/Xooglers/other Faang alumni produce hot garbage as well. Sure, on average you might have better code, but that doesn’t mean its good.
> "Many Java developers I worked with in the past had no understanding of callbacks, asynchronous logic, events, recursion, scope, closure, array notation (Java has this), or high speed data via random access hash maps (Java has this too)..."
What??? I find it unlikely that ANY paid "programmer" in ANY language would not have at least a decent grasp of most of those things in order to produce any correct program at all.
No, I think it's more likely that you're involved in what I've often speculated is a physical manifestation of a finite monkey experiment. The remainder of an drug-fueled late-night VC bet, no doubt. The other side, of course, is likely trying to corner the cavendish market right now - starve you guys out! Stay strong - I believe in you.
>> What??? I find it unlikely that ANY paid "programmer" in ANY language would not have at least a decent grasp of most of those things in order to produce any correct program at all.
Such ignorance is commonplace. I have seen so much evidence of basic ignorance in so much code that I do not at all dispute what austincheney has said. The worst problems appear in an area that was omitted from the list; concurrency. Many, many "paid programmers" are oblivious to concurrency issues and produce races and deadlocks throughout their work. The thought that anyone might expect them to yield "thread safe" work prior to production deployment is absurd.
As basic and simple minded as Java is, it is far beyond some large fraction of the paid programmers using it.
If this offends you and you believe this is a world where such incompetence is not tolerated please understand you are, respectfully, very wrong. The people employing such "programmers" do not care, even when they are told and provided irrefutable evidence. They want cheap. They want to check a "done" box and if problems appear later they'll make more boxes. They simply don't care.
The bulk of them are billed as high level devs complete with masters degrees and provided under contract by body shops. They are not "out of the street." They were "taught" java almost exclusively.
Generally when people compile code they may not be able to read the compiled output, but they still have some idea of what that output is doing. To prove they know what the output is doing they write positive and negative tests.
In the case of GWT the Java developers actually had no idea what the output was doing. They, I presume, had some idea what the originating Java code was doing and needed logic to execute in the browser. However, the browser is/was a foreign environment not well understood. There were times they were not exactly sure how to execute the output much less test it. They just knew GWT would generate JavaScript vaguely reflective of their Java input and that web browsers would execute that JavaScript.
It's really impossible for anyone to develop a non-trivial GWT project without having to compile in PRETTY/Draft mode and drop into a Web debugger. GWT's Java debugging support was great for business logic, but you could not step into a lot of UI code, and almost universally, you ended up looking at the source code to the Widget library to understand what's going on.
This had nothing to do with Java->JS transpilation, and everything to do with GWT's UI SDK.
If I gave a Javascript developer a heavy weight OO UI library abstraction where they constructed UIs by doing "new Listview(), new Button(), list.addChild(button), etc" and had it hide CSS, DOM, and other Web issues, you'd run into exactly the same issue of leaky abstractions and people not knowing what was going on.
The issue with GWT was API design, not language. The way Java was translated to JS (unoptimized) was straightforward and understandable and arguing otherwise IS like arguing C compiled to Assembly is a problem. J2CL even more so is straightforward, was designed to transpile to "clean" ES6 that resembles hand written JS classes.
GWT "hid" the Web behind heavyweight widgets. J2CL doesn't.
How many React JS developers have a clue as to how VDOM is implemented?
Here's some J2CL web code:
var div = document.createElement("div");
div.setInnerText("Hello World");
document.body.appendChild(div);
div.addEventListener("click", evt -> window.alert("You clicked me!"), false);
This compiles to almost 1:1 what you'd get in Typescript->JS.
I like Java (and not Scala), and I have code that I want to run both on the server and in the browser. There are several ways to run Java in the browser already, but it's always nice to have one more.
One could argue that one of main GWT's strengths was to cover all the horrible JavaScript warts, like callbacks within callbacks within callbacks within callbacks and so on, making large projects possible.
Yes - 100%. Javascript is different because the language has quirks, but that's more superficial than you would think. The runtime environment is where all the gotchas are.
Everything is single threaded, but events happen constantly and at times you don't control. However there's no good atomics support. The environment uses async for pretty much everything non-trivial but has some of the worst async primitives ever (until very recently, at least).
That make things very different to develop for, and won't be solved by writing your code in Java. It will just run into the same fundamental browser limitations.
Someone at some point (was it an intern or OSS contributor? I forgot, or maybe I'm misremembering) made a prototype Kotlin->Java J2CL code transpiler. Basically, you just need a Kotlin backend that generates Java source instead of Bytecode.
Kotlin hired the guy who wrote the TeaVM, so I think they are focusing on bytecode translation approaches to JS. We considered this for J2CL but ultimately decided to use JDT parsing from Source, because with bytecode you lose some information you have in the Java AST that requires reconstructing it.
Also, Kotlin's runtime is quite large, and if you were trying to compile Kotlin -> J2CL you'd want a customized runtime that relies on JsInterop and Elemental2 to get the smallest possible code size.
Yes, but it's somewhat bloated. J2CL+Closure optimizes code better. KotlinJS requires inclusion of a bulky runtime. Last time I checked, it doesn't do dead code elimination well (on the runtime).
Closure Compiler was built to optimize even untyped JS, and the way hybrid J2CL/JS apps work, extern files assist the compiler in "safely" doing global optimizations. It's not perfect, and you can confuse the compiler (but you can do the same thing in Java with reflection + Proguard), but it works well enough if you know what to watch out for.
I've read J2CL vs. GWT? in the readme but still do not quite understand how J2CL is different. Hasn't gwt transpiled Java to JavaScript for many years? What is meant by closure-style JavaScript? That it uses jsdoc type annotations and goog.require etc.?
GWT was a transpiler, optimizing Java compiler, optimizing JS compiler (had two backends inside of it), a container for hosted development environment, an annotation processor environment (before Java annotation processors), an SDK with a huge number of APIs, a Linker, a UI toolkit, and on and on, it basically was an end to end build environment.
J2CL is a transpiler, from Java to Closure annotated JS. It does no optimizations. It has no APIs. It only deals with standard Java inputs, everything else: SDK, debugger, optimizer, build time processing, edit/refresh, etc all has to come from the rest of the toolchain.
GWT was monolithic. J2CL is a step in your build file.
J2CL also produces smaller code than GWT, compiles faster, and fits into existing JS ecosystem a lot better. It's not hard to say, wire up J2CL code with any arbitrary TS or JS node module.
The rise of the various open source solutions is relieving but I don't feel confident recommending them yet over say TypeScript. I wish Oracle would see the opportunity here to win back some space of user apps where Java had mindshare and make a compile target. It's not easy I know but still I wish.
36 comments
[ 2.2 ms ] story [ 89.3 ms ] threadHere is a good article about Closure Compiler optimizations which J2CL uses as its optimizing compiler: https://medium.com/@thomasdeegan/10-optimizations-closure-co...
This website has Closure Compiler compiled by J2CL running in the browser itself!
https://closure-compiler-debugger.appspot.com/j2cl_debugger....
https://evmar.github.io/js-min-bench/
What I've discovered that has changed recently is that the Graal-compiled Closure is now as fast as other tools, but also that other tools seem to produce about as good of code. I suspect J2CL might particularly benefit from Closure in that it likely generates a lot more dead code.
Many Java developers I worked with in the past had no understanding of callbacks, asynchronous logic, events, recursion, scope, closure, array notation (Java has this), or high speed data via random access hash maps (Java has this too). This becomes problematic because some Java concepts do not exist in JavaScript and some JavaScript concepts do not exist in Java. Often times the Java developer will still need help from a JavaScript developer to achieve basic business requirements.
Also calling Closure Compiler generated code the best of JavaScript is highly debatable.
If as a Java developer you want greater expressive freedom and more functional code like you can do in JavaScript, without sacrificing performance, you are better off writing your code in Scala. If as a JavaScript developer you want a compiler to validate your code against strict type checks you are better off writing your code in TypeScript.
In the past the only business objective behind GWT was solving for labor shortages. Java developers were common and typically competent. JavaScript developers were often less trusted or harder to find. I wonder if this is still a factor.
J2CL is designed for cross platform code reuse. For example, the code powering Google Docs front end needs to be written for web, Android and iOS. J2CL does the transpilation of all document manipulation and rendering logic from Java -> JS (and accomplishes this with unprecedented js code size). The UI is still written in JS.
Java -> Android
Java -> Backend Server
Java -> J2objc -> iOS
Java -> J2CL -> JS/web.
With the Elemental2 library and JsInterop this could easily be written in Java "to the metal" as well, but so much of existing Web code is already in Soy and JS, it makes more sense to reuse that.
We are currently looking on what to do with our quite massive GWT app. Already in the process of RPC to REST switch, with Angular, AngularDart and GWT3 (depending what it would end up to be) as options.
Just wanted to check if we are missing an alternative
I mean, come on, Java's platform APIs are full of callbacks, java.util.EventListener has been around since JDK 1.1. java.util.concurrent was introduced in Java5 which introduces a bunch of async/callback interfaces. Then there's Guava, the most popular add on library, which itself introduces a lot of async primitives. On top of that, a lot of mobile developers on Android use RxJava, and Java8, both of which heavily rely on lambdas, and introduce stream processing APIs.
The only real issues seasoned Java developers run into on the frontend is having to deal with CSS, Layout, Paint, and cross browser issues. I have never encountered a Java programmer who didn't know what recursion was. Javascript doesn't even have tail call elimination, so there's no reason why a JS programmer should be expected to have some kind of advantage in that category.
At the time GWT was created (2004), the Javascript ecosystem was absolute garbage, and jquery was pretty much the primary way most people got anything done. By contrast, GWT and Closure Compiler, enabled very large SPAs to be constructed, as well as code splitting, something that took years to finally arrive in the JS ecosystem, and even today, the code splitting I see in the wild still is inferior to what Closure's cross-module method/code motion does.
It is certainly true that the Javascript ecosystem has come a long way since ES3, IE6/8, browser compliance to the HTML5 spec has converged, and that GWT's layering over the DOM/UI is no longer needed.
But that's not what J2CL is for. J2CL is about sharing business logic between platforms. For example, Google Inbox was what J2CL was created for, 75-80% of runtime code and unit tests, are shared between Android, iOS, and the Web. On Android, the code has no impedance mismatch, and on iOS via j2obj and JS (via J2CL) the impedance is very low thanks to almost zero-overhead interop layers. J2CL is not meant for "write once run anywhere UI" The philosophy of using it is that you can, and probably should, write the UI code in the 'impedance matched' language for that platform (e.g. ObjC/Swift for iOS, Java/Kotlin for Android, ES6/TS for Web)
By contrast, approaches like React-Native to construct large cross platform code sharing are fraught with problems, from trying to share UI code, to running in resource hungry, battery draining, poor performing JS VMs.
I'd say if you're a Java programmer who wants more expressiveness AND an impedance match for the primary ecosystems Java lives in, Kotlin would be a much better target. Kotlin is dramatically simpler than Scala, has a faster and less buggy compiler, and competitive with Typescript in terms of expressiveness.
There's even Kotlin->JS, Kotlin->WASM, and there's even been some Kotlin->J2Cl prototypes.
I take it you work for Google or contribute to projects under management of Google. Perhaps Google is more selective in their hiring. My claims about Java developer generalizations comes from a decade in the travel industry with 4 of its largest corporate brands, each (at one time) employing thousands of developers. This is the reality of big corporate software development.
Take a look at any major corporate brand presence with a website and notice how many megs are downloaded for small amounts of content and tiny interactions. Consider that content quantity served on webpages has not dramatically increased since the 90s and the interactive experience has gotten better since the 90s, but not by orders of magnitude. Yet, despite high speed connections it takes longer to load most corporate websites now than it did back then.
It seems, from the bloat, exchanging developer competence for tooling and ecosystem advancement has a had a negative correlation on performance and code quality. I completely understand this is an over simplification, but most problems solved by ecosystem advancement aren't problems related to any business requirement or user concern. Most of those problems are things only developers care about. The changes to the platform that actually do relate to business concerns are generally addressed as enhancements to the technology standards that comprise the platform.
If you do work at Google you have access to economists and can get their opinion on this matter.
Yes, Enterprise software is full of very low quality development, but this is language independent. I have seen plenty of web developers in enterprise whose sole skill was cut-and-pasting jquery snippets from web searches and tutorials and using jquery plugins. I've also seen some pretty terrible Ruby-on-Rails stuff in the enterprise. Actually, Obamacare's launch was stymied by poor Ruby code, and I hear Square at one point had problems with their Ruby, hired a bunch of Xooglers, who redid everything in Java. (and released some kick ass Java open source libs, like Retrofit, Dagger, etc)
The common variable isn't Java, or Javascript, or tooling, it's Enterprise IT hiring inexperienced or unqualified engineers, often consultants, some of whom don't have degrees in engineering/CS, or are from body shops.
Once enterprise switches most of the legacy systems from Java or Ruby to Node, you're going to find exactly the same people writing horrible code. You can already start to see it in the Node ecosystem, and in Kubernetes (go ecosystem), with people piling high on dependencies and frameworks, layer upon layer, of new-fangled tools and magic that will solve your enterprise problems, but what it ends up doing is creating a brittle system of crushing complexity and bloat and silos of IT department people who have narrow specific skills as opposed to general purpose engineering skills.
The big tech companies in the valley don't look for candidates who have acronyms on their resumes "Java/Javascript/SQL/noSQL/RDBMS/J2EE/XML/SOAP/...." or professional training certifications, they look for people with general purpose engineering skills who can learn any language needed, and who generally adhere to good practices and habits.
Back in the 90s, I taught retraining courses to enterprise and government workers. Many of them had never done coding before outside some basic Office or Lotus Notes scripting, and some of them were former COBOL users. A lot of them were reading books like "Perl, CGI in 21 days" or "Java in 21 days". And that's the problem, because the proper way to retrain your employees isn't to send them for a crash course. It's to hire some very good engineers and engineering managers, and let them learn as apprentices having their code reviewed by them.
I don't want to bash all enterprise developers, there are some excellent companies out there doing good work. But my general impression from years of cleaning up messes I encountered in consulting, is that corporate IT departments don't care about things like code health or tech debt. This isn't a Java specific problem, it was there with COBOL, and it's there with Ruby, and it'll be there with Node. It's just whatever is Enterprise's favorite fad du jour will eventually be given a bad rep. If enterprise was using Haskell, even Haskell code would come out with a bad rep. :)
What??? I find it unlikely that ANY paid "programmer" in ANY language would not have at least a decent grasp of most of those things in order to produce any correct program at all.
No, I think it's more likely that you're involved in what I've often speculated is a physical manifestation of a finite monkey experiment. The remainder of an drug-fueled late-night VC bet, no doubt. The other side, of course, is likely trying to corner the cavendish market right now - starve you guys out! Stay strong - I believe in you.
Such ignorance is commonplace. I have seen so much evidence of basic ignorance in so much code that I do not at all dispute what austincheney has said. The worst problems appear in an area that was omitted from the list; concurrency. Many, many "paid programmers" are oblivious to concurrency issues and produce races and deadlocks throughout their work. The thought that anyone might expect them to yield "thread safe" work prior to production deployment is absurd.
As basic and simple minded as Java is, it is far beyond some large fraction of the paid programmers using it.
If this offends you and you believe this is a world where such incompetence is not tolerated please understand you are, respectfully, very wrong. The people employing such "programmers" do not care, even when they are told and provided irrefutable evidence. They want cheap. They want to check a "done" box and if problems appear later they'll make more boxes. They simply don't care.
Out of the street devs, sold as capable of doing something.
A recurring pattern in offshoring consultancies.
And no, it isn't exclusive to Java.
By that argument anything but assembler is garbage.
Generally when people compile code they may not be able to read the compiled output, but they still have some idea of what that output is doing. To prove they know what the output is doing they write positive and negative tests.
In the case of GWT the Java developers actually had no idea what the output was doing. They, I presume, had some idea what the originating Java code was doing and needed logic to execute in the browser. However, the browser is/was a foreign environment not well understood. There were times they were not exactly sure how to execute the output much less test it. They just knew GWT would generate JavaScript vaguely reflective of their Java input and that web browsers would execute that JavaScript.
This had nothing to do with Java->JS transpilation, and everything to do with GWT's UI SDK.
If I gave a Javascript developer a heavy weight OO UI library abstraction where they constructed UIs by doing "new Listview(), new Button(), list.addChild(button), etc" and had it hide CSS, DOM, and other Web issues, you'd run into exactly the same issue of leaky abstractions and people not knowing what was going on.
The issue with GWT was API design, not language. The way Java was translated to JS (unoptimized) was straightforward and understandable and arguing otherwise IS like arguing C compiled to Assembly is a problem. J2CL even more so is straightforward, was designed to transpile to "clean" ES6 that resembles hand written JS classes.
GWT "hid" the Web behind heavyweight widgets. J2CL doesn't.
How many React JS developers have a clue as to how VDOM is implemented?
Here's some J2CL web code:
var div = document.createElement("div"); div.setInnerText("Hello World"); document.body.appendChild(div); div.addEventListener("click", evt -> window.alert("You clicked me!"), false);
This compiles to almost 1:1 what you'd get in Typescript->JS.
Wasn't this the same argument made back in the day against C when comparing it to assembly?
Everything is single threaded, but events happen constantly and at times you don't control. However there's no good atomics support. The environment uses async for pretty much everything non-trivial but has some of the worst async primitives ever (until very recently, at least).
That make things very different to develop for, and won't be solved by writing your code in Java. It will just run into the same fundamental browser limitations.
Everyone and their mother writes in JavaScript nowadays. It’s gotten to be a bubble waiting to burst at this point.
Kotlin hired the guy who wrote the TeaVM, so I think they are focusing on bytecode translation approaches to JS. We considered this for J2CL but ultimately decided to use JDT parsing from Source, because with bytecode you lose some information you have in the Java AST that requires reconstructing it.
Also, Kotlin's runtime is quite large, and if you were trying to compile Kotlin -> J2CL you'd want a customized runtime that relies on JsInterop and Elemental2 to get the smallest possible code size.
Closure Compiler was built to optimize even untyped JS, and the way hybrid J2CL/JS apps work, extern files assist the compiler in "safely" doing global optimizations. It's not perfect, and you can confuse the compiler (but you can do the same thing in Java with reflection + Proguard), but it works well enough if you know what to watch out for.
J2CL is a transpiler, from Java to Closure annotated JS. It does no optimizations. It has no APIs. It only deals with standard Java inputs, everything else: SDK, debugger, optimizer, build time processing, edit/refresh, etc all has to come from the rest of the toolchain.
GWT was monolithic. J2CL is a step in your build file.
J2CL also produces smaller code than GWT, compiles faster, and fits into existing JS ecosystem a lot better. It's not hard to say, wire up J2CL code with any arbitrary TS or JS node module.
I currently use TeaVM and it's excellent, but I'll give J2CL a try.