mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[platform] better restarter for Linux (IDEA-161186)
This commit is contained in:
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Waits for the parent process to terminate, then executes specified commands.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
raise Exception('At least one argument expected')
|
||||
|
||||
while os.getppid() != 1:
|
||||
time.sleep(0.5)
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
os.spawnv(os.P_WAIT, sys.argv[2], sys.argv[2:])
|
||||
|
||||
to_launch = sys.argv[1]
|
||||
if sys.platform == 'darwin':
|
||||
os.execv('/usr/bin/open', ['/usr/bin/open', to_launch])
|
||||
else:
|
||||
os.execv(to_launch, [to_launch])
|
||||
@@ -184,23 +184,11 @@ LD_LIBRARY_PATH="$IDE_BIN_HOME:$LD_LIBRARY_PATH" "$JAVA_BIN" \
|
||||
"-Xbootclasspath/a:$IDE_HOME/lib/boot.jar" \
|
||||
-classpath "$CLASSPATH" \
|
||||
${VM_OPTIONS} \
|
||||
"-Djb.vmOptionsFile=$VM_OPTIONS_FILE" \
|
||||
"-XX:ErrorFile=$HOME/java_error_in_@@product_uc@@_%p.log" \
|
||||
"-XX:HeapDumpPath=$HOME/java_error_in_@@product_uc@@.hprof" \
|
||||
-Djb.restart.code=88 -Didea.paths.selector=@@system_selector@@ \
|
||||
-Didea.paths.selector=@@system_selector@@ \
|
||||
"-Djb.vmOptionsFile=$VM_OPTIONS_FILE" \
|
||||
${IDE_PROPERTIES_PROPERTY} \
|
||||
@@ide_jvm_args@@ \
|
||||
com.intellij.idea.Main \
|
||||
"$@"
|
||||
EC=$?
|
||||
unset IFS
|
||||
|
||||
test ${EC} -ne 88 && exit ${EC}
|
||||
|
||||
RESTARTER="$HOME/.@@system_selector@@/system/restart/restarter.sh"
|
||||
if [ -x "$RESTARTER" ]; then
|
||||
"$RESTARTER"
|
||||
"$RM" -f "$RESTARTER"
|
||||
fi
|
||||
|
||||
exec "$0"
|
||||
|
||||
+4
-2
@@ -78,11 +78,13 @@ class CrossPlatformDistributionBuilder {
|
||||
exclude(name: "bin/fsnotifier*")
|
||||
exclude(name: "bin/*.vmoptions")
|
||||
exclude(name: "bin/*.sh")
|
||||
exclude(name: "bin/*.py")
|
||||
exclude(name: "bin/idea.properties")
|
||||
exclude(name: "help/**")
|
||||
}
|
||||
zipfileset(dir: "$linuxDistPath/bin", filemode: "775", prefix: "bin") {
|
||||
zipfileset(dir: "$linuxDistPath/bin", prefix: "bin", filemode: "775") {
|
||||
include(name: "*.sh")
|
||||
include(name: "*.py")
|
||||
}
|
||||
zipfileset(dir: "$linuxDistPath/bin", prefix: "bin/linux", filemode: "775") {
|
||||
include(name: "fsnotifier*")
|
||||
@@ -97,7 +99,7 @@ class CrossPlatformDistributionBuilder {
|
||||
exclude(name: "bin/idea.properties")
|
||||
exclude(name: "bin/*.vmoptions")
|
||||
}
|
||||
zipfileset(dir: "$macDistPath/bin", filemode: "775", prefix: "bin") {
|
||||
zipfileset(dir: "$macDistPath/bin", prefix: "bin", filemode: "775") {
|
||||
include(name: "restarter*")
|
||||
include(name: "*.py")
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder {
|
||||
paths.each {
|
||||
tarfileset(dir: it, prefix: tarRoot) {
|
||||
exclude(name: "bin/*.sh")
|
||||
exclude(name: "bin/*.py")
|
||||
exclude(name: "bin/fsnotifier*")
|
||||
extraBins.each {
|
||||
exclude(name: it)
|
||||
@@ -166,8 +167,9 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder {
|
||||
}
|
||||
|
||||
paths.each {
|
||||
tarfileset(dir: it, filemode: "755", prefix: tarRoot) {
|
||||
tarfileset(dir: it, prefix: tarRoot, filemode: "755") {
|
||||
include(name: "bin/*.sh")
|
||||
include(name: "bin/*.py")
|
||||
include(name: "bin/fsnotifier*")
|
||||
extraBins.each {
|
||||
include(name: it)
|
||||
|
||||
@@ -1006,10 +1006,12 @@ binding.setVariable("buildCrossPlatformZip", { String zipPath, String sandbox, L
|
||||
exclude(name: "bin/fsnotifier*")
|
||||
exclude(name: "bin/*.vmoptions")
|
||||
exclude(name: "bin/*.sh")
|
||||
exclude(name: "bin/*.py")
|
||||
exclude(name: "help/**")
|
||||
}
|
||||
zipfileset(dir: "$distUnix/bin", filemode: "775", prefix: "bin") {
|
||||
zipfileset(dir: "$distUnix/bin", prefix: "bin", filemode: "775") {
|
||||
include(name: "*.sh")
|
||||
include(name: "*.py")
|
||||
}
|
||||
zipfileset(dir: "$distUnix/bin", prefix: "bin/linux", filemode: "775") {
|
||||
include(name: "fsnotifier*")
|
||||
@@ -1024,7 +1026,7 @@ binding.setVariable("buildCrossPlatformZip", { String zipPath, String sandbox, L
|
||||
exclude(name: "bin/idea.properties")
|
||||
exclude(name: "bin/*.vmoptions")
|
||||
}
|
||||
zipfileset(dir: "$distMac/bin", filemode: "775", prefix: "bin") {
|
||||
zipfileset(dir: "$distMac/bin", prefix: "bin", filemode: "775") {
|
||||
include(name: "restarter*")
|
||||
include(name: "*.py")
|
||||
}
|
||||
@@ -1058,7 +1060,7 @@ binding.setVariable("buildMacZip", { String zipRoot, String zipPath, List paths,
|
||||
}
|
||||
|
||||
allPaths.each {
|
||||
zipfileset(dir: it, filemode: "755", prefix: zipRoot) {
|
||||
zipfileset(dir: it, prefix: zipRoot, filemode: "755") {
|
||||
include(name: "bin/*.sh")
|
||||
include(name: "bin/*.py")
|
||||
include(name: "bin/fsnotifier")
|
||||
@@ -1090,6 +1092,7 @@ binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths,
|
||||
paths.each {
|
||||
tarfileset(dir: it, prefix: tarRoot) {
|
||||
exclude(name: "bin/*.sh")
|
||||
exclude(name: "bin/*.py")
|
||||
exclude(name: "bin/fsnotifier*")
|
||||
extraBins.each {
|
||||
exclude(name: it)
|
||||
@@ -1099,8 +1102,9 @@ binding.setVariable("buildTarGz", { String tarRoot, String tarPath, List paths,
|
||||
}
|
||||
|
||||
paths.each {
|
||||
tarfileset(dir: it, filemode: "755", prefix: tarRoot) {
|
||||
tarfileset(dir: it, prefix: tarRoot, filemode: "755") {
|
||||
include(name: "bin/*.sh")
|
||||
include(name: "bin/*.py")
|
||||
include(name: "bin/fsnotifier*")
|
||||
extraBins.each {
|
||||
include(name: it)
|
||||
|
||||
@@ -53,6 +53,7 @@ OS_TYPE=`uname -s`
|
||||
if [ "$OS_TYPE" = "Linux" ]; then
|
||||
cp -a "$DEV_IDEA_HOME/bin/linux/"*.so "$WORK_IDEA_HOME/bin"
|
||||
cp -a "$DEV_IDEA_HOME/bin/linux/"fsnotifier* "$WORK_IDEA_HOME/bin"
|
||||
cp -a "$DEV_IDEA_HOME/bin/linux/"*.py "$WORK_IDEA_HOME/bin"
|
||||
elif [ "$OS_TYPE" = "Darwin" ]; then
|
||||
cp -a "$DEV_IDEA_HOME/bin/mac/"*.jnilib "$WORK_IDEA_HOME/bin"
|
||||
cp -a "$DEV_IDEA_HOME/bin/mac/fsnotifier" "$WORK_IDEA_HOME/bin"
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.io.StringWriter;
|
||||
|
||||
public class Main {
|
||||
public static final int NO_GRAPHICS = 1;
|
||||
//public static final int UPDATE_FAILED = 2;
|
||||
public static final int RESTART_FAILED = 2;
|
||||
public static final int STARTUP_EXCEPTION = 3;
|
||||
public static final int JDK_CHECK_FAILED = 4;
|
||||
public static final int DIR_CHECK_FAILED = 5;
|
||||
|
||||
@@ -64,6 +64,7 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
|
||||
public void initComponent() {
|
||||
checkJvm();
|
||||
checkIBus();
|
||||
checkLauncherScript();
|
||||
startDiskSpaceMonitoring();
|
||||
}
|
||||
|
||||
@@ -91,6 +92,12 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLauncherScript() {
|
||||
if (SystemInfo.isXWindow && System.getProperty("jb.restart.code") != null) {
|
||||
showNotification("ide.launcher.script.outdated");
|
||||
}
|
||||
}
|
||||
|
||||
private void showNotification(@PropertyKey(resourceBundle = "messages.IdeBundle") String key) {
|
||||
final String ignoreKey = "ignore." + key;
|
||||
boolean ignored = myProperties.isValueSet(ignoreKey);
|
||||
|
||||
+5
-3
@@ -780,10 +780,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
int exitCode = 0;
|
||||
if (restart && Restarter.isSupported()) {
|
||||
try {
|
||||
exitCode = Restarter.scheduleRestart(beforeRestart);
|
||||
Restarter.scheduleRestart(beforeRestart);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("Cannot restart", e);
|
||||
catch (Throwable t) {
|
||||
LOG.error("Restart failed", t);
|
||||
Main.showMessage("Restart failed", t);
|
||||
exitCode = Main.RESTART_FAILED;
|
||||
}
|
||||
}
|
||||
System.exit(exitCode);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.util;
|
||||
|
||||
import com.intellij.jna.JnaLoader;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
@@ -28,9 +29,7 @@ import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.win32.StdCallLibrary;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -39,76 +38,40 @@ import java.util.List;
|
||||
public class Restarter {
|
||||
private Restarter() { }
|
||||
|
||||
private static int getRestartCode() {
|
||||
return SystemProperties.getIntProperty("jb.restart.code", 0);
|
||||
private static File getLauncherScript() {
|
||||
return new File(PathManager.getBinPath(), ApplicationNamesInfo.getInstance().getLowercaseProductName() + ".sh");
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
if (getRestartCode() != 0) {
|
||||
return true;
|
||||
}
|
||||
if (SystemInfo.isWindows) {
|
||||
return JnaLoader.isLoaded() && new File(PathManager.getBinPath(), "restarter.exe").exists();
|
||||
}
|
||||
if (SystemInfo.isMac) {
|
||||
return PathManager.getHomePath().contains(".app");
|
||||
return PathManager.getHomePath().contains(".app") && new File(PathManager.getBinPath(), "restarter").canExecute();
|
||||
}
|
||||
if (SystemInfo.isUnix) {
|
||||
return getLauncherScript().canExecute() && new File(PathManager.getBinPath(), "restart.py").canExecute();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int scheduleRestart(@NotNull String... beforeRestart) throws IOException {
|
||||
try {
|
||||
int restartCode = getRestartCode();
|
||||
if (restartCode != 0) {
|
||||
runCommand(beforeRestart);
|
||||
return restartCode;
|
||||
}
|
||||
else if (SystemInfo.isWindows) {
|
||||
restartOnWindows(beforeRestart);
|
||||
return 0;
|
||||
}
|
||||
else if (SystemInfo.isMac) {
|
||||
restartOnMac(beforeRestart);
|
||||
return 0;
|
||||
}
|
||||
public static void scheduleRestart(@NotNull String... beforeRestart) throws IOException {
|
||||
if (SystemInfo.isWindows) {
|
||||
restartOnWindows(beforeRestart);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new IOException("Cannot restart application: " + t.getMessage(), t);
|
||||
else if (SystemInfo.isMac) {
|
||||
restartOnMac(beforeRestart);
|
||||
}
|
||||
|
||||
runCommand(beforeRestart);
|
||||
throw new IOException("Cannot restart application: not supported.");
|
||||
}
|
||||
|
||||
private static void runCommand(String... beforeRestart) throws IOException {
|
||||
if (beforeRestart.length == 0) return;
|
||||
|
||||
File restartDir = new File(getRestarterDir());
|
||||
String systemPath = new File(System.getProperty("user.home") + "/." + System.getProperty("idea.paths.selector") + "/system/restart").getPath();
|
||||
if (! systemPath.equals(restartDir.getPath())){
|
||||
throw new IOException("idea.system.path was changed. Restart is not supported.");
|
||||
else if (SystemInfo.isUnix) {
|
||||
restartOnUnix(beforeRestart);
|
||||
}
|
||||
if (!FileUtilRt.createDirectory(restartDir)) {
|
||||
throw new IOException("Cannot create dir: " + restartDir);
|
||||
}
|
||||
|
||||
File restarter = new File(restartDir, "restarter.sh");
|
||||
try (BufferedWriter output = new BufferedWriter(new FileWriter(restarter))) {
|
||||
output.write("#!/bin/sh\n");
|
||||
for (int i = 0; i < beforeRestart.length; i++) {
|
||||
output.write(beforeRestart[i]);
|
||||
if (i <= beforeRestart.length - 2) output.write(' ');
|
||||
if (i >= beforeRestart.length - 2) output.write('"');
|
||||
}
|
||||
output.write('\n');
|
||||
}
|
||||
|
||||
if (!restarter.setExecutable(true, true)) {
|
||||
throw new IOException("Cannot make file executable: " + restarter);
|
||||
else {
|
||||
throw new IOException("Cannot restart application: not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void restartOnWindows(@NotNull String... beforeRestart) throws IOException {
|
||||
private static void restartOnWindows(String... beforeRestart) throws IOException {
|
||||
Kernel32 kernel32 = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
|
||||
Shell32 shell32 = (Shell32)Native.loadLibrary("shell32", Shell32.class);
|
||||
|
||||
@@ -144,14 +107,22 @@ public class Restarter {
|
||||
TimeoutUtil.sleep(500);
|
||||
}
|
||||
|
||||
private static void restartOnMac(@NotNull String... beforeRestart) throws IOException {
|
||||
private static void restartOnMac(String... beforeRestart) throws IOException {
|
||||
String homePath = PathManager.getHomePath();
|
||||
int p = homePath.indexOf(".app");
|
||||
if (p < 0) throw new IOException("Application bundle not found: " + homePath);
|
||||
|
||||
String bundlePath = homePath.substring(0, p + 4);
|
||||
doScheduleRestart(new File(PathManager.getBinPath(), "restarter"), commands -> {
|
||||
Collections.addAll(commands, bundlePath);
|
||||
commands.add(bundlePath);
|
||||
Collections.addAll(commands, beforeRestart);
|
||||
});
|
||||
}
|
||||
|
||||
private static void restartOnUnix(String... beforeRestart) throws IOException {
|
||||
File launcherScript = getLauncherScript();
|
||||
if (!launcherScript.exists()) throw new IOException("Launcher script not found: " + launcherScript);
|
||||
doScheduleRestart(new File(PathManager.getBinPath(), "restart.py"), commands -> {
|
||||
commands.add(launcherScript.getPath());
|
||||
Collections.addAll(commands, beforeRestart);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1138,11 +1138,9 @@ FileChooser.refreshActionLabelText=Refresh
|
||||
browsers.settings=Web Browsers
|
||||
updates.check.period.on.exit=On every exit
|
||||
|
||||
unsupported.jvm.openjdk.message=OpenJDK 6 is not supported. Please use Oracle Java or newer OpenJDK.
|
||||
unsupported.jvm.ea.message=Early Access Java versions may cause compatibility issues. Please use stable release.
|
||||
|
||||
ibus.blocking.warn.message=IBus prior to 1.5.11 may cause input problems. See <a href="https://youtrack.jetbrains.com/issue/IDEA-78860">IDEA-78860</a> for details.
|
||||
|
||||
ide.launcher.script.outdated=IDE launcher script (idea.sh) is outdated. Please upgrade, otherwise you won't be able to restart the IDE.
|
||||
sys.health.acknowledge.link=<br/><a href="ack">Do not show again</a>.
|
||||
|
||||
low.disk.space.message=Low disk space on a {0} system directory partition
|
||||
|
||||
Reference in New Issue
Block a user