百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

浏览器运行 Java 的7种尖端技术!

zhezhongyun 2025-01-13 19:11 104 浏览

家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

今天给大家带来的主题是如何使用浏览器来运行Java程序,话不多说,直接开始。

1.CheerpJ

1.1 什么是CheerpJ

CheerpJ是一种企业级解决方案,通过消除客户端对 Java 的依赖,实现对Java 应用程序和Java Applet的现代化访问。

目前,CheerpJ 可以将 Java 客户端应用转换为标准的 HTML5 / WebAssembly / JavaScript以便它可以在现代浏览器原生环境中运行,从而节省企业时间、金钱和资源。

CheerpJ包括以下核心组成部分:

  • CheerpJ AOT 编译器:一个基于 LLVM 的 Java 字节码到 JavaScript 的编译器。 可用于将 Java (例如 .jar)或单个 .class 文件转换为 JavaScript。 目前支持: Linux、macOS 和 Windows。
  • 运行时库:是 WebAssembly 和 JavaScript 中的完整 Java SE 运行时。
  • 即时 Java-to-JavaScript 编译器:这是 CheerpJ 编译器的精简 JavaScript 版本,以启用 Java 的动态功能,例如反射。

1.2 为什么选择 CheerpJ?

CheerpJ 可以在浏览器上延长 Java 应用程序的生命周期,无需访问、更改其源代码。CheerpJ 的功能很强大,主要包括以下内容:

  • 100% 转换 Java,包括反射、代理类。直接在 Java 字节码上工作,无需干预源代码。
  • 带有完整的 Java SE 运行时,包括 Swing/AWT。 支持音频、打印和任何其他 Java SE 组件。 运行时支持 WebAssembly 以获得最佳性能。
  • 生成的 JavaScript 代码经过高度优化、可进行高效垃圾回收。
  • 支持双向 Java-JavaScript 互操作性。 可以从 Java 调用和操作 JavaScript 库以及 DOM。 可以从 JavaScript 调用转换后的 Java 模块。
  • 支持 Java 多线程,允许使用 Web Workers 创建并发应用程序。

2.GWT

GWT 是一个开发工具包,用于构建和优化复杂的基于浏览器的应用程序。 它的目标是实现高性能 Web 应用程序的高效开发,而无需开发人员成为浏览器怪癖、XMLHttpRequest 和 JavaScript 方面的专家。 GWT开源并且完全免费,目前被全世界成千上万的开发者使用。

GWT 是一个开发工具包,用来构建大规模和高性能 Web 应用程序。GWT 用 JAVA 编写客户端应用程序, 然后将 JAVA 代码编译成 JS 代码。能够支持大部分的浏览器和操作系统,GWT是Google在前端工程化上的重要尝试。

GWT强调可重用的常见Web开发任务方法,即异步远程过程调用,历史管理,书签,UI抽象,国际化和跨浏览器可移植性。

GWT应用程序可以以两种模式运行:

  • 开发模式:应用程序在Java虚拟机(JVM)中作为Java字节码运行。此模式通常用于开发,支持代码的热交换和调试。在2014年,开发人员模式的经典实现因浏览器更新而无法使用,直到用更兼容的超级开发模式取代,后者成为GWT 2.7中的默认模式。
  • 生产模式:应用程序作为纯Java和HTML运行,从Java源代码编译。此模式通常用于部署。

3.TeaVM

3.1 什么是TeaVM

TeaVM 是 Java 字节码的预编译器,编译产物为在浏览器中运行的 JavaScript 和 WebAssembly。 它的近亲是众所周知的 GWT,GWT和TeaVM的主要区别是 TeaVM 不需要源代码,只需要编译的类文件。 而且不要求源代码是Java,所以TeaVM已经成功编译了Kotlin和Scala等其他语言。

TeaVM具有以下明显特征:

  • 易于使用从 Maven 原型创建一个新项目或应用 Gradle 插件就可以愉快地开发,而无需使用 npm、Webpack、UglifyJS、Babel 等进行复杂的设置。
  • 高效:TeaVM 非常高效,编译时时间很快。此外,TeaVM 为快速启动的 Web 应用程序生成快速、小型的 JavaScript 代码,即使在移动设备上也是如此。

3.2 为什么需要TeaVM

TeaVM 主要是一个网络开发工具, 它不是为了使用 Java 或 Kotlin 现有的大型代码库来生成 JavaScript。 不幸的是,Java 并不是为在浏览器中高效运行而设计的。 如果不生成低效的 JavaScript,有些 Java API 是无法实现的。 比如一些 API :反射、资源、类加载器和 JNI。 TeaVM 限制这些 API 的使用。 通常,开发者必须手动重写代码以适应 TeaVM 约束。

TeaVM 适合以下开发者:

  • 一名 Java 开发人员,从头开始编写 Web 前端。
  • 已经拥有基于 Java 的后端,并希望将前端代码紧密集成到现有的开发基础架构中。
  • 您有一些要在前端重用的 Java 后端代码。
  • 您已准备好重写代码以使用 TeaVM。

如果您有使用 Swing 的紧耦合应用程序,希望在 Web 中运行这些应用程序,并且不关心下载大小、启动时间和性能,此时可以考虑使用 CheerpJ而不是TeaVM。

4.Jsweet

JSweet通过使用JavaScript库和框架,利用TypeScript在Java中编写丰富且响应迅速的Web应用程序。使用JSweet,可以将Java程序被转换成TypeScript和JavaScript。

比如官网的描述:

JSweet:A transpiler to write JavaScript programs in Java

JSweet具有以下明显特点:

  • JSweet快速、轻量:生成的代码是常规JavaScript代码,可以直接与现有JavaScript程序和库进行交互操作。
  • 安全可靠:JSweet为web应用程序提供类型检测,并生成完整的类型检测程序。它基于Oracle的Java编译器(javac)和Microsoft's TypeScript(tsc)。同时JSweet允许开发者自由选择JS库。
  • 代码共享:JSweet支持服务端Java和客户端JavaScript代码共享。

比如下面的Java程序:

package org.jsweet;

import static jsweet.dom.Globals.*;

/**
* This is a very simple example that just shows an alert.
*/
public class HelloWorld {
	public static void main(String[] args) {
		alert("Hi there!");
	}
}

使用JSweet会生成以下TypeScript程序:

namespace org.jsweet {
    /**
* This is a very simple example that just shows an alert.
*/
    export class HelloWorld {
        public static main(args : string[]) {
            alert("Hi there!");
        }
    }
}
org.jsweet.HelloWorld.main(null);

最终输出的JavaScript代码如下:

var org;
(function (org) {
    var jsweet;
    (function (jsweet) {
        /**
        * This is a very simple example that just shows an alert.
        */
        var HelloWorld = (function () {
            function HelloWorld() {
            }
            HelloWorld.main = function (args) {
                alert("Hi there!");
            };
            return HelloWorld;
        }());
        jsweet.HelloWorld = HelloWorld;
    })(jsweet = org.jsweet || (org.jsweet = {}));
})(org || (org = {}));
org.jsweet.HelloWorld.main(null);

5.Vaadin Flow

Vaadin Flow 使用 Java 来构建现代 Web 应用程序。 Vaadin Flow 是一个独特的全栈框架,让开发者无需编写 HTML 或 JavaScript 即可构建 Web 应用程序。Vaadin Flow具有以下明显特点。

构建 Web 应用程序的更简单方法

使用全堆栈 Java 框架 Vaadin Flow,开发者无需考虑请求、响应和其他底层Web 开发概念。与构建传统桌面应用程序非常相似,开发者可以从组件组成 UI,将其连接到数据源并对用户事件做出反应。 UI 在 JVM 上运行,无需公开 REST 服务或想出其他方法将数据移动到浏览器。

应用程序在浏览器中呈现为标准 HTML,它们适用于所有现代浏览器和设备,无需插件。

@Route("hello-world")
public class HelloWorld extends VerticalLayout {

    public HelloWorld() {
        TextField name = new TextField("Name");
        Paragraph greeting = new Paragraph("");

        Button button = new Button("Greet", event -> {
            greeting.setText("Hello " + name.getValue());
        });

        add(name, button, greeting);
    }
}

集成UI 组件

Vaadin 带有大量漂亮的 UI 组件,例如表单输入、对话框、数据网格和可视化。 开发者可以直接在 Java 代码中扩展组件和创建组合。 一切都建立在开放的网络标准之上,并可以在所有现代主流浏览器上运行。

支持实时协作

Collaboration Engine 提供的功能使您的用户能够直接在应用程序内实时协同工作。 仅需几行代码,即可显示活跃用户、实现聊天并允许多人在同一视图上工作。

自动化用户界面测试

使用 Vaadin TestBench 实现自动化 UI 测试。模拟用户测试允许开发者在用户之前发现所有主要浏览器的任何回归或兼容性问题。

可视化UI构建

使用 Vaadin Designer 更快地构建 UI。拖放功能和外部设备预览功能使开发者能够快速组装可用于 Flow 应用程序的 HTML 模板。


6.J2CL

J2CL 是一个功能强大、简单且轻量级的从 Java 到 Closure 风格的JavaScript 的转换器。

J2CL 充分利用 Java 和 JavaScript, 开发者不再需要在两者之间做出选择或锁定特定的框架或语言。J2CL具有以下明显特点:

  • 及早错误捕捉: 基于强大的 Java 类型系统的强大的运行时类型检查与高级跨语言类型检查相结合,可以及早发现您的错误。
  • 提供大量代码重用: J2CL 严格遵循 Java 语言语义,实现了跨不同平台的重用,支持将最流行的 Java 库引入工具包,包括 Guava、Dagger 和 AutoValue。
  • 现代、速度极快: 在 Bazel 的支持下,J2CL 提供了一种快速而现代的开发体验,让开发者保持高效。
  • 安全生产部署: J2CL 是谷歌开发的最先进的 GSuite 应用程序的底层技术,包括 GMail、Inbox、Docs、Slides 和 Calendar等等。

Closure Compiler :是一种使 JavaScript 下载和运行速度更快的工具。 它是一个真正的 JavaScript 编译器。 它不是从源语言编译为机器代码,而是从 JavaScript 编译为更好的 JavaScript。 它解析 JavaScript,对其进行分析,删除死代码、重写并最小化剩余的代码。 它还会检查语法、变量引用和类型,并对常见的 JavaScript 陷阱发出警告。

7.JWebAssembly

JWebAssembly 是 WebAssembly 编译器的 Java 字节码。 它使用 Java 类文件作为输入。 可以编译任何可编译为 Java 字节码的语言,如 Clojure、Groovy、JRuby、Jython、Kotlin 和 Scala。

JWebAssembly的编译输出为二进制格式(.wasm 文件)或文本格式(.wat 文件),其本质是使用 WebAssembly 在浏览器中本地运行 Java。

与类似项目的不同之处在于,不应移植具有 GC 和内存管理功能的完整 VM。 这更像是 1:1 的转换。 生成的 WebAssembly 代码在大小上与原始 Java 类文件相似。

比如下面的例子,要导出 Java 函数以使其可从 JavaScript 访问,开发者必须添加注释 de.inetsoftware.jwebassembly.api.annotation.Export。

import de.inetsoftware.jwebassembly.api.annotation.Export;
@Export
public static int add( int a, int b ) {
    return a + b;
}

8.本文总结

本文主要和大家介绍浏览器运行 Java 的5种尖端技术,包括:CheerpJ 、GWT 、TeaVM 、Jsweet 、Vaadin Flow 、J2CL 、JWebAssembly等等。同时,笔者已经成功将CheerpJ用于线上生产项目中,并完成线上部署。因为篇幅有限,文章并没有就每一个方案过多展开,如果有兴趣,可以直接在我主页继续阅读单框架介绍,但是文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!


参考资料

http://teavm.org/docs/intro/overview.html

https://blog.csdn.net/terrychinaz/article/details/117398107

https://www.gwtproject.org/doc/latest/DevGuide.html

https://github.com/cincheo/jsweet

https://vaadin.com/flow

https://github.com/google/closure-compiler

https://www.infoq.cn/article/dLh3evH5zl7bzj0N11Vh

https://github.com/i-net-software/JWebAssembly

https://github.com/google/j2cl

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...