Closed4

playwright-java をKotlinで使う

Yusuke IwakiYusuke Iwaki

playwright-javaは1.10でstableに昇格したらしいが、びっくりするくらい利用事例が少ない。
playwright-sharpもそういえばstableなんだっけ?

Yusuke IwakiYusuke Iwaki
$ brew install gradle
==> Downloading https://services.gradle.org/distributions/gradle-7.0-all.zip
==> Downloading from https://downloads.gradle-dn.com/distributions/gradle-7.0-all.zip
######################################################################## 100.0%
🍺  /usr/local/Cellar/gradle/7.0: 10,864 files, 261.0MB, built in 45 seconds
$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 4

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Kotlin) [1..2] 2
Yusuke IwakiYusuke Iwaki

KotlinはVSCodeでは満足に書けないので、IntelliJはほぼ必須。
https://www.jetbrains.com/ja-jp/idea/download/#section=mac

Playwright.create() のところ、 jvmTarget 1.8指定が必要。build.gradle.ktsに以下を追記。

tasks.withType<KotlinCompile> {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
App.kt
package com.example.playwright

import com.microsoft.playwright.Page
import com.microsoft.playwright.Playwright
import java.nio.file.Paths

fun main() {
    Playwright.create().use { playwright ->
        playwright.chromium().launch().use { browser ->
            val page = browser.newPage()
            page.navigate("https://github.com/YusukeIwaki")
            page.screenshot(Page.ScreenshotOptions().setPath(Paths.get("YusukeIwaki.png")))
        }
    }
}

じみーにBrowserやPageなどがAutoClosableを実装していたりするので、Kotlinだとuseを使える(Javaでいうところのtry-with-resources)

Yusuke IwakiYusuke Iwaki
$ ./gradlew clean run

> Task :app:run
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.Object java.util.Optional.value accessible: module java.base does not "opens java.util" to unnamed module @76e041cf
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
        at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:177)
        at java.base/java.lang.reflect.Field.setAccessible(Field.java:171)
        at com.google.gson.internal.reflect.UnsafeReflectionAccessor.makeAccessible(UnsafeReflectionAccessor.java:44)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:159)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
        at com.google.gson.Gson.getAdapter(Gson.java:458)
        at com.google.gson.Gson.fromJson(Gson.java:931)
        at com.google.gson.Gson.fromJson(Gson.java:897)
        at com.google.gson.Gson.fromJson(Gson.java:846)
        at com.google.gson.Gson.fromJson(Gson.java:817)
        at com.microsoft.playwright.impl.Utils.convertViaJson(Utils.java:37)
        at com.microsoft.playwright.impl.BrowserImpl.newPageImpl(BrowserImpl.java:186)
        at com.microsoft.playwright.impl.BrowserImpl.lambda$newPage$2(BrowserImpl.java:182)
        at com.microsoft.playwright.impl.LoggingSupport.withLogging(LoggingSupport.java:47)
        at com.microsoft.playwright.impl.BrowserImpl.newPage(BrowserImpl.java:182)
        at com.microsoft.playwright.Browser.newPage(Browser.java:562)
        at com.example.playwright.AppKt.main(App.kt:13)
        at com.example.playwright.AppKt.main(App.kt)

> Task :app:run FAILED

FAILURE: Build failed with an exception.

https://stackoverflow.com/questions/56803554/exception-in-thread-thread-0-java-lang-reflect-inaccessibleobjectexception

https://blog1.mammb.com/entry/2020/12/28/090000

これを参考にbuild.gradle.ktsを少し変更

application {
    // Define the main class for the application.
    mainClass.set("com.example.playwright.AppKt")
    applicationDefaultJvmArgs = listOf(
        "--add-opens", "java.base/java.util=ALL-UNNAMED",
        "--add-opens", "java.base/sun.nio.fs=ALL-UNNAMED",
    )
}

→ ふたたび ./gradlew run する。

$ ./gradlew clean run

BUILD SUCCESSFUL in 9s
3 actionable tasks: 3 executed

このスクラップは2021/04/21にクローズされました