Perbedaan antara Java 8 dan Java 11/17

Dengan bermigrasi ke runtime Java 11/17, Anda dapat menggunakan fitur bahasa terbaru dan membangun aplikasi yang lebih portabel dengan kode idiomatis.

Memahami opsi migrasi Anda

Untuk mengurangi upaya dan kompleksitas migrasi runtime, lingkungan standar App Engine memungkinkan Anda mengakses banyak layanan dan API paket lama di runtime Java 11/17, seperti Memcache. Aplikasi Java 11/17 Anda dapat memanggil API paket layanan melalui JAR API App Engine, dan mengakses sebagian besar fungsi yang sama seperti pada runtime Java 8.

Anda juga memiliki opsi untuk menggunakan produk Google Cloud yang menawarkan fungsi serupa dengan layanan paket lama. Produk Google Cloud ini menyediakan Library Klien Cloud untuk Java yang idiomatis. Untuk paket layanan yang tidak tersedia sebagai produk terpisah di Google Cloud, seperti pemrosesan gambar, penelusuran, dan pesan, Anda dapat menggunakan penyedia pihak ketiga atau solusi lain yang disarankan.

Untuk mempelajari lebih lanjut cara bermigrasi ke layanan yang tidak dipaketkan, lihat Bermigrasi dari layanan paket.

Ada beberapa perbedaan dalam melakukan migrasi runtime, tergantung apakah Anda memilih untuk menggunakan layanan paket lama atau tidak:

Bermigrasi ke Java 11/17 dengan paket layanan Bermigrasi ke Java 11/17 tanpa paket layanan
Akses layanan paket menggunakan JAR API App Engine. Atau, gunakan produk Google Cloud atau layanan pihak ketiga yang direkomendasikan.

Gunakan appengine-web.xml dan web.xml untuk konfigurasi aplikasi.

Anda mungkin juga perlu mengonfigurasi file YAML tambahan, tergantung pada fitur yang digunakan aplikasi Anda.

Gunakan app.yaml untuk konfigurasi aplikasi.

Anda mungkin juga perlu mengonfigurasi file YAML tambahan, tergantung pada fitur yang digunakan aplikasi Anda.

Aplikasi di-deploy melalui Jetty. Menggunakan format WAR untuk mengemas aplikasi Anda. Aplikasi di-deploy menggunakan server Anda sendiri. Gunakan format JAR untuk mengemas aplikasi Anda. Untuk mempelajari lebih lanjut cara mengonversi file WAR yang sudah ada menjadi JAR yang dapat dieksekusi, lihat Memaketkan ulang file WAR.

Ringkasan proses migrasi

Berikut beberapa perubahan yang mungkin harus Anda buat pada aplikasi Java 8 App Engine yang ada dan proses deployment untuk menggunakan runtime Java 11/17 App Engine:

Perbedaan utama antara runtime Java 8 dan Java 11/17

Berikut adalah ringkasan perbedaan antara runtime Java 8 dan Java 11/17 di lingkungan standar App Engine:

Runtime Java 8 Runtime Java 11/17
Deployment server Server di-deploy untuk Anda melalui Jetty Jika aplikasi Anda tidak menggunakan layanan paket lama, Anda harus men-deploy server sendiri.1
Layanan paket lama App Engine Tersedia Tersedia
Kemampuan menggunakan Library Klien Cloud untuk Java Ya Ya
Dukungan Ekstensi bahasa dan library sistem Ya Ya
Akses jaringan eksternal Ya Ya
Akses sistem file Akses baca/tulis ke /tmp Akses baca/tulis ke /tmp
Runtime bahasa Diubah untuk App Engine Runtime open source yang tidak dimodifikasi
Mekanisme isolasi Sandbox container berbasis gVisor Sandbox container berbasis gVisor
Menguji dengan server pengembangan lokal Didukung Didukung
Konfigurasi keamanan thread Dapat ditentukan dalam file appengine-web.xml. Tidak dapat ditentukan dalam file konfigurasi. Semua aplikasi dianggap aman untuk thread.3
Logging Menggunakan java.util.logging.
ConsoleHandler, yang menulis ke
stderr dan mengosongkan aliran data
setelah setiap pencatatan data.
Cloud Logging Standar 2

Catatan:

  1. Jika aplikasi Anda tidak menggunakan layanan paket lama, runtime Java 11/17 dapat menjalankan framework Java apa pun selama Anda mengemas server web yang dikonfigurasi untuk merespons permintaan HTTP pada port yang ditentukan oleh variabel lingkungan PORT (direkomendasikan) atau pada port 8080. Misalnya, runtime Java 11/17 dapat menjalankan Spring Boot Uber JAR sebagaimana adanya. Untuk contoh lainnya, lihat bagian Fleksibilitas framework.

    Jika aplikasi Anda menggunakan layanan paket lama, App Engine akan men-deploy-nya menggunakan Jetty dengan cara yang sama seperti pada runtime Java 8.

  2. Logging dalam runtime Java 11/17 mengikuti standar logging di Cloud Logging. Pada runtime Java 11/17, log aplikasi tidak lagi dipaketkan dengan log permintaan, tetapi dipisahkan dalam data yang berbeda. Untuk mempelajari lebih lanjut cara membaca dan menulis log di runtime Java 11/17, lihat panduan logging.

  3. Untuk mengonfigurasi aplikasi non-threadsafe di runtime Java 11/17, mirip dengan cara menetapkan <threadsafe>false</threadsafe> di Java 8, tetapkan konkurensi maksimum ke 1 di file app.yaml atau file appengine-web.xml jika menggunakan layanan paket lama.

Fleksibilitas framework

Runtime Java 11/17 tidak menyertakan framework penayangan web apa pun kecuali jika Anda menggunakan layanan paket lama. Artinya, Anda dapat menggunakan framework selain framework berbasis servlet. Jika Anda menggunakan layanan paket lama, runtime Java 11/17 akan menyediakan framework penayangan web Jetty.

Ada contoh hello world yang menggunakan framework web Java populer di repositori GitHub Google Cloud:

Memigrasikan format file XML ke YAML

gcloud CLI tidak mendukung format file berikut:

  • cron.xml
  • datastore-index.xml
  • dispatch.xml
  • queue.xml

Contoh berikut menunjukkan cara memigrasikan file xml ke file yaml.

Memigrasikan file secara otomatis

Untuk memigrasikan file xml secara otomatis:

  1. Anda harus memiliki gcloud CLI versi 226.0.0 atau yang lebih baru. Untuk mengupdate ke versi terbaru:

    gcloud components update
    
  2. Untuk setiap file yang ingin dimigrasikan, tentukan salah satu subperintah berikut (cron-xml-to-yaml, datastore-indexes-xml-to-yaml, dispatch-xml-to-yaml, queue-xml-to-yaml) dan nama file:

    gcloud beta app migrate-config queue-xml-to-yaml MY-QUEUE-XML-FILE.xml
    
  3. Periksa kembali file yang dikonversi secara manual sebelum men-deploy ke produksi.

    Untuk mengetahui contoh konversi file xml ke yaml yang berhasil, lihat tab Memigrasikan file secara manual.

Memigrasikan file secara manual

Untuk memigrasikan file xml secara manual ke file yaml:

cron.yaml

Buat file cron.yaml dengan objek cron yang berisi daftar objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <cron> dalam file cron.xml, sebagai yang ditunjukkan di bawah ini.

File cron.yaml yang dikonversi:

cron:
- url: '/recache'
  schedule: 'every 2 minutes'
  description: 'Repopulate the cache every 2 minutes'
- url: '/weeklyreport'
  schedule: 'every monday 08:30'
  target: 'version-2'
  timezone: 'America/New_York'
  description: 'Mail out a weekly report'

File cron.xml asli:

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
  <cron>
    <url>/recache</url>
    <description>Repopulate the cache every 2 minutes</description>
    <schedule>every 2 minutes</schedule>
  </cron>
  <cron>
    <url>/weeklyreport</url>
    <description>Mail out a weekly report</description>
    <schedule>every monday 08:30</schedule>
    <timezone>America/New_York</timezone>
    <target>version-2</target>
  </cron>
</cronentries>

Untuk informasi selengkapnya, lihat dokumentasi referensi cron.yaml.

dispatch.yaml

Buat file dispatch.yaml dengan objek dispatch yang berisi daftar objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <dispatch> dalam file dispatch.xml, sebagai yang ditunjukkan di bawah ini.

File dispatch.yaml yang dikonversi:

dispatch:
- url: '*/favicon.ico'
  module: default
- url: 'simple-sample.uc.r.appspot.com/'
  module: default
- url: '*/mobile/*'
  module: mobile-frontend

File dispatch.xml asli

<?xml version="1.0" encoding="UTF-8"?>
<dispatch-entries>
  <dispatch>
      <url>*/favicon.ico</url>
      <module>default</module>
  </dispatch>
  <dispatch>
      <url>simple-sample.uc.r.appspot.com/</url>
      <module>default</module>
  </dispatch>
  <dispatch>
      <url>*/mobile/*</url>
      <module>mobile-frontend</module>
  </dispatch>
</dispatch-entries>

Untuk informasi selengkapnya, lihat dokumentasi referensi dispatch.yaml

index.yaml

Buat file index.yaml dengan objek indexes yang berisi daftar objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <datastore-index> dalam file datastore-indexes.xml, sebagai yang ditunjukkan di bawah ini.

File index.yaml yang dikonversi:

indexes:
- ancestor: false
  kind: Employee
  properties:
  - direction: asc
    name: lastName
  - direction: desc
    name: hireDate
- ancestor: false
  kind: Project
  properties:
  - direction: asc
    name: dueDate
  - direction: desc
    name: cost

File datastore-index.xml asli:

<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
 autoGenerate="true">
   <datastore-index kind="Employee" ancestor="false">
       <property name="lastName" direction="asc" />
       <property name="hireDate" direction="desc" />
   </datastore-index>
   <datastore-index kind="Project" ancestor="false">
       <property name="dueDate" direction="asc" />
       <property name="cost" direction="desc" />
   </datastore-index>
</datastore-indexes>

Untuk informasi selengkapnya, lihat dokumentasi referensi index.yaml.

queue.yaml

Buat file queue.yaml dengan objek queue yang berisi daftar objek, masing-masing dengan kolom yang sesuai dengan setiap atribut tag <queue> dalam file queue.xml, sebagai yang ditunjukkan di bawah ini.

File queue.yaml yang dikonversi:

queue:
- name: fooqueue
  mode: push
  rate: 1/s
  retry_parameters:
    task_retry_limit: 7
    task_age_limit: 2d
- name: barqueue
  mode: push
  rate: 1/s
  retry_parameters:
    min_backoff_seconds: 10
    max_backoff_seconds: 200
    max_doublings: 0

File queue.xml asli:

<queue-entries>
  <queue>
    <name>fooqueue</name>
    <rate>1/s</rate>
    <retry-parameters>
      <task-retry-limit>7</task-retry-limit>
      <task-age-limit>2d</task-age-limit>
    </retry-parameters>
  </queue>
  <queue>
    <name>barqueue</name>
    <rate>1/s</rate>
    <retry-parameters>
      <min-backoff-seconds>10</min-backoff-seconds>
      <max-backoff-seconds>200</max-backoff-seconds>
      <max-doublings>0</max-doublings>
    </retry-parameters>
  </queue>
<queue-entries>