diff --git a/.github/build.sh b/.github/build.sh new file mode 100755 index 0000000..523abeb --- /dev/null +++ b/.github/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-build.sh +sh ci-build.sh diff --git a/.github/setup.sh b/.github/setup.sh new file mode 100755 index 0000000..a03464b --- /dev/null +++ b/.github/setup.sh @@ -0,0 +1,3 @@ +#!/bin/sh +curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-setup-github-actions.sh +sh ci-setup-github-actions.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..612b61d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,38 @@ +name: build + +on: + push: + branches: + - main + tags: + - "*-[0-9]+.*" + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'zulu' + cache: 'maven' + - name: Set up CI environment + run: .github/setup.sh + shell: bash + - name: Execute the build + run: .github/build.sh + shell: bash + env: + GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + MAVEN_USER: ${{ secrets.MAVEN_USER }} + MAVEN_PASS: ${{ secrets.MAVEN_PASS }} + CENTRAL_USER: ${{ secrets.CENTRAL_USER }} + CENTRAL_PASS: ${{ secrets.CENTRAL_PASS }} + SIGNING_ASC: ${{ secrets.SIGNING_ASC }} diff --git a/LICENSE.txt b/LICENSE.txt index cce13af..b4d1bd0 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2008 - 2015, Board of Regents of the University of +Copyright (c) 2008 - 2026, Board of Regents of the University of Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck Institute of Molecular Cell Biology and Genetics. All rights reserved. diff --git a/README.md b/README.md index a683aa9..a16ffca 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![](https://github.com/scijava/scripting-java/actions/workflows/build.yml/badge.svg)](https://github.com/scijava/scripting-java/actions/workflows/build.yml) + # Java Scripting This library provides a diff --git a/pom.xml b/pom.xml index 38030e9..459e65e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,22 +1,25 @@ - + 4.0.0 org.scijava pom-scijava - 6.0.0 + 44.0.0 scripting-java - 0.3.1-SNAPSHOT + 1.0.2-SNAPSHOT SciJava Scripting: Java JSR-223-compliant Java scripting language plugin. - http://scijava.org/ + https://github.com/scijava/scripting-java 2008 - + + SciJava + https://scijava.org/ + Simplified BSD License @@ -25,33 +28,42 @@ - - dscho - Johannes Schindelin - schindelin@wisc.edu - http://loci.wisc.edu/people/johannes-schindelin - UW-Madison LOCI - http://loci.wisc.edu/ - - architect - developer - - -6 - ctrueden Curtis Rueden - ctrueden@wisc.edu - http://loci.wisc.edu/people/curtis-rueden - UW-Madison LOCI - http://loci.wisc.edu/ + https://imagej.net/User:Rueden - architect + lead developer + debugger + reviewer + support + maintainer - -6 + + + Johannes Schindelin + https://imagej.net/User:Schindelin + founder + dscho + + + Gabriel Einsdorf + https://imagej.net/User:Gab1one + gab1one + + + Jonathan Hale + Squareys + + + Mark Hiner + https://imagej.net/User:Hinerm + hinerm + + @@ -64,22 +76,29 @@ - scm:git:git://github.com/scijava/scripting-java + scm:git:https://github.com/scijava/scripting-java scm:git:git@github.com:scijava/scripting-java HEAD https://github.com/scijava/scripting-java - GitHub Issues https://github.com/scijava/scripting-java/issues - - Jenkins - https://jenkins.imagej.net/job/scripting-Java/ + GitHub Actions + https://github.com/scijava/scripting-java/actions + + 8 + org.scijava.plugins.scripting.java + bsd_2 + Board of Regents of the University of +Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck +Institute of Molecular Cell Biology and Genetics. + + @@ -91,60 +110,23 @@ scijava-common + + + io.github.classgraph + classgraph + + junit junit test + + org.scijava + scijava-common + tests + test + - - - - - maven-jar-plugin - - - - org.scijava.plugins.scripting.java - - - - - - org.codehaus.mojo - license-maven-plugin - - bsd_2 - Board of Regents of the University of -Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck -Institute of Molecular Cell Biology and Genetics. - - - - - - - - - tools-jar - - - - ${java.home}/../lib/tools.jar - - - - - com.sun - tools - 1.4.2 - system - ${java.home}/../lib/tools.jar - - - - - diff --git a/src/main/java/org/scijava/plugins/scripting/java/AbstractJavaRunner.java b/src/main/java/org/scijava/plugins/scripting/java/AbstractJavaRunner.java deleted file mode 100644 index 9c4165b..0000000 --- a/src/main/java/org/scijava/plugins/scripting/java/AbstractJavaRunner.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * #%L - * JSR-223-compliant Java scripting language plugin. - * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of - * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck - * Institute of Molecular Cell Biology and Genetics. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -package org.scijava.plugins.scripting.java; - -import org.scijava.plugin.AbstractHandlerPlugin; - -/** - * Abstract superclass of {@link JavaRunner} implementations. - * - * @author Curtis Rueden - */ -public abstract class AbstractJavaRunner extends - AbstractHandlerPlugin> implements JavaRunner -{ - - // -- Typed methods -- - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Class> getType() { - return (Class) Class.class; - } - -} diff --git a/src/main/java/org/scijava/plugins/scripting/java/CommandJavaRunner.java b/src/main/java/org/scijava/plugins/scripting/java/CommandJavaRunner.java deleted file mode 100644 index 37daa90..0000000 --- a/src/main/java/org/scijava/plugins/scripting/java/CommandJavaRunner.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * #%L - * JSR-223-compliant Java scripting language plugin. - * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of - * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck - * Institute of Molecular Cell Biology and Genetics. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -package org.scijava.plugins.scripting.java; - -import org.scijava.command.Command; -import org.scijava.command.CommandInfo; -import org.scijava.command.CommandService; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.plugin.PluginService; - -/** - * Runs the given {@link Command} class. - * - * @author Curtis Rueden - */ -@Plugin(type = JavaRunner.class) -public class CommandJavaRunner extends AbstractJavaRunner { - - @Parameter - private PluginService pluginService; - - @Parameter - private CommandService commandService; - - // -- JavaRunner methods -- - - @Override - public void run(final Class c) { - @SuppressWarnings("unchecked") - final Class commandClass = (Class) c; - final Plugin annotation = c.getAnnotation(Plugin.class); - final CommandInfo info = new CommandInfo(commandClass, annotation); - pluginService.addPlugin(info); - commandService.run(info, true); - } - - // -- Typed methods -- - - @Override - public boolean supports(final Class c) { - return Command.class.isAssignableFrom(c); - } - -} diff --git a/src/main/java/org/scijava/plugins/scripting/java/DefaultJavaService.java b/src/main/java/org/scijava/plugins/scripting/java/DefaultJavaService.java deleted file mode 100644 index 81b27f7..0000000 --- a/src/main/java/org/scijava/plugins/scripting/java/DefaultJavaService.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * #%L - * JSR-223-compliant Java scripting language plugin. - * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of - * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck - * Institute of Molecular Cell Biology and Genetics. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -package org.scijava.plugins.scripting.java; - -import javax.script.ScriptException; - -import org.scijava.log.LogService; -import org.scijava.plugin.AbstractHandlerService; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; -import org.scijava.service.Service; - -/** - * Default service for managing available {@link JavaRunner} plugins. - * - * @author Curtis Rueden - */ -@Plugin(type = Service.class) -public class DefaultJavaService extends - AbstractHandlerService, JavaRunner> implements JavaService -{ - - @Parameter - private LogService log; - - // -- JavaService methods -- - - @Override - public void run(final Class c) throws ScriptException { - for (final JavaRunner runner : getInstances()) { - if (runner.supports(c)) { - runner.run(c); - return; - } - } - log.error("Unknown class type: " + c.getName()); - } - - // -- PTService methods -- - - @Override - public Class getPluginType() { - return JavaRunner.class; - } - - // -- Typed methods -- - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Class> getType() { - return (Class) Class.class; - } - -} diff --git a/src/main/java/org/scijava/plugins/scripting/java/JavaEngine.java b/src/main/java/org/scijava/plugins/scripting/java/JavaEngine.java index 93f0cde..ea2a4fa 100644 --- a/src/main/java/org/scijava/plugins/scripting/java/JavaEngine.java +++ b/src/main/java/org/scijava/plugins/scripting/java/JavaEngine.java @@ -2,7 +2,7 @@ * #%L * JSR-223-compliant Java scripting language plugin. * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of + * Copyright (C) 2008 - 2026 Board of Regents of the University of * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck * Institute of Molecular Cell Biology and Genetics. * %% @@ -31,6 +31,33 @@ package org.scijava.plugins.scripting.java; +import io.github.classgraph.ClassGraph; +import org.scijava.command.CommandService; +import org.scijava.minimaven.BuildEnvironment; +import org.scijava.minimaven.Coordinate; +import org.scijava.minimaven.MavenProject; +import org.scijava.plugin.Parameter; +import org.scijava.plugin.PluginService; +import org.scijava.run.RunService; +import org.scijava.script.AbstractScriptEngine; +import org.scijava.util.FileUtils; +import org.scijava.util.LineOutputStream; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -43,43 +70,13 @@ import java.io.Reader; import java.io.StringReader; import java.io.Writer; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; -import java.util.jar.Attributes.Name; -import java.util.jar.JarFile; -import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.script.ScriptEngine; -import javax.script.ScriptException; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.scijava.command.CommandService; -import org.scijava.minimaven.BuildEnvironment; -import org.scijava.minimaven.Coordinate; -import org.scijava.minimaven.MavenProject; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.PluginService; -import org.scijava.script.AbstractScriptEngine; -import org.scijava.util.FileUtils; -import org.scijava.util.LineOutputStream; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - /** * A pseudo-{@link ScriptEngine} compiling and executing Java classes. *

@@ -114,14 +111,14 @@ public class JavaEngine extends AbstractScriptEngine { private CommandService commandService; @Parameter - private JavaService javaService; + private RunService runService; /** * Compiles and runs the specified {@code .java} class. If a filename is set * in the engine scope bindings via the {@link ScriptEngine#FILENAME} key, * this method compiles that file and runs the resulting main class instead. *

- * The currently active {@link JavaService} is responsible for running the + * The currently active {@link RunService} is responsible for running the * class. *

* @@ -133,7 +130,7 @@ public Object eval(String script) throws ScriptException { final Writer writer = getContext().getErrorWriter(); try { final Class clazz = compile(script); - javaService.run(clazz); + runService.run(clazz); } catch (Exception e) { if (writer != null) { @@ -154,7 +151,7 @@ public Object eval(String script) throws ScriptException { * in the engine scope bindings via the {@link ScriptEngine#FILENAME} key, * this method compiles that file and runs the resulting main class instead. *

- * The currently active {@link JavaService} is responsible for running the + * The currently active {@link RunService} is responsible for running the * class. *

* @@ -188,53 +185,43 @@ public Class compile(String script) throws ScriptException { File file = path == null ? null : new File(path); final Writer writer = getContext().getErrorWriter(); + final Builder builder = new Builder(); try { - - final Builder builder; - if (file != null && file.exists()) { // if the filename set in engine scope bindings is valid, // ignore the given script and use that file instead. - builder = new Builder(file, writer); + builder.initialize(file, writer); } else { // script may be null, but then we cannot create a StringReader for it, // therefore null is passed if script is null. final Reader reader = (script == null) ? null : new StringReader(script); - builder = new Builder(reader, writer); + builder.initialize(reader, writer); } final MavenProject project = builder.project; String mainClass = builder.mainClass; - try { - project.build(true); + project.build(true); + if (mainClass == null) { + mainClass = project.getMainClass(); if (mainClass == null) { - mainClass = project.getMainClass(); - if (mainClass == null) { - throw new ScriptException("No main class found for file " + file); - } + throw new ScriptException("No main class found for file " + file); } - - // make class loader - String[] paths = project.getClassPath(false).split(File.pathSeparator); - URL[] urls = new URL[paths.length]; - for (int i = 0; i < urls.length; i++) - urls[i] = - new URL("file:" + paths[i] + (paths[i].endsWith(".jar") ? "" : "/")); - URLClassLoader classLoader = - new URLClassLoader(urls, Thread.currentThread() - .getContextClassLoader()); - - // needed for annotation processing - Thread.currentThread().setContextClassLoader(classLoader); - - // load main class - return classLoader.loadClass(mainClass); - } - finally { - builder.cleanup(); } + + // make class loader + String[] paths = project.getClassPath(false).split(File.pathSeparator); + URL[] urls = new URL[paths.length]; + for (int i = 0; i < urls.length; i++) + urls[i] = + new URL("file:" + paths[i] + (paths[i].endsWith(".jar") ? "" : "/")); + + final URLClassLoader classLoader = new URLClassLoader(urls, Thread.currentThread() + .getContextClassLoader()); + + // load main class + return classLoader.loadClass(mainClass); } catch (Exception e) { if (writer != null) { @@ -247,6 +234,9 @@ public Class compile(String script) throws ScriptException { throw new ScriptException(e); } } + finally { + builder.cleanup(); + } return null; } @@ -295,20 +285,19 @@ public void compile(final File file) { * @see #compile(String) */ public void compile(final File file, final Writer errorWriter) { + final Writer writer = + (errorWriter == null) ? getContext().getErrorWriter() : errorWriter; + final Builder builder = new Builder(); try { - final Writer writer = - (errorWriter == null) ? getContext().getErrorWriter() : errorWriter; - final Builder builder = new Builder(file, writer); - try { - builder.project.build(); - } - finally { - builder.cleanup(); - } + builder.initialize(file, writer); + builder.project.build(); } catch (Throwable t) { printOrThrow(t, errorWriter); } + finally { + builder.cleanup(); + } } /** @@ -322,22 +311,21 @@ public void compile(final File file, final Writer errorWriter) { public void makeJar(final File file, final boolean includeSources, final File output, final Writer errorWriter) { + final Builder builder = new Builder(); try { - final Builder builder = new Builder(file, errorWriter); - try { - builder.project.build(true, true, includeSources); - final File target = builder.project.getTarget(); - if (output != null && !target.equals(output)) { - BuildEnvironment.copyFile(target, output); - } - } - finally { - builder.cleanup(); + builder.initialize(file, errorWriter); + builder.project.build(true, true, includeSources); + final File target = builder.project.getTarget(); + if (output != null && !target.equals(output)) { + BuildEnvironment.copyFile(target, output); } } catch (Throwable t) { printOrThrow(t, errorWriter); } + finally { + builder.cleanup(); + } } /** @@ -371,14 +359,17 @@ private void printOrThrow(Throwable t, Writer errorWriter) { */ private class Builder { - private final PrintStream err; - private final File temporaryDirectory; + private PrintStream err; + private File temporaryDirectory; private String mainClass; private MavenProject project; /** * Constructs a wrapper around a possibly project for a source or maven * project file. + *

+ * This method is intended to be called only once. + *

* * @param file the {@code .java} file to build (or null, if {@code reader} * is set). @@ -391,7 +382,7 @@ private class Builder { * @throws TransformerException * @throws TransformerFactoryConfigurationError */ - private Builder(final File file, final Writer errorWriter) + private void initialize(final File file, final Writer errorWriter) throws ScriptException, IOException, ParserConfigurationException, SAXException, TransformerConfigurationException, TransformerException, TransformerFactoryConfigurationError @@ -414,6 +405,9 @@ private Builder(final File file, final Writer errorWriter) /** * Constructs a wrapper around a possibly temporary project for source code * generated by a Reader. + *

+ * This method is intended to be called only once. + *

* * @param reader provides the Java source if {@code file} is {@code null} * @param errorWriter where to write the error output. @@ -425,7 +419,7 @@ private Builder(final File file, final Writer errorWriter) * @throws TransformerException * @throws TransformerFactoryConfigurationError */ - private Builder(final Reader reader, final Writer errorWriter) + private void initialize(final Reader reader, final Writer errorWriter) throws ScriptException, IOException, ParserConfigurationException, SAXException, TransformerConfigurationException, TransformerException, TransformerFactoryConfigurationError @@ -473,8 +467,8 @@ public void println(final String line) throws IOException { * @return the created {@link BuildEnvironment}. */ private BuildEnvironment createBuildEnvironment() { - boolean verbose = "true".equals(get("verbose")); - boolean debug = "true".equals(get("debug")); + boolean verbose = "true".equals(get("verbose")) || log().isInfo(); + boolean debug = "true".equals(get("debug")) || log().isDebug(); return new BuildEnvironment(err, true, verbose, debug); } @@ -553,8 +547,9 @@ private static String getFullClassName(final File file) throws IOException { Pattern.compile(".*public class ([a-zA-Z0-9_]*).*"); final BufferedReader reader = new BufferedReader(new FileReader(file)); for (;;) { - String line = reader.readLine().trim(); + String line = reader.readLine(); if (line == null) break; + line = line.trim(); outerLoop: while (line.startsWith("/*")) { int end = line.indexOf("*/", 2); @@ -764,7 +759,7 @@ private static Element append(final Document document, final Element parent, { Element child = document.createElement(tag); if (content != null) child - .appendChild(document.createCDATASection(content)); + .appendChild(document.createTextNode(content)); parent.appendChild(child); return child; } @@ -788,23 +783,14 @@ private static Element append(final Document document, final Element parent, getAllDependencies(final BuildEnvironment env) { final List result = new ArrayList(); - for (ClassLoader loader = Thread.currentThread().getContextClassLoader(); loader != null; loader = - loader.getParent()) - { - if (loader instanceof URLClassLoader) { - for (final URL url : ((URLClassLoader) loader).getURLs()) { - if (url.getProtocol().equals("file")) { - final File file = new File(url.getPath()); - if (url.toString().matches( - ".*/target/surefire/surefirebooter[0-9]*\\.jar")) - { - getSurefireBooterURLs(file, url, env, result); - continue; - } - result.add(fakeDependency(env, file)); - } - } - } + ClassGraph cg = new ClassGraph(); + String cp = cg.getClasspath(); + String[] candidates = cp.split(File.pathSeparator); + + for( String candidate : candidates ){ + File file = new File(candidate); + Coordinate c = fakeDependency(env, file); + result.add(c); } return result; } @@ -831,56 +817,6 @@ private static Coordinate fakeDependency(final BuildEnvironment env, return dependency; } - /** - * Figures out the class path given a {@code .jar} file generated by the - * {@code maven-surefire-plugin}. - *

- * A little-known feature of JAR files is that their manifest can specify - * additional class path elements in a {@code Class-Path} entry. The - * {@code maven-surefire-plugin} makes extensive use of that: the URLs of the - * of the active {@link URLClassLoader} will consist of only a single - * {@code .jar} file that is empty except for a manifest whose sole purpose is - * to specify the dependencies. - *

- *

- * This method can be used to discover those additional class path elements. - *

- * - * @param file the {@code .jar} file generated by the - * {@code maven-surefire-plugin} - * @param baseURL the {@link URL} of the {@code .jar} file, needed for class - * path elements specified as relative paths - * @param env the {@link BuildEnvironment}, to store the Maven POMs faked for - * the class path elements - * @param result the list of dependencies to which the discovered dependencies - * are added - */ - private static void getSurefireBooterURLs(final File file, final URL baseURL, - final BuildEnvironment env, final List result) - { - try { - final JarFile jar = new JarFile(file); - Manifest manifest = jar.getManifest(); - if (manifest != null) { - final String classPath = - manifest.getMainAttributes().getValue(Name.CLASS_PATH); - if (classPath != null) { - for (final String element : classPath.split(" +")) - try { - final File dependency = - new File(new URL(baseURL, element).getPath()); - result.add(fakeDependency(env, dependency)); - } - catch (MalformedURLException e) { - e.printStackTrace(); - } - } - } - } - catch (final IOException e) { - e.printStackTrace(); - } - } /** * Read complete contents of a Reader and return as String. diff --git a/src/main/java/org/scijava/plugins/scripting/java/JavaEngineBindings.java b/src/main/java/org/scijava/plugins/scripting/java/JavaEngineBindings.java index 173165c..7620396 100644 --- a/src/main/java/org/scijava/plugins/scripting/java/JavaEngineBindings.java +++ b/src/main/java/org/scijava/plugins/scripting/java/JavaEngineBindings.java @@ -2,7 +2,7 @@ * #%L * JSR-223-compliant Java scripting language plugin. * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of + * Copyright (C) 2008 - 2026 Board of Regents of the University of * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck * Institute of Molecular Cell Biology and Genetics. * %% diff --git a/src/main/java/org/scijava/plugins/scripting/java/JavaRunner.java b/src/main/java/org/scijava/plugins/scripting/java/JavaRunner.java deleted file mode 100644 index 005696c..0000000 --- a/src/main/java/org/scijava/plugins/scripting/java/JavaRunner.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * #%L - * JSR-223-compliant Java scripting language plugin. - * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of - * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck - * Institute of Molecular Cell Biology and Genetics. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -package org.scijava.plugins.scripting.java; - -import javax.script.ScriptException; - -import org.scijava.plugin.HandlerPlugin; -import org.scijava.plugin.Plugin; - -/** - * A plugin which extends the Java script language's execution handling. A - * {@code JavaRunner} knows how to execute certain classes, beyond just Java's - * usual {@code main} method. - *

- * Java runner plugins discoverable at runtime must implement this interface and - * be annotated with @{@link Plugin} with attribute {@link Plugin#type()} = - * {@link JavaRunner}.class. While it possible to create an console argument - * plugin merely by implementing this interface, it is encouraged to instead - * extend {@link AbstractJavaRunner}, for convenience. - *

- * - * @author Curtis Rueden - */ -public interface JavaRunner extends HandlerPlugin> { - - /** Executes the given class. */ - void run(Class c) throws ScriptException; - -} diff --git a/src/main/java/org/scijava/plugins/scripting/java/JavaScriptLanguage.java b/src/main/java/org/scijava/plugins/scripting/java/JavaScriptLanguage.java index 0aa43dd..7c4d08f 100644 --- a/src/main/java/org/scijava/plugins/scripting/java/JavaScriptLanguage.java +++ b/src/main/java/org/scijava/plugins/scripting/java/JavaScriptLanguage.java @@ -2,7 +2,7 @@ * #%L * JSR-223-compliant Java scripting language plugin. * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of + * Copyright (C) 2008 - 2026 Board of Regents of the University of * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck * Institute of Molecular Cell Biology and Genetics. * %% diff --git a/src/main/java/org/scijava/plugins/scripting/java/JavaService.java b/src/main/java/org/scijava/plugins/scripting/java/JavaService.java deleted file mode 100644 index 232d1b8..0000000 --- a/src/main/java/org/scijava/plugins/scripting/java/JavaService.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * #%L - * JSR-223-compliant Java scripting language plugin. - * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of - * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck - * Institute of Molecular Cell Biology and Genetics. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -package org.scijava.plugins.scripting.java; - -import javax.script.ScriptException; - -import org.scijava.plugin.HandlerService; -import org.scijava.service.SciJavaService; - -/** - * Interface for service that manages available {@link JavaRunner} plugins. - * - * @author Curtis Rueden - */ -public interface JavaService extends - HandlerService, JavaRunner>, SciJavaService -{ - - /** Executes the given class using the most appropriate handler. */ - void run(Class c) throws ScriptException; - -} diff --git a/src/main/java/org/scijava/plugins/scripting/java/MainJavaRunner.java b/src/main/java/org/scijava/plugins/scripting/java/MainJavaRunner.java deleted file mode 100644 index b4dea91..0000000 --- a/src/main/java/org/scijava/plugins/scripting/java/MainJavaRunner.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * #%L - * JSR-223-compliant Java scripting language plugin. - * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of - * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck - * Institute of Molecular Cell Biology and Genetics. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -package org.scijava.plugins.scripting.java; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import javax.script.ScriptException; - -import org.scijava.Priority; -import org.scijava.log.LogService; -import org.scijava.plugin.Parameter; -import org.scijava.plugin.Plugin; - -/** - * Executes the given class's {@code main} method. - * - * @author Curtis Rueden - */ -@Plugin(type = JavaRunner.class, priority = Priority.LOW_PRIORITY) -public class MainJavaRunner extends AbstractJavaRunner { - - @Parameter(required = false) - private LogService log; - - // -- JavaRunner methods -- - - @Override - public void run(final Class c) throws ScriptException { - try { - getMain(c).invoke(null, new Object[] { new String[0] }); - } - catch (final IllegalArgumentException exc) { - throw new ScriptException(exc); - } - catch (final IllegalAccessException exc) { - throw new ScriptException(exc); - } - catch (final InvocationTargetException exc) { - throw new ScriptException(exc); - } - } - - // -- Typed methods -- - - @Override - public boolean supports(final Class c) { - return getMain(c) != null; - } - - // -- Helper methods -- - - private Method getMain(final Class c) { - try { - return c.getMethod("main", String[].class); - } - catch (final SecurityException exc) { - if (log != null) log.debug(exc); - return null; - } - catch (final NoSuchMethodException exc) { - if (log != null) log.debug(exc); - return null; - } - } - -} diff --git a/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory new file mode 100644 index 0000000..bb5de81 --- /dev/null +++ b/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory @@ -0,0 +1 @@ +org.scijava.plugins.scripting.java.JavaScriptLanguage diff --git a/src/test/java/org/scijava/plugins/scripting/java/JavaEngineTest.java b/src/test/java/org/scijava/plugins/scripting/java/JavaEngineTest.java index 15bb104..6e9e68b 100644 --- a/src/test/java/org/scijava/plugins/scripting/java/JavaEngineTest.java +++ b/src/test/java/org/scijava/plugins/scripting/java/JavaEngineTest.java @@ -2,7 +2,7 @@ * #%L * JSR-223-compliant Java scripting language plugin. * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of + * Copyright (C) 2008 - 2026 Board of Regents of the University of * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck * Institute of Molecular Cell Biology and Genetics. * %% @@ -48,6 +48,8 @@ import org.junit.Test; import org.scijava.Context; import org.scijava.object.ObjectService; +import org.scijava.run.RunService; +import org.scijava.script.AbstractScriptLanguageTest; import org.scijava.script.ScriptLanguage; import org.scijava.script.ScriptService; import org.scijava.test.TestUtils; @@ -57,14 +59,19 @@ * * @author Johannes Schindelin */ -public class JavaEngineTest { +public class JavaEngineTest extends AbstractScriptLanguageTest { + + @Test + public void testDiscovery() { + assertDiscovered(JavaScriptLanguage.class); + } @Before public void assumeJavaC() { boolean found = false; try { final ClassLoader classLoader = getClass().getClassLoader(); - found = classLoader.loadClass("com.sun.tools.javac.Main") != null; + found = classLoader.loadClass("javax.tools.ToolProvider") != null; } catch (final Throwable t) { // NB: No action needed. @@ -161,6 +168,32 @@ public void testEvalReader() throws Exception { assertTrue(result); } + @Test + public void testAnnotations() { + boolean result = true; + final String source = "" + // + "import org.scijava.command.Command;\n" + // + "import org.scijava.plugin.Plugin;\n" + // + "@Plugin(type = Command.class)\n" + // + "public class PluginTest implements Command {\n" + // + "\t@Override\n" + // + "\tpublic void run() {\n" + // + "\t\tSystem.out.println(\"I am a plugin!\");\n" + // + "\t}\n" + // + "}"; + + final ScriptEngine miniMaven = miniMaven(); + try { + miniMaven.eval(source); + } + catch (final ScriptException e) { + e.printStackTrace(); + result = false; + } + + assertTrue(result); + } + // -- helper functions private File makeMinimalProject() throws IOException { @@ -241,7 +274,7 @@ private void writeFiles(final File dir, final String... args) private ScriptEngine miniMaven() { final Context context = - new Context(ScriptService.class, ObjectService.class, JavaService.class); + new Context(ScriptService.class, ObjectService.class, RunService.class); final ObjectService objectService = context.getService(ObjectService.class); final ScriptLanguage java = objectService.getObjects(JavaScriptLanguage.class).get(0); diff --git a/src/test/java/org/scijava/plugins/scripting/java/MakeJarTest.java b/src/test/java/org/scijava/plugins/scripting/java/MakeJarTest.java index 5729664..39dff7c 100644 --- a/src/test/java/org/scijava/plugins/scripting/java/MakeJarTest.java +++ b/src/test/java/org/scijava/plugins/scripting/java/MakeJarTest.java @@ -2,7 +2,7 @@ * #%L * JSR-223-compliant Java scripting language plugin. * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of + * Copyright (C) 2008 - 2026 Board of Regents of the University of * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck * Institute of Molecular Cell Biology and Genetics. * %% diff --git a/src/test/resources/Dummy.java b/src/test/resources/Dummy.java index 6d168ce..a26e8cd 100644 --- a/src/test/resources/Dummy.java +++ b/src/test/resources/Dummy.java @@ -2,7 +2,7 @@ * #%L * JSR-223-compliant Java scripting language plugin. * %% - * Copyright (C) 2008 - 2015 Board of Regents of the University of + * Copyright (C) 2008 - 2026 Board of Regents of the University of * Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck * Institute of Molecular Cell Biology and Genetics. * %%