کامپایل کد جاوا در WebAssembly یک راه کارآمد برای اجرای آن در یک مرورگر وب است و شما عملکردی جدی را افزایش می دهید. بگذار چک کنیم.
- چرا از WebAssembly برای جاوا استفاده کنیم؟
- جاوا به Wasm: چگونه کار میکند
- کامپایل جاوا به Wasm با TeaVM
- نتیجهگیری
WebAssembly یا Wasm، یک قالب باینری بومی سبک و تعمیم یافته را برای هر زبانی که می توان روی آن کامپایل کرد، ارائه می دهد. هنگامی که زبان مبدأ به WebAssembly تبدیل می شود، آن باینری فشرده می تواند در زمینه های مختلفی اجرا شود، از ماشین های مجازی ابری و دسکتاپ گرفته تا اینترنت اشیا و دستگاه های تلفن همراه. یکی از جالب ترین محیط هایی که Wasm از آن پشتیبانی می کند، مرورگر وب است. در این مقاله، نحوه کامپایل کد جاوا را در WebAssembly بررسی می کنیم، سپس یک برنامه آزمایشی را در یک وب سرور اجرا می کنیم و آن را در عمل مشاهده می کنیم.
چرا از WebAssembly برای جاوا استفاده کنیم؟
Wasm راهی برای اجرای جاوا در قسمت جلویی مرورگر وب ارائه میکند، جایی که Java API شما را میتوان از جاوا اسکریپت فراخوانی کرد.
کامپایلرهای WebAssembly یک باینری از منبع جاوا (یا از بایت کد) تولید می کنند و آن باینری توسط مرورگر با استفاده از قابلیت های سیستم عامل میزبان اجرا می شود، بنابراین عملکرد در سطح سیستم عامل را دریافت می کنید. کد جاوا به یک باینری Wasm تبدیل میشود که قلابهایی را که از جاوا اسکریپت فراخوانی میکنید، آشکار میکند.
Wasm در تمام مرورگرهای اصلی مدرن موجود است، بنابراین می توانید هم اکنون از آن استفاده کنید. این عملکرد عالی برای کارهای سخت به زبان انتخابی شما ارائه می دهد. رمزگذاری ویدیو، گرافیک و سایر پردازش های فشرده داده کاندیدهای خوبی برای این فناوری هستند. برخی از پروژهها از Wasm برای رفع محدودیتهای عملکرد بلاکچین استفاده میکنند.
اگر مدتی در جاوا بوده اید، ممکن است وقتی در مورد جاوا در مرورگر می شنوید به اپلت های جاوا فکر کنید. مطمئن باشید واسم حیوانی کاملا متفاوت است. این یک فناوری مدرن و با کارایی بالا است که از ابتدا بهعنوان یک زمان اجرا امن با جعبه سند طراحی شده است. با قابلیت حمل، عملکرد، امنیت و پشتیبانی چند زبانه، Wasm یک قطعه حیاتی از چشم انداز فناوری امروز است.
جاوا به Wasm: چگونه کار می کند
تبدیل یک برنامه جاوا به WebAssembly کمی مشکل است. یک مسیر طلایی کاملا قابل قبول وجود ندارد که بتوانم آن را توصیه کنم. پروژه های متعددی وجود دارد، اما آنها بالغ یا مستند نیستند. جاوا به عنوان یک زبان چند مشکل دشوار را برای یک Transpiler WebAssembly ارائه می دهد، مانند جمع آوری زباله و بازتاب. به نظر می رسد اینها منشأ تأخیر در دستیابی به راه حل درجه یک Java Wasm باشند.
GraalVM در حال حاضر در حال ایجاد پشتیبانی برای خروجی به Wasm با ابزار native-image ( به عنوان یک باینری هدف در پرچم --features
). اگر پیشنهاد موفقیت آمیز باشد، احتمالاً به مسیر توصیه شده تبدیل خواهد شد. GraalVM قبلاً ظرفیت اجرای Wasm را دارد و به طور کلی یک پروژه عالی است. هنگامی که GraalVM بتواند باینری Wasm تولید کند، ارزش کاوش را دارد.
در این میان، تعداد انگشت شماری کتابخانه برای مدیریت کامپایل Java-to-Wasm وجود دارد:
ما از TeaVM برای کامپایل Java Wasm خود استفاده خواهیم کرد. از خالق TeaVM، الکسی آندریف پرسیدم که چرا جاوا در پیادهسازی Wasm از سایر زبانها عقب است. او به من گفت: «به طور خلاصه: نوشتن GC یا مدیریت استثنایی خود کار سختی نیست. پیاده سازی GC خود در Wasm به دلیل عدم دسترسی به پشته دشوار است. WebAssembly به دلایل امنیتی دسترسی به پشته محدود دارد. همانطور که آندریف پیشنهاد کرده است، به جای جستجوی راههایی برای دسترسی ایمن به پشته، Wasm تصمیم گرفته است که مجموعه زباله را در خود Wasm بسازد. (برای پیگیری روند جمع آوری زباله در Wasm به صفحه پروژه WebAssembly در GitHub مراجعه کنید.)
کامپایل جاوا به Wasm با TeaVM
TeaVM یک کتابخانه سبک وزن برای ایجاد Wasm از جاوا است. این ابزار از Google Web Toolkit الهام می گیرد اما به جای منبع، از بایت کد ساخته می شود. به همین دلیل، می تواند سایر زبان های JVM مانند Scala را مدیریت کند. TeaVM به ما یک راه سریع برای نگاه کردن به پروژه جاوا Wasm با یکی از پروژههای نمونه خود میدهد که برای نمایش از آن استفاده خواهیم کرد.
راه اندازی TeaVM و پروژه نمونه
برای استفاده از TeaVM به JDK جاوا ۸ یا بالاتر نیاز دارید. ما میخواهیم آخرین نسخه TeaVM را بسازیم و آن را در مخزن محلی خود نصب کنیم، سپس یکی از پروژههای نمونه را بسازیم که از Wasm استفاده میکند تا ببینیم چگونه کامپایل Java-to-Wasm را در تبدیل مرورگر انجام میدهد.
برای شبیه سازی پروژه TeaVM به Git نصب شده نیاز دارید: Git clone https://github.com/ konsoletyper/teavm.git. در زمان نگارش، TeaVM روی ۰.۸.۰-SNAPSHOT
است.
پس از بررسی پروژه، باید خود کتابخانه TeaVM را بسازید و آن را در مخزن محلی خود نصب کنید. به دایرکتوری ریشه بروید و تایپ کنید: /teavm/gradlew
. برای ساخت TeaVM و نصب محلی آن از بستهبندی مستقل Gradle استفاده میکند.
پس از انجام این کار، میتوانید به فهرست /teavm/samples/pi
بروید و تایپ کنید: ../../gradlew war
. این به Gradle میگوید که پروژه نمونه Pi را در یک فایل WAR بسازد. پس از تکمیل، یک فایل /teavm/samples/pi/build/libs/pi.war
وجود خواهد داشت که میتوانیم آن را در یک کانتینر servlet مستقر کنیم.
در مورد من، من اوبونتو را برای این نسخه نمایشی اجرا می کنم، بنابراین Tomcat را به عنوان یک سرویس نصب کردم (sudo apt-get install tomcat9
) و سپس را کپی کردم. فایل code>pi.war در فهرست /webapps
(sudo cp /teavm-wasm/target/pi.war /var/lib/tomcat9/webapps/
). بعد، من از sudo systemctl start tomcat9
برای راه اندازی Tomcat استفاده کردم. راه دیگر استفاده از اسکریپت start.sh/.bat
در فهرست /bin
است که در صورتی که نسخه مستقل Tomcat را دانلود کرده باشید، کار می کند.
توجه داشته باشید که نمونه Pi هر دو قابلیت جاوا اسکریپت و خروجی Wasm TeaVM را نشان می دهد. ما به Wasm پایبند خواهیم بود.
دمو Pi برای Wasm
این برنامه اکنون باید در localhost:8080/pi
اجرا شود. اگر از آن URL در مرورگر بازدید کنید، یک رابط کاربری ساده با دو پیوند، یکی برای جاوا اسکریپت و دیگری برای WebAssembly خواهید دید. روی WebAssembly کلیک کنید و نمایی مانند تصویر زیر را مشاهده خواهید کرد.
شکل ۱. رابط WebAssembly Pi
این رابط به شما امکان میدهد تعداد ارقام را برای محاسبه پی تعیین کنید. از جاوای استفاده می کند که در Wasm کامپایل شده است و کد را از جاوا اسکریپت فراخوانی می کند. بیایید ببینیم این محاسبه چگونه انجام می شود.
اگر به پروژه /teavm/samples/pi
نگاه کنید، این یک طرح بندی استاندارد Maven/Gradle است که هم منابع جاوا و هم منابع برنامه وب را شامل می شود. اینها به ترتیب در src/main/java
و src/main/webapp
ذخیره میشوند. به تک کلاس جاوا در src/main/java/org/teavm/samples/pi/PiCalculator.java
نگاه کنید و خواهید دید که یک کلاس جاوا معمولی به نام PiCalculator کد>. کلاس یک متد اصلی را تعریف می کند که یک آرگومان واحد را از
args[]
به عنوان تعداد ارقام برای محاسبه می گیرد. از یک کلاس داخلی به نام PiDigitSpigot
برای انجام کرانچ واقعی pi استفاده می کند و بر یک کتابخانه جاوا تکیه دارد، java.math.BigInteger
. به طور کلی، این یک برنامه جاوا با تنوع باغ است. در واقع، اگر به /teavm/samples/pi/build/libs/classes/main
بروید و java org/teavm/samples/pi/PiCalculator 50
را تایپ کنید، با خوشحالی پی را تا ۵۰ رقم برای شما در خط فرمان محاسبه می کند.
اکنون اجازه دهید به جنبه برنامه کاربردی وب در teavm/samples/pi/src/main/webapp
نگاه کنیم. wasm.html
موردی است که ما به آن علاقه مندیم. بیشتر فایل HTML اولیه است، اما جاوا اسکریپت جالبی وجود دارد که در فهرست ۱ نشان داده شده است.
<script type="application/javascript">
let runner = null;
function init() {
TeaVM.wasm.load("wasm/pi.wasm", {
installImports(o, controller) {
function putwchars(address, count) {
let instance = controller.instance;
let memory = new Int8Array(instance.exports.memory.buffer);
let string = "";
for (let i = 0; i < count; ++i) {
string += $rt_putStdoutCustom(memory[address++]);
}
}
o.teavm.putwcharsOut = putwchars;
o.teavm.putwcharsErr = putwchars;
},
}).then(teavm => {
this.instance = teavm.instance;
runner = n => teavm.main([n.toString()]);
document.getElementById("run").disabled = false;
})
}
function calculate() {
var count = parseInt(document.getElementById("digit-count").value);
runner(count);
}
init();
</script>
</head>
</body>
<div>
Digit count:
<input type="text" id="digit-count" value="1000">
<button onclick="calculate()" id="run" disabled>Run</button>
</div>
<div id="stdout"></div>
</body>
برای شروع، خط TeaVM.wasm.load("wasm/pi.wasm", { ...
وارد کردن فایل pi.wasm
را آغاز می کند. از سرور. این یک بستهبندی برای WebAssembly.instantiate( ) که به مرورگر میگوید یک فایل Wasm را بارگیری کند. شئ ارسال شده به عنوان پارامتر دوم روش بارگذاری پیکربندی میشود، و فراخوانی .then()
یک تابع پاسخ به تماس را برای رسیدگی به اتفاقات ارائه میدهد. پس از آماده شدن برنامه WebAssembly.
هنوز هیچ سندی برای TeaVM.wasm.load
در دسترس نیست، اما میتوانید کد منبع را در GitHub پیدا کنید.
چیزی که ما بیشتر به آن علاقه مندیم تابع callback است، جایی که خط را می بینیم: runner = n => teavm.main([n.toString()]);
. اینجاست که ما تابع main()
جاوا خود را در جاوا اسکریپت فراخوانی می کنیم و تعداد ارقام را برای محاسبه به عنوان آرگومان ارسال می کنیم.
اکنون بیایید ببینیم که چگونه فایل PiCalculator.java
به pi.wasm
تبدیل شد. در فایل /pi/build.gradle.kts
، افزونه TeaVM طوری پیکربندی شده است که به فایل جاوا اشاره کند، همانطور که در فهرست ۲ نشان داده شده است.
teavm {
js {
addedToWebApp.set(true)
}
wasm {
addedToWebApp.set(true)
}
wasi {
outputDir.set(File(buildDir, "libs/wasi"))
relativePathInOutputDir.set("")
}
all {
mainClass.set("org.teavm.samples.pi.PiCalculator")
}
}
میتوانید ببینید که پلاگین TeaVM با mainClass.set("org.teavm.samples.pi.PiCalculator")
، در قسمت all
پیکربندی شده است زیرا اعمال میشود. به هر دو جاوا اسکریپت و Wasm (یعنی پروژه هر دو نسخه جاوا اسکریپت و Wasm را خروجی می دهد). اگر به build/generated/teavm/wasm/
نگاه کنید، میتوانید ببینید TeaVM فایلهای Wasm را کجا انداخته است.
نتیجه گیری
Wasm یک فناوری امیدوارکننده است که جاوا را قادر میسازد در مرورگر وب با عملکرد خوب اجرا شود. در حالی که هنوز کار در حال انجام است، کتابخانه هایی مانند TeaVM ابزار ساده ای برای کار با جاوا و WebAssembly به ما می دهند. TeaVM به ما امکان می دهد کد جاوا را در یک باینری فشرده که با استفاده از قابلیت های سیستم عامل میزبان در مرورگر اجرا می شود، کامپایل کنیم. Wasm بخش مهمی از چشم انداز فناوری جاوا است و هنوز در مراحل اولیه توسعه است. یکپارچه سازی جمع آوری زباله می تواند پتانسیل خود را در چندین زمینه کلیدی گسترش دهد. این قطعا یکی از مواردی است که باید تماشا کنید.
پست های مرتبط
کار با جاوا و Wasm
کار با جاوا و Wasm
کار با جاوا و Wasm