This is an automated email from the ASF dual-hosted git repository.

jtulach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans-html4j.git


The following commit(s) were added to refs/heads/master by this push:
     new 13758bb2 Enabling CI testing on JDK 25 (#57)
13758bb2 is described below

commit 13758bb2bd352935b5eda5a39c00e460072caf89
Author: Jaroslav Tulach <[email protected]>
AuthorDate: Sat May 16 07:42:20 2026 +0200

    Enabling CI testing on JDK 25 (#57)
---
 .github/workflows/linux.yml                        |   3 +-
 .github/workflows/mac.yml                          |   3 +-
 .github/workflows/windows.yml                      |   3 +-
 boot-agent-test/pom.xml                            |  10 +-
 boot-script/pom.xml                                |  10 +-
 boot/pom.xml                                       |  10 +-
 .../java/org/netbeans/html/boot/impl/Compile.java  | 273 ---------------------
 .../html/boot/impl/JavaScriptCompletionTest.java   |   1 +
 .../html/boot/impl/JavaScriptProcesorTest.java     |   1 +
 generic/pom.xml                                    |  10 +-
 geo/pom.xml                                        |   6 +
 .../java/org/netbeans/html/geo/impl/Compile.java   | 262 --------------------
 .../netbeans/html/geo/impl/GeoProcessorTest.java   |   1 +
 json/pom.xml                                       |  10 +-
 .../test/java/net/java/html/json/MapModelTest.java |  12 +-
 .../net/java/html/json/ModelProcessorTest.java     |   1 +
 pom.xml                                            |  18 +-
 sound/pom.xml                                      |  10 +-
 testing/pom.xml                                    | 101 ++++++++
 .../java/org/netbeans/html/testing}/Compile.java   | 103 ++++++--
 20 files changed, 221 insertions(+), 627 deletions(-)

diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 5267b1a8..f015a2b7 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -30,8 +30,9 @@ jobs:
 
     runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
-        java: [ '8', '11', '17', '21' ]
+        java: [ '8', '11', '17', '21', '25' ]
         os: [ ubuntu-22.04 ]
 
     steps:
diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml
index ceec8544..93d46476 100644
--- a/.github/workflows/mac.yml
+++ b/.github/workflows/mac.yml
@@ -30,8 +30,9 @@ jobs:
 
     runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
-        java: [ '11', '17' ] 
+        java: [ '11', '17' ]
         os: [ macos-14 ]
 
     steps:
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index c244fed5..dd5ac688 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -30,8 +30,9 @@ jobs:
 
     runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
-        java: [ '8', '11', '17', '21' ]
+        java: [ '8', '11', '17', '21', '25' ]
         os: [ windows-2022 ]
 
     steps:
diff --git a/boot-agent-test/pom.xml b/boot-agent-test/pom.xml
index 188742a3..5b29cf5f 100644
--- a/boot-agent-test/pom.xml
+++ b/boot-agent-test/pom.xml
@@ -94,12 +94,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-          <groupId>org.graalvm.js</groupId>
-          <artifactId>js</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>org.graalvm.js</groupId>
-          <artifactId>js-scriptengine</artifactId>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>testing</artifactId>
+          <version>${project.version}</version>
+          <scope>test</scope>
         </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/boot-script/pom.xml b/boot-script/pom.xml
index a630aa73..5a73f5a8 100644
--- a/boot-script/pom.xml
+++ b/boot-script/pom.xml
@@ -129,12 +129,10 @@
             <type>jar</type>
         </dependency>
         <dependency>
-          <groupId>org.graalvm.js</groupId>
-          <artifactId>js</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>org.graalvm.js</groupId>
-          <artifactId>js-scriptengine</artifactId>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>testing</artifactId>
+          <version>${project.version}</version>
+          <scope>test</scope>
         </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/boot/pom.xml b/boot/pom.xml
index 6ef37757..a9a32da3 100644
--- a/boot/pom.xml
+++ b/boot/pom.xml
@@ -111,12 +111,10 @@
       <type>jar</type>
     </dependency>
     <dependency>
-        <groupId>org.graalvm.js</groupId>
-        <artifactId>js</artifactId>
-    </dependency>
-    <dependency>
-        <groupId>org.graalvm.js</groupId>
-        <artifactId>js-scriptengine</artifactId>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>testing</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
     </dependency>
   </dependencies>
     <description>Builder to launch your Java/HTML based 
application.</description>
diff --git a/boot/src/test/java/org/netbeans/html/boot/impl/Compile.java 
b/boot/src/test/java/org/netbeans/html/boot/impl/Compile.java
deleted file mode 100644
index a5584793..00000000
--- a/boot/src/test/java/org/netbeans/html/boot/impl/Compile.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.netbeans.html.boot.impl;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticListener;
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
-import javax.tools.ToolProvider;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-/**
- *
- * @author Jaroslav Tulach
- */
-final class Compile implements DiagnosticListener<JavaFileObject> {
-    private final List<Diagnostic<? extends JavaFileObject>> errors = new 
ArrayList<>();
-    private final Map<String, byte[]> classes;
-    private final String pkg;
-    private final String cls;
-    private final String html;
-    private final String sourceLevel;
-
-    private Compile(String html, String code, String sl) throws IOException {
-        this.pkg = findPkg(code);
-        this.cls = findCls(code);
-        this.html = html;
-        this.sourceLevel = sl;
-        classes = compile(html, code);
-    }
-
-    /** Performs compilation of given HTML page and associated Java code
-     */
-    public static Compile create(String html, String code) throws IOException {
-        return create(html, code, "8");
-    }
-    static Compile create(String html, String code, String sourceLevel) throws 
IOException {
-        return new Compile(html, code, sourceLevel);
-    }
-    
-    /** Checks for given class among compiled resources */
-    public byte[] get(String res) {
-        return classes.get(res);
-    }
-    
-    /** Obtains errors created during compilation.
-     */
-    public List<Diagnostic<? extends JavaFileObject>> getErrors() {
-        return getDiagnostics(Diagnostic.Kind.ERROR);
-    }
-    public List<Diagnostic<? extends JavaFileObject>> 
getDiagnostics(Diagnostic.Kind kind) {
-        List<Diagnostic<? extends JavaFileObject>> err = new ArrayList<>();
-        for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
-            if (diagnostic.getKind() == kind) {
-                err.add(diagnostic);
-            }
-        }
-        return err;
-    }
-    
-    private Map<String, byte[]> compile(final String html, final String code) 
throws IOException {
-        StandardJavaFileManager sjfm = 
ToolProvider.getSystemJavaCompiler().getStandardFileManager(this, null, null);
-
-        final Map<String, ByteArrayOutputStream> class2BAOS = new HashMap<>();
-
-        JavaFileObject file = new 
SimpleJavaFileObject(URI.create("mem://mem"), Kind.SOURCE) {
-            @Override
-            public CharSequence getCharContent(boolean ignoreEncodingErrors) 
throws IOException {
-                return code;
-            }
-        };
-        final JavaFileObject htmlFile = new 
SimpleJavaFileObject(URI.create("mem://mem2"), Kind.OTHER) {
-            @Override
-            public CharSequence getCharContent(boolean ignoreEncodingErrors) 
throws IOException {
-                return html;
-            }
-
-            @Override
-            public InputStream openInputStream() throws IOException {
-                return new ByteArrayInputStream(html.getBytes());
-            }
-        };
-        
-        JavaFileManager jfm = new 
ForwardingJavaFileManager<JavaFileManager>(sjfm) {
-            @Override
-            public FileObject getFileForOutput(JavaFileManager.Location 
location, String packageName, String relativeName, FileObject sibling) throws 
IOException {
-                try {
-                    return new VirtFO(new URI("mem://resource/" + 
relativeName), Kind.OTHER, relativeName);
-                } catch (URISyntaxException ex) {
-                    throw new IllegalStateException(ex);
-                }
-            }
-            
-            
-            @Override
-            public JavaFileObject getJavaFileForOutput(Location location, 
String className, Kind kind, FileObject sibling) throws IOException {
-                if (kind  == Kind.CLASS) {
-                    final ByteArrayOutputStream buffer = new 
ByteArrayOutputStream();
-
-                    class2BAOS.put(className.replace('.', '/') + ".class", 
buffer);
-                    return new SimpleJavaFileObject(sibling.toUri(), kind) {
-                        @Override
-                        public OutputStream openOutputStream() throws 
IOException {
-                            return buffer;
-                        }
-                    };
-                }
-                
-                if (kind == Kind.SOURCE) {
-                    final String n = className.replace('.', '/') + ".java";
-                    final URI un;
-                    try {
-                        un = new URI("mem://" + n);
-                    } catch (URISyntaxException ex) {
-                        throw new IOException(ex);
-                    }
-                    return new VirtFO(un/*sibling.toUri()*/, kind, n);
-                }
-                
-                throw new IllegalStateException();
-            }
-
-            @Override
-            public FileObject getFileForInput(Location location, String 
packageName, String relativeName) throws IOException {
-                if (location == StandardLocation.SOURCE_PATH) {
-                    if (packageName.equals(pkg)) {
-                        return htmlFile;
-                    }
-                    if (packageName.isEmpty() && 
relativeName.startsWith(pkg.replace('.', '/'))) {
-                        return htmlFile;
-                    }
-                }
-                
-                return null;
-            }
-
-            @Override
-            public boolean isSameFile(FileObject a, FileObject b) {
-                if (a instanceof VirtFO && b instanceof VirtFO) {
-                    return ((VirtFO)a).getName().equals(((VirtFO)b).getName());
-                }
-                
-                return super.isSameFile(a, b);
-            }
-
-            class VirtFO extends SimpleJavaFileObject {
-
-                private final String n;
-
-                public VirtFO(URI uri, Kind kind, String n) {
-                    super(uri, kind);
-                    this.n = n;
-                }
-                private final ByteArrayOutputStream data = new 
ByteArrayOutputStream();
-
-                @Override
-                public OutputStream openOutputStream() throws IOException {
-                    return data;
-                }
-
-                @Override
-                public String getName() {
-                    return n;
-                }
-
-                @Override
-                public CharSequence getCharContent(boolean 
ignoreEncodingErrors) throws IOException {
-                    data.close();
-                    return new String(data.toByteArray());
-                }
-            }
-        };
-
-        ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, 
/*XXX:*/Arrays.asList("-source", sourceLevel, "-target", sourceLevel), null, 
Arrays.asList(file)).call();
-
-        Map<String, byte[]> result = new HashMap<>();
-
-        for (Map.Entry<String, ByteArrayOutputStream> e : 
class2BAOS.entrySet()) {
-            result.put(e.getKey(), e.getValue().toByteArray());
-        }
-
-        return result;
-    }
-
-
-    @Override
-    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
-        errors.add(diagnostic);
-    }
-    private static String findPkg(String java) throws IOException {
-        Pattern p = 
Pattern.compile("package\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}*;",
 Pattern.MULTILINE);
-        Matcher m = p.matcher(java);
-        if (!m.find()) {
-            throw new IOException("Can't find package declaration in the java 
file");
-        }
-        String pkg = m.group(1);
-        return pkg;
-    }
-    private static String findCls(String java) throws IOException {
-        Pattern p = 
Pattern.compile("class\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}",
 Pattern.MULTILINE);
-        Matcher m = p.matcher(java);
-        if (!m.find()) {
-            throw new IOException("Can't find package declaration in the java 
file");
-        }
-        String cls = m.group(1);
-        return cls;
-    }
-
-    String getHtml() {
-        String fqn = "'" + pkg + '.' + cls + "'";
-        return html.replace("'${fqn}'", fqn);
-    }
-    void assertErrors() {
-        assertFalse(getErrors().isEmpty(), "There are supposed to be some 
errors");
-    }
-
-    void assertError(String expMsg) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Can't find ").append(expMsg).append(" among:");
-        for (Diagnostic<? extends JavaFileObject> e : errors) {
-            String msg = e.getMessage(Locale.US);
-            if (msg.contains(expMsg)) {
-                return;
-            }
-            sb.append("\n");
-            sb.append(msg);
-        }
-        fail(sb.toString());
-    }
-
-    void assertNoErrors() {
-        assertTrue(getErrors().isEmpty(), "No errors expected: " + 
getErrors());
-    }
-}
diff --git 
a/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptCompletionTest.java 
b/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptCompletionTest.java
index b38ae837..aeb2f2ae 100644
--- 
a/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptCompletionTest.java
+++ 
b/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptCompletionTest.java
@@ -30,6 +30,7 @@ import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import net.java.html.js.JavaScriptBody;
+import org.netbeans.html.testing.Compile;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotEquals;
 import static org.testng.Assert.assertTrue;
diff --git 
a/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java 
b/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java
index 632fcdee..e0f95de9 100644
--- a/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java
+++ b/boot/src/test/java/org/netbeans/html/boot/impl/JavaScriptProcesorTest.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Locale;
 import javax.tools.Diagnostic;
 import javax.tools.JavaFileObject;
+import org.netbeans.html.testing.Compile;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
diff --git a/generic/pom.xml b/generic/pom.xml
index e481335b..504952b4 100644
--- a/generic/pom.xml
+++ b/generic/pom.xml
@@ -70,12 +70,10 @@
             <artifactId>strings</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.graalvm.js</groupId>
-            <artifactId>js</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.graalvm.js</groupId>
-            <artifactId>js-scriptengine</artifactId>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>testing</artifactId>
+          <version>${project.version}</version>
+          <scope>test</scope>
         </dependency>
     </dependencies>
     <build>
diff --git a/geo/pom.xml b/geo/pom.xml
index 2acd1cc4..b4790d7a 100644
--- a/geo/pom.xml
+++ b/geo/pom.xml
@@ -71,6 +71,12 @@
           </exclusion>
       </exclusions>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>testing</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
     <description>Find out where your Java program running in an HTML page 
is!</description>
 </project>
diff --git a/geo/src/test/java/org/netbeans/html/geo/impl/Compile.java 
b/geo/src/test/java/org/netbeans/html/geo/impl/Compile.java
deleted file mode 100644
index 6f207a5c..00000000
--- a/geo/src/test/java/org/netbeans/html/geo/impl/Compile.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.netbeans.html.geo.impl;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticListener;
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
-import javax.tools.ToolProvider;
-import static org.testng.Assert.*;
-
-/**
- *
- * @author Jaroslav Tulach
- */
-final class Compile implements DiagnosticListener<JavaFileObject> {
-    private final List<Diagnostic<? extends JavaFileObject>> errors = 
-            new ArrayList<Diagnostic<? extends JavaFileObject>>();
-    private final Map<String, byte[]> classes;
-    private final String pkg;
-    private final String cls;
-    private final String html;
-    private final String sourceLevel;
-
-    private Compile(String html, String code, String sl) throws IOException {
-        this.pkg = findPkg(code);
-        this.cls = findCls(code);
-        this.html = html;
-        this.sourceLevel = sl;
-        classes = compile(html, code);
-    }
-
-    /** Performs compilation of given HTML page and associated Java code
-     */
-    public static Compile create(String html, String code) throws IOException {
-        return create(html, code, "8");
-    }
-    static Compile create(String html, String code, String sourceLevel) throws 
IOException {
-        return new Compile(html, code, sourceLevel);
-    }
-    
-    /** Checks for given class among compiled resources */
-    public byte[] get(String res) {
-        return classes.get(res);
-    }
-    
-    /** Obtains errors created during compilation.
-     */
-    public List<Diagnostic<? extends JavaFileObject>> getErrors() {
-        List<Diagnostic<? extends JavaFileObject>> err;
-        err = new ArrayList<Diagnostic<? extends JavaFileObject>>();
-        for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
-            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
-                err.add(diagnostic);
-            }
-        }
-        return err;
-    }
-    
-    private Map<String, byte[]> compile(final String html, final String code) 
throws IOException {
-        StandardJavaFileManager sjfm = 
ToolProvider.getSystemJavaCompiler().getStandardFileManager(this, null, null);
-
-        final Map<String, ByteArrayOutputStream> class2BAOS;
-        class2BAOS = new HashMap<String, ByteArrayOutputStream>();
-
-        JavaFileObject file = new 
SimpleJavaFileObject(URI.create("mem://mem"), Kind.SOURCE) {
-            @Override
-            public CharSequence getCharContent(boolean ignoreEncodingErrors) 
throws IOException {
-                return code;
-            }
-        };
-        final JavaFileObject htmlFile = new 
SimpleJavaFileObject(URI.create("mem://mem2"), Kind.OTHER) {
-            @Override
-            public CharSequence getCharContent(boolean ignoreEncodingErrors) 
throws IOException {
-                return html;
-            }
-
-            @Override
-            public InputStream openInputStream() throws IOException {
-                return new ByteArrayInputStream(html.getBytes());
-            }
-        };
-        
-        final URI scratch;
-        try {
-            scratch = new URI("mem://mem3");
-        } catch (URISyntaxException ex) {
-            throw new IOException(ex);
-        }
-        
-        JavaFileManager jfm = new 
ForwardingJavaFileManager<JavaFileManager>(sjfm) {
-            @Override
-            public JavaFileObject getJavaFileForOutput(Location location, 
String className, Kind kind, FileObject sibling) throws IOException {
-                if (kind  == Kind.CLASS) {
-                    final ByteArrayOutputStream buffer = new 
ByteArrayOutputStream();
-
-                    class2BAOS.put(className.replace('.', '/') + ".class", 
buffer);
-                    return new SimpleJavaFileObject(sibling.toUri(), kind) {
-                        @Override
-                        public OutputStream openOutputStream() throws 
IOException {
-                            return buffer;
-                        }
-                    };
-                }
-                
-                if (kind == Kind.SOURCE) {
-                    final String n = className.replace('.', '/') + ".java";
-                    final URI un;
-                    try {
-                        un = new URI("mem://" + n);
-                    } catch (URISyntaxException ex) {
-                        throw new IOException(ex);
-                    }
-                    return new VirtFO(un/*sibling.toUri()*/, kind, n);
-                }
-                
-                throw new IllegalStateException();
-            }
-
-            @Override
-            public FileObject getFileForInput(Location location, String 
packageName, String relativeName) throws IOException {
-                if (location == StandardLocation.SOURCE_PATH) {
-                    if (packageName.equals(pkg)) {
-                        return htmlFile;
-                    }
-                }
-                
-                return null;
-            }
-
-            @Override
-            public boolean isSameFile(FileObject a, FileObject b) {
-                if (a instanceof VirtFO && b instanceof VirtFO) {
-                    return ((VirtFO)a).getName().equals(((VirtFO)b).getName());
-                }
-                
-                return super.isSameFile(a, b);
-            }
-
-            class VirtFO extends SimpleJavaFileObject {
-
-                private final String n;
-
-                public VirtFO(URI uri, Kind kind, String n) {
-                    super(uri, kind);
-                    this.n = n;
-                }
-                private final ByteArrayOutputStream data = new 
ByteArrayOutputStream();
-
-                @Override
-                public OutputStream openOutputStream() throws IOException {
-                    return data;
-                }
-
-                @Override
-                public String getName() {
-                    return n;
-                }
-
-                @Override
-                public CharSequence getCharContent(boolean 
ignoreEncodingErrors) throws IOException {
-                    data.close();
-                    return new String(data.toByteArray());
-                }
-            }
-        };
-
-        ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, 
/*XXX:*/Arrays.asList("-source", sourceLevel, "-target", sourceLevel), null, 
Arrays.asList(file)).call();
-
-        Map<String, byte[]> result = new HashMap<String, byte[]>();
-
-        for (Map.Entry<String, ByteArrayOutputStream> e : 
class2BAOS.entrySet()) {
-            result.put(e.getKey(), e.getValue().toByteArray());
-        }
-
-        return result;
-    }
-
-
-    @Override
-    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
-        errors.add(diagnostic);
-    }
-    private static String findPkg(String java) throws IOException {
-        Pattern p = 
Pattern.compile("package\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}*;",
 Pattern.MULTILINE);
-        Matcher m = p.matcher(java);
-        if (!m.find()) {
-            throw new IOException("Can't find package declaration in the java 
file");
-        }
-        String pkg = m.group(1);
-        return pkg;
-    }
-    private static String findCls(String java) throws IOException {
-        Pattern p = 
Pattern.compile("class\\p{javaWhitespace}*([\\p{Alnum}\\.]+)\\p{javaWhitespace}",
 Pattern.MULTILINE);
-        Matcher m = p.matcher(java);
-        if (!m.find()) {
-            throw new IOException("Can't find package declaration in the java 
file");
-        }
-        String cls = m.group(1);
-        return cls;
-    }
-
-    String getHtml() {
-        String fqn = "'" + pkg + '.' + cls + "'";
-        return html.replace("'${fqn}'", fqn);
-    }
-
-    void assertErrors() {
-        assertFalse(getErrors().isEmpty(), "There are supposed to be some 
errors");
-    }
-
-    void assertError(String expMsg) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Can't find ").append(expMsg).append(" among:");
-        for (Diagnostic<? extends JavaFileObject> e : errors) {
-            String msg = e.getMessage(Locale.US);
-            if (msg.contains(expMsg)) {
-                return;
-            }
-            sb.append("\n");
-            sb.append(msg);
-        }
-        fail(sb.toString());
-    }
-}
diff --git a/geo/src/test/java/org/netbeans/html/geo/impl/GeoProcessorTest.java 
b/geo/src/test/java/org/netbeans/html/geo/impl/GeoProcessorTest.java
index 0e16c928..24682e16 100644
--- a/geo/src/test/java/org/netbeans/html/geo/impl/GeoProcessorTest.java
+++ b/geo/src/test/java/org/netbeans/html/geo/impl/GeoProcessorTest.java
@@ -19,6 +19,7 @@
 package org.netbeans.html.geo.impl;
 
 import java.io.IOException;
+import org.netbeans.html.testing.Compile;
 import org.testng.annotations.Test;
 
 /** Test whether the annotation processor detects errors correctly.
diff --git a/json/pom.xml b/json/pom.xml
index 31c5a962..c15d8973 100644
--- a/json/pom.xml
+++ b/json/pom.xml
@@ -83,12 +83,10 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.graalvm.js</groupId>
-      <artifactId>js</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.graalvm.js</groupId>
-      <artifactId>js-scriptengine</artifactId>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>testing</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
     </dependency>
   </dependencies>
     <description>API for smooth representation of JSON objects in Java. Write 
your
diff --git a/json/src/test/java/net/java/html/json/MapModelTest.java 
b/json/src/test/java/net/java/html/json/MapModelTest.java
index cc5f2d33..495ba28a 100644
--- a/json/src/test/java/net/java/html/json/MapModelTest.java
+++ b/json/src/test/java/net/java/html/json/MapModelTest.java
@@ -18,6 +18,7 @@
  */
 package net.java.html.json;
 
+import org.netbeans.html.testing.Compile;
 import net.java.html.BrwsrCtx;
 import java.io.IOException;
 import java.io.InputStream;
@@ -306,7 +307,7 @@ public class MapModelTest {
 
         assertNotEquals(one.changes, 0, "At least one change");
 
-        if (isJDK8()) {
+        if (Compile.isJDK8()) {
             assertEquals(one.changes, 1, "Exactly one echange");
         }
     }
@@ -374,15 +375,6 @@ public class MapModelTest {
         assertEquals(incThreeTimes.cnt, 3, "Property change delivered three 
times");
     }
 
-    private static boolean isJDK8() {
-        try {
-            Class.forName("java.lang.FunctionalInterface");
-            return true;
-        } catch (ClassNotFoundException ex) {
-            return false;
-        }
-    }
-    
     static final class One {
         int changes;
         final PropertyBinding pb;
diff --git a/json/src/test/java/net/java/html/json/ModelProcessorTest.java 
b/json/src/test/java/net/java/html/json/ModelProcessorTest.java
index a4406275..42acb916 100644
--- a/json/src/test/java/net/java/html/json/ModelProcessorTest.java
+++ b/json/src/test/java/net/java/html/json/ModelProcessorTest.java
@@ -18,6 +18,7 @@
  */
 package net.java.html.json;
 
+import org.netbeans.html.testing.Compile;
 import java.io.IOException;
 import java.util.Locale;
 import javax.tools.Diagnostic;
diff --git a/pom.xml b/pom.xml
index 1f3c30af..1c2f7dd6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,6 @@
   <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
       <netbeans.version>RELEASE130</netbeans.version>
-      <graalvm.version>21.3.0</graalvm.version>
       <grizzly.version>2.3.8</grizzly.version>
       <openjfx.version>11.0.2</openjfx.version>
       <license>COPYING</license>
@@ -76,6 +75,7 @@
     <module>renderer</module>
     <module>generic</module>
     <module>webkit</module>
+    <module>testing</module>
   </modules>
   <licenses>
       <license>
@@ -551,25 +551,11 @@ 
org.netbeans.html.boot.impl:org.netbeans.html.boot.fx:org.netbeans.html.context.
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <artifactId>js</artifactId>
-            <groupId>org.graalvm.js</groupId>
-            <type>jar</type>
-            <scope>test</scope>
-            <version>${graalvm.version}</version>
-        </dependency>
-        <dependency>
-            <artifactId>js-scriptengine</artifactId>
-            <groupId>org.graalvm.js</groupId>
-            <type>jar</type>
-            <scope>test</scope>
-            <version>${graalvm.version}</version>
-        </dependency>
       </dependencies>
   </dependencyManagement>
   <profiles>
       <profile>
-          <id>jdk8</id>
+          <id>javafx8</id>
           <activation>
               <file>
                   <exists>${java.home}/lib/ext/jfxrt.jar</exists>
diff --git a/sound/pom.xml b/sound/pom.xml
index 777e8e5a..1dee0c3f 100644
--- a/sound/pom.xml
+++ b/sound/pom.xml
@@ -108,12 +108,10 @@
           <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.graalvm.js</groupId>
-            <artifactId>js</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.graalvm.js</groupId>
-            <artifactId>js-scriptengine</artifactId>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>testing</artifactId>
+          <version>${project.version}</version>
+          <scope>test</scope>
         </dependency>
     </dependencies>
 </project>
diff --git a/testing/pom.xml b/testing/pom.xml
new file mode 100644
index 00000000..70456754
--- /dev/null
+++ b/testing/pom.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.netbeans.html</groupId>
+        <artifactId>pom</artifactId>
+        <version>2.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>testing</artifactId>
+    <packaging>jar</packaging>
+    <properties>
+        <exec.mainClass>org.netbeans.html.testing.Testing</exec.mainClass>
+        <enforcer.skip>true</enforcer.skip>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <profiles>
+        <profile>
+            <id>graaljs8</id>
+            <activation>
+                <jdk>[1.8,21)</jdk>
+            </activation>
+            <properties>
+                <graaljs.version>21.3.0</graaljs.version>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.graalvm.js</groupId>
+                    <artifactId>js</artifactId>
+                    <scope>runtime</scope>
+                    <version>${graaljs.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.graalvm.js</groupId>
+                    <artifactId>js-scriptengine</artifactId>
+                    <scope>runtime</scope>
+                    <version>${graaljs.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>graaljs21</id>
+            <activation>
+                <jdk>[21,]</jdk>
+            </activation>
+            <properties>
+                <graaljs.version>25.0.3</graaljs.version>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.graalvm.js</groupId>
+                    <artifactId>js-language</artifactId>
+                    <scope>runtime</scope>
+                    <version>${graaljs.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.graalvm.js</groupId>
+                    <artifactId>js-scriptengine</artifactId>
+                    <scope>runtime</scope>
+                    <version>${graaljs.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file
diff --git a/json/src/test/java/net/java/html/json/Compile.java 
b/testing/src/main/java/org/netbeans/html/testing/Compile.java
similarity index 78%
rename from json/src/test/java/net/java/html/json/Compile.java
rename to testing/src/main/java/org/netbeans/html/testing/Compile.java
index 7ca2c4d6..5335fe2a 100644
--- a/json/src/test/java/net/java/html/json/Compile.java
+++ b/testing/src/main/java/org/netbeans/html/testing/Compile.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package net.java.html.json;
+package org.netbeans.html.testing;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -44,15 +44,17 @@ import javax.tools.SimpleJavaFileObject;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.StandardLocation;
 import javax.tools.ToolProvider;
-import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 /**
  *
  * @author Jaroslav Tulach
  */
-final class Compile implements DiagnosticListener<JavaFileObject> {
-    private final List<Diagnostic<? extends JavaFileObject>> errors = 
-            new ArrayList<Diagnostic<? extends JavaFileObject>>();
+public final class Compile implements DiagnosticListener<JavaFileObject> {
+    private final List<Diagnostic<? extends JavaFileObject>> errors = new 
ArrayList<>();
     private final Map<String, byte[]> classes;
     private final String pkg;
     private final String cls;
@@ -72,28 +74,37 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
     public static Compile create(String html, String code) throws IOException {
         return create(html, code, "8");
     }
-    static Compile create(String html, String code, String sourceLevel) throws 
IOException {
+
+    /** Performs compilation of given HTML page and associated Java code
+     */
+    public static Compile create(String html, String code, String sourceLevel) 
throws IOException {
         return new Compile(html, code, sourceLevel);
     }
-    
+
     /** Checks for given class among compiled resources */
     public byte[] get(String res) {
         return classes.get(res);
     }
-    
+
     /** Obtains errors created during compilation.
      */
-    public List<Diagnostic<? extends JavaFileObject>> getErrors() {
-        List<Diagnostic<? extends JavaFileObject>> err;
-        err = new ArrayList<Diagnostic<? extends JavaFileObject>>();
+    public final List<Diagnostic<? extends JavaFileObject>> getErrors() {
+        return getDiagnostics(Diagnostic.Kind.ERROR);
+    }
+
+    /** Obtains diagnostics of a specific kind created during compilation.
+     * @param kind the kind of diagnostics to obtain
+     */
+    public final List<Diagnostic<? extends JavaFileObject>> 
getDiagnostics(Diagnostic.Kind kind) {
+        var err = new ArrayList<Diagnostic<? extends JavaFileObject>>();
         for (Diagnostic<? extends JavaFileObject> diagnostic : errors) {
-            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+            if (diagnostic.getKind() == kind) {
                 err.add(diagnostic);
             }
         }
         return err;
     }
-    
+
     private Map<String, byte[]> compile(final String html, final String code) 
throws IOException {
         StandardJavaFileManager sjfm = 
ToolProvider.getSystemJavaCompiler().getStandardFileManager(this, null, null);
 
@@ -117,15 +128,24 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
                 return new ByteArrayInputStream(html.getBytes());
             }
         };
-        
+
         final URI scratch;
         try {
             scratch = new URI("mem://mem3");
         } catch (URISyntaxException ex) {
             throw new IOException(ex);
         }
-        
+
         JavaFileManager jfm = new 
ForwardingJavaFileManager<JavaFileManager>(sjfm) {
+            @Override
+            public FileObject getFileForOutput(JavaFileManager.Location 
location, String packageName, String relativeName, FileObject sibling) throws 
IOException {
+                try {
+                    return new VirtFO(new URI("mem://resource/" + 
relativeName), Kind.OTHER, relativeName);
+                } catch (URISyntaxException ex) {
+                    throw new IllegalStateException(ex);
+                }
+            }
+
             @Override
             public JavaFileObject getJavaFileForOutput(Location location, 
String className, Kind kind, FileObject sibling) throws IOException {
                 if (kind  == Kind.CLASS) {
@@ -139,7 +159,7 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
                         }
                     };
                 }
-                
+
                 if (kind == Kind.SOURCE) {
                     final String n = className.replace('.', '/') + ".java";
                     final URI un;
@@ -150,7 +170,7 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
                     }
                     return new VirtFO(un/*sibling.toUri()*/, kind, n);
                 }
-                
+
                 throw new IllegalStateException();
             }
 
@@ -161,7 +181,7 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
                         return htmlFile;
                     }
                 }
-                
+
                 return null;
             }
 
@@ -170,7 +190,7 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
                 if (a instanceof VirtFO && b instanceof VirtFO) {
                     return ((VirtFO)a).getName().equals(((VirtFO)b).getName());
                 }
-                
+
                 return super.isSameFile(a, b);
             }
 
@@ -224,11 +244,15 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
                 }
             }
         };
-
-        ToolProvider.getSystemJavaCompiler().getTask(null, jfm, this, 
/*XXX:*/Arrays.asList("-source", sourceLevel, "-target", sourceLevel), null, 
Arrays.asList(file)).call();
-
-        Map<String, byte[]> result = new HashMap<String, byte[]>();
-
+        var options = new ArrayList<String>();
+        options.addAll(Arrays.asList("-source", sourceLevel));
+        options.addAll(Arrays.asList("-target", sourceLevel));
+        if (isJDK17()) {
+            options.add("-proc:full");
+        }
+        var task = ToolProvider.getSystemJavaCompiler().getTask(null, jfm, 
this, options, null, Arrays.asList(file));
+        task.call();
+        var result = new HashMap<String, byte[]>();
         for (Map.Entry<String, ByteArrayOutputStream> e : 
class2BAOS.entrySet()) {
             result.put(e.getKey(), e.getValue().toByteArray());
         }
@@ -264,14 +288,14 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
         String fqn = "'" + pkg + '.' + cls + "'";
         return html.replace("'${fqn}'", fqn);
     }
-    void assertErrors() {
+    public final void assertErrors() {
         assertFalse(getErrors().isEmpty(), "There are supposed to be some 
errors");
     }
-    void assertNoErrors() {
+    public final void assertNoErrors() {
         assertTrue(getErrors().isEmpty(), "There are supposed to be no errors: 
" + getErrors());
     }
 
-    void assertError(String expMsg) {
+    public final void assertError(String expMsg) {
         StringBuilder sb = new StringBuilder();
         sb.append("Can't find ").append(expMsg).append(" among:");
         for (Diagnostic<? extends JavaFileObject> e : errors) {
@@ -284,4 +308,29 @@ final class Compile implements 
DiagnosticListener<JavaFileObject> {
         }
         fail(sb.toString());
     }
+
+    public static boolean isJDK8() {
+        try {
+            Class.forName("java.lang.FunctionalInterface");
+            return true;
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+    public static boolean isJDK11() {
+        try {
+            Class.forName("java.lang.Module");
+            return true;
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+    public static boolean isJDK17() {
+        try {
+            Class.forName("java.lang.Record");
+            return true;
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists


Reply via email to