From 41fba27ce8728722076f1c0c9f81db215c7b494a Mon Sep 17 00:00:00 2001 From: Mat Booth Date: Thu, 28 Sep 2017 16:13:50 +0100 Subject: [PATCH] Better support system installed versions of Jython for Linux distros --- .../debug/ui/launching/PythonRunnerConfig.java | 4 ++- .../python/pydev/runners/SimpleJythonRunner.java | 33 ++++++++++++++++--- .../ui/interpreters/JythonInterpreterManager.java | 21 ++++++++++++ .../AbstractInterpreterProviderFactory.java | 2 +- .../pydev/ui/pythonpathconf/InterpreterInfo.java | 8 ++--- .../JythonInterpreterProviderFactory.java | 37 +++++++++++++++++++--- 6 files changed, 89 insertions(+), 16 deletions(-) diff --git a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java index ae4202094..6aa827837 100644 --- a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java +++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/ui/launching/PythonRunnerConfig.java @@ -59,6 +59,7 @@ import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.ast.interpreter_managers.InterpreterInfo; import org.python.pydev.ast.interpreter_managers.InterpreterManagersAPI; import org.python.pydev.ast.listing_utils.JavaVmLocationFinder; +import org.python.pydev.ast.runners.SimpleJythonRunner; import org.python.pydev.ast.runners.SimpleRunner; import org.python.pydev.core.ExtensionHelper; import org.python.pydev.core.IInterpreterInfo; @@ -701,7 +702,8 @@ public class PythonRunnerConfig { // if (project.getNature(Constants.JAVA_NATURE) != null){ // cpath = getClasspath(JavaCore.create(project)); // } else { - cpath = interpreter + SimpleRunner.getPythonPathSeparator() + pythonpathUsed; + cpath = SimpleJythonRunner.generateClasspath(interpreter.toString()) + SimpleRunner.getPythonPathSeparator() + + pythonpathUsed; // } cmdArgs.add(cpath); cmdArgs.add("-Dpython.path=" + pythonpathUsed); //will be added to the env variables in the run (check if this works on all platforms...) diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/runners/SimpleJythonRunner.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/runners/SimpleJythonRunner.java index 1b3d84c2b..f5552ce68 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/runners/SimpleJythonRunner.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/runners/SimpleJythonRunner.java @@ -11,9 +11,13 @@ package org.python.pydev.runners; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.AssertionFailedException; @@ -81,15 +85,15 @@ public class SimpleJythonRunner extends SimpleRunner { //In Jython 2.5b0, if we don't set python.home, it won't be able to calculate the correct PYTHONPATH //(see http://bugs.jython.org/issue1214 ) + String classpath = generateClasspath(jythonJar); String pythonHome = new File(jythonJar).getParent().toString(); if (additionalPythonpath != null) { - jythonJar += SimpleRunner.getPythonPathSeparator(); - jythonJar += additionalPythonpath; + classpath += SimpleRunner.getPythonPathSeparator() + additionalPythonpath; s = new String[] { javaLoc, "-Dpython.path=" + additionalPythonpath, "-Dpython.home=" + pythonHome, - "-classpath", jythonJar, "org.python.util.jython", script }; + "-classpath", classpath, "org.python.util.jython", script }; } else { - s = new String[] { javaLoc, "-Dpython.home=" + pythonHome, "-classpath", jythonJar, + s = new String[] { javaLoc, "-Dpython.home=" + pythonHome, "-classpath", classpath, "org.python.util.jython", script }; } @@ -147,6 +151,8 @@ public class SimpleJythonRunner extends SimpleRunner { } jythonPath.append(libs); + String classpath = generateClasspath(jythonJar); + //may have the dir or be null String cacheDir = null; try { @@ -162,7 +168,7 @@ public class SimpleJythonRunner extends SimpleRunner { String[] s = new String[] { "-Dpython.path=" + jythonPath.toString(), "-classpath", - jythonJar + pathSeparator + jythonPath, + classpath + pathSeparator + jythonPath, "org.python.util.jython", script }; @@ -178,4 +184,21 @@ public class SimpleJythonRunner extends SimpleRunner { return asList.toArray(new String[0]); } + public static String generateClasspath(String jythonJar) { + Path jythonPath = Paths.get(jythonJar); + String separator = SimpleRunner.getPythonPathSeparator(); + try { + String javalibs = Files.list(jythonPath.getParent().resolve("javalib")) + .filter(Files::isRegularFile) + .map(Path::toString) + .collect(Collectors.joining(separator)); + String classpath = jythonPath.toString(); + if (javalibs != null && !javalibs.isEmpty()) { + classpath += separator + javalibs; + } + return classpath; + } catch (IOException e) { + return jythonPath.toString(); + } + } } diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/JythonInterpreterManager.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/JythonInterpreterManager.java index e9f3333d1..6970c0854 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/JythonInterpreterManager.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/JythonInterpreterManager.java @@ -12,6 +12,10 @@ package org.python.pydev.ast.interpreter_managers; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import org.eclipse.core.runtime.CoreException; @@ -71,6 +75,23 @@ public class JythonInterpreterManager extends AbstractInterpreterManager { } File script = getInterpreterInfoPy(); + Path path = Paths.get(executable); + try { + if (executable.endsWith(".jar")) { + path = path.getParent().toRealPath(); + } else { + path = path.toRealPath().getParent().getParent(); + } + if (Files.isRegularFile(path.resolve("jython.jar")) && Files.isDirectory(path.resolve("Lib"))) { + executable = path.resolve("jython.jar").toString(); + } else if (Files.isRegularFile(path.resolve("jython-dev.jar")) + && Files.isDirectory(path.resolve("Lib"))) { + executable = path.resolve("jython-dev.jar").toString(); + } + } catch (IOException e) { + executable = path.toString(); + } + //gets the info for the python side Tuple outTup = new SimpleJythonRunner().runAndGetOutputWithJar( FileUtils.getFileAbsolutePath(script), diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java index 0e012a9c9..7f10e3b4f 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/AbstractInterpreterProviderFactory.java @@ -72,7 +72,7 @@ public abstract class AbstractInterpreterProviderFactory implements IInterpreter if (available != null) { for (File afile : available) { int priority = matchesPattern(patterns, afile); - if (priority != INVALID) { + if (priority != INVALID && !afile.isDirectory()) { if (pathSetsByPriority[priority] == null) { pathSetsByPriority[priority] = new LinkedHashSet(); } diff --git a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java index 17145cf46..c8c051bb9 100644 --- a/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java +++ b/plugins/org.python.pydev.ast/src/org/python/pydev/ast/interpreter_managers/InterpreterInfo.java @@ -14,6 +14,7 @@ package org.python.pydev.ui.pythonpathconf; import java.io.File; import java.io.FilenameFilter; import java.io.StringReader; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1479,10 +1481,8 @@ public class InterpreterInfo implements IInterpreterInfo { * @return if the executable is the jython jar. */ public static boolean isJythonExecutable(String executable) { - if (executable.endsWith("\"")) { - return executable.endsWith(".jar\""); - } - return executable.endsWith(".jar"); + java.nio.file.Path p = Paths.get(executable); + return p.endsWith(Paths.get("bin", "jython")) || p.getFileName().toString().endsWith(".jar"); } /** diff --git a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java index dc2586ce3..6b397f22d 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java +++ b/plugins/org.python.pydev/src/org/python/pydev/ui/pythonpathconf/JythonInterpreterProviderFactory.java @@ -12,6 +12,10 @@ ******************************************************************************/ package org.python.pydev.ui.pythonpathconf; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; @@ -57,13 +61,36 @@ public class JythonInterpreterProviderFactory extends AbstractInterpreterProvide } catch (CoreException e) { Log.log(e); } + // The jython home location for linux packaged versions of jython + pathsToSearch.add("/usr/share/jython"); + // The standard location for jars on linux distros pathsToSearch.add("/usr/share/java"); - pathsToSearch.add("/usr/bin"); - pathsToSearch.add("/usr/local/bin"); - String[] searchResults = searchPaths(pathsToSearch, Arrays.asList("jython.jar")); - if (searchResults.length > 0) { - return AlreadyInstalledInterpreterProvider.create("jython", searchResults); + String[] searchResults = searchPaths(pathsToSearch, Arrays.asList("jython.jar", "jython-dev.jar", "jython"), + false); + + LinkedHashSet paths = new LinkedHashSet<>(); + for (String result : searchResults) { + Path path = Paths.get(result); + try { + if (result.endsWith(".jar")) { + path = path.getParent().toRealPath(); + } else { + path = path.toRealPath().getParent().getParent(); + } + if (Files.isRegularFile(path.resolve("jython.jar")) && Files.isDirectory(path.resolve("Lib"))) { + paths.add(path.resolve("jython.jar").toString()); + } else if (Files.isRegularFile(path.resolve("jython-dev.jar")) + && Files.isDirectory(path.resolve("Lib"))) { + paths.add(path.resolve("jython-dev.jar").toString()); + } + } catch (IOException e) { + continue; + } + } + + if (paths.size() > 0) { + return AlreadyInstalledInterpreterProvider.create("jython", paths.toArray(new String[paths.size()])); } return null; -- 2.13.5