Switch LS to std in/out from socket with port

This commit is contained in:
BoykoAlex
2021-08-11 19:20:28 -04:00
parent 3209237334
commit 4447021b79
23 changed files with 139 additions and 211 deletions

View File

@@ -53,14 +53,6 @@ import com.google.common.collect.ImmutableSet;
*/
public class DelegatingStreamConnectionProvider implements StreamConnectionProvider {
private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder");
private static void debug(String string) {
if (DEBUG) {
System.out.println(string);
}
}
private StreamConnectionProvider provider;
private ResourceListener fResourceListener;
private LanguageServer languageServer;

View File

@@ -75,7 +75,6 @@ public class LiveProcessCommandsQuickAccessProvider implements IQuickAccessCompu
}
private void createCommandItems(List<QuickAccessElement> res, Object commandResult) {
System.out.println(commandResult);
if (commandResult instanceof List<?>) {
List<?> allCommands = (List<?>) commandResult;

View File

@@ -43,7 +43,7 @@ public class LanguageServerProcessReaper extends Thread {
private static void debug(String string) {
if (DEBUG) {
System.out.println("LanguageServerProcessReaper: "+string);
System.err.println("LanguageServerProcessReaper: "+string);
}
}

View File

@@ -19,21 +19,17 @@ import org.eclipse.core.filebuffers.IFileBuffer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.springframework.tooling.jdt.ls.commons.Logger;
public class ProjectSorter implements Comparator<IProject> {
private Set<IProject> projectsWithEditors;
private Logger logger = Logger.forEclipsePlugin(() -> LanguageServerCommonsActivator.getInstance());
public ProjectSorter() {
this.projectsWithEditors = new HashSet<IProject>();
IFileBuffer[] openBuffers = FileBuffers.getTextFileBufferManager().getFileBuffers();
for (IFileBuffer ob : openBuffers) {
IPath path = ob.getLocation();
System.out.println(path);
if (path.segmentCount() >= 1) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
projectsWithEditors.add(project);

View File

@@ -38,7 +38,6 @@ public class InProjectSymbolsProvider implements SymbolsProvider {
public static InProjectSymbolsProvider createFor(LiveExpression<IProject> project) {
LiveExpression<List<LanguageServer>> languageServers = project.apply(p -> {
System.out.println("project = "+(p==null?null:p.getName()));
return p == null
? ImmutableList.of()
: LanguageServiceAccessor.getLanguageServers(

View File

@@ -51,7 +51,6 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider {
return LanguageServiceAccessor.getLanguageServers(project,
WS_SYMBOL_CAP, true);
} else {
System.out.println("project = null");
return LanguageServiceAccessor.getActiveLanguageServers(WS_SYMBOL_CAP);
}
});

View File

@@ -10,11 +10,13 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.jandex;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
@@ -190,7 +192,7 @@ public class IndexRoutines {
private static IndexView createJarIndex(File indexFile, File jarFile) {
try {
return JarIndexer.createJarIndex(jarFile, new Indexer(), indexFile, false, false,
false, System.out, System.err).getIndex();
false, new PrintStream(new ByteArrayOutputStream()), System.err).getIndex();
} catch (Exception e) {
log.error("Failed to index '" + jarFile + "'", e);
return null;

View File

@@ -58,9 +58,6 @@ public class BadWordReconcileEngine implements IReconcileEngine {
@Override
public void reconcile(IDocument doc, IProblemCollector problemCollector) {
String text = doc.get();
System.out.println(">>>> reconciling for bad words ==========");
System.out.println(text);
System.out.println("<<<< reconciling for bad words ==========");
problemCollector.beginCollecting();
try {

View File

@@ -144,7 +144,7 @@ public class AsyncProcess {
if (captureStreams) {
init(workingDir, cmd, new ByteArrayOutputStream(), new ByteArrayOutputStream());
} else {
init(workingDir, cmd, System.out, System.err);
init(workingDir, cmd, System.err, System.err);
}
}
@@ -197,12 +197,12 @@ public class AsyncProcess {
result.append("exitValue = "+exitValue+"\n");
String strOut = getOut();
if (strOut!=null) {
result.append("------- System.out -------\n");
result.append("------- System-out -------\n");
result.append(strOut);
}
String strErr = getErr();
if (strErr!=null) {
result.append("------- System.err -------\n");
result.append("------- System-err -------\n");
result.append(strErr);
}
result.append("<<<< ExternalProcess");

View File

@@ -71,9 +71,7 @@ public class ExternalCommand {
* 0 exit value an exception is thrown.
*/
public void exec(File workdir) throws IOException, InterruptedException, TimeoutException {
System.out.println(">>> exec: "+this);
ExternalProcess process = new ExternalProcess(workdir, this);
System.out.println(process);
new ExternalProcess(workdir, this);
// org.junit.Assert.assertEquals(0, process.getExitValue());
}

View File

@@ -151,7 +151,7 @@ public class ExternalProcess {
if (captureStreams) {
init(workingDir, cmd, new ByteArrayOutputStream(), new ByteArrayOutputStream(), timeout);
} else {
init(workingDir, cmd, System.out, System.err, timeout);
init(workingDir, cmd, System.err, System.err, timeout);
}
}
@@ -178,12 +178,12 @@ public class ExternalProcess {
result.append("exitValue = "+exitValue+"\n");
String strOut = getOut();
if (strOut!=null) {
result.append("------- System.out -------\n");
result.append("------- System-out -------\n");
result.append(strOut);
}
String strErr = getErr();
if (strErr!=null) {
result.append("------- System.err -------\n");
result.append("------- System-err -------\n");
result.append(strErr);
}
result.append("<<<< ExternalProcess");

View File

@@ -22,8 +22,7 @@ public class LogRedirect {
String logfilePath = System.getProperty("sts.log.file");
if (StringUtil.hasText(logfilePath)) {
PrintStream logFile = logFileStream(logfilePath);
System.setErr(logFile);
System.setOut(logFile); //Spring boot actually logs on sysout instead of syserr.
System.setErr(logFile);
}
}

View File

@@ -34,14 +34,7 @@ import org.springframework.ide.vscode.commons.util.text.IRegion;
* </p>
*/
public abstract class AbstractLineTracker implements ILineTracker, ILineTrackerExtension {
/**
* Tells whether this class is in debug mode.
*
* @since 3.1
*/
private static final boolean DEBUG= false;
/**
* Combines the information of the occurrence of a line delimiter. <code>delimiterIndex</code>
* is the index where a line delimiter starts, whereas <code>delimiterLength</code>,
@@ -267,8 +260,6 @@ public abstract class AbstractLineTracker implements ILineTracker, ILineTrackerE
* @since 3.1
*/
protected final void flushRewriteSession() throws BadLocationException {
if (DEBUG)
System.out.println("AbstractLineTracker: Flushing rewrite session: " + fActiveRewriteSession); //$NON-NLS-1$
Iterator<Request> e= fPendingRequests.iterator();

View File

@@ -109,7 +109,6 @@ public class ManifestYamlLanguageServerInitializer implements InitializingBean {
});
// workspace.onDidChangeConfiguraton(settings -> {
// System.out.println("Config changed: "+params);
// Integer val = settings.getInt("languageServerExample", "maxNumberOfProblems");
// if (val!=null) {
// maxProblems = ((Number) val).intValue();

View File

@@ -6,7 +6,6 @@ cd ../jdt-ls-extension
if command -v xvfb-run ; then
echo "Using xvfb to run in headless environment..."
xvfb-run ../mvnw \
-DskipTests \
-DtrimStackTrace=false \
-f ../pom.xml \
-pl $modules \
@@ -14,7 +13,6 @@ if command -v xvfb-run ; then
clean install
else
../mvnw \
-DskipTests \
-DtrimStackTrace=false \
-f ../pom.xml \
-pl $modules \
@@ -24,7 +22,6 @@ fi
cd ../xml-ls-extension
../mvnw \
-DtrimStackTrace=false \
-DskipTests \
-f ../pom.xml \
-pl xml-ls-extension \
-am \

View File

@@ -126,27 +126,4 @@ public class AnnotationHierarchyAwareLookup<T> {
return bindings.containsKey(fqName);
}
// private static int indent = 0;
//
// private static void debug(int indent, String msg) {
// for (int i = 0; i < indent; i++) {
// System.out.print(" ");
// }
// System.out.println(msg);
// }
// private static int debug_in(String msg) {
// for (int i = 0; i < indent; i++) {
// System.out.print(" ");
// }
// System.out.println(">> "+msg);
// return indent ++;
// }
// private static void debug_out(String msg) {
// indent --;
// for (int i = 0; i < indent; i++) {
// System.out.print(" ");
// }
// System.out.println("<< "+msg);
// }
}

View File

@@ -230,7 +230,6 @@ public class SpringIndexerXML implements SpringIndexer {
// List<DOMAttr> attributeNodes = node.getAttributeNodes();
// if (attributeNodes != null) {
// for (DOMAttr attribute : attributeNodes) {
// System.out.println(attribute.getName() + " - " + attribute.getValue());
// }
// }
// }

View File

@@ -64,12 +64,6 @@ public class SpringPropertyIndex {
}
}
// System.out.println(">>> spring properties metadata loaded "+this.size()+" items===");
// dumpAsTestData();
// System.out.println(">>> spring properties metadata loaded "+this.size()+" items===");
// } catch (Exception e) {
// LOG.log
// }
}
}
@@ -77,32 +71,6 @@ public class SpringPropertyIndex {
properties.add(new PropertyInfo(valueProviders, propertyInfo));
}
// /**
// * Dumps out 'test data' based on the current contents of the index. This is not meant to be
// * used in 'production' code. The idea is to call this method during development to dump a
// * 'snapshot' of the index onto System.out. The data is printed in a forma so that it can be easily
// * pasted/used into JUNit testing code.
// */
// public void dumpAsTestData() {
// List<Match<PropertyInfo>> allData = this.find("");
// for (Match<PropertyInfo> match : allData) {
// PropertyInfo d = match.data;
// System.out.println("data("
// +dumpString(d.getId())+", "
// +dumpString(d.getType())+", "
// +dumpString(d.getDefaultValue())+", "
// +dumpString(d.getDescription()) +");"
// );
//// for (PropertySource source : d.getSources()) {
//// String st = source.getSourceType();
//// String sm = source.getSourceMethod();
//// if (sm!=null) {
//// System.out.println(d.getId() +" from: "+st+"::"+sm);
//// }
//// }
// }
// }
private String dumpString(Object v) {
if (v==null) {
return "null";

View File

@@ -154,9 +154,6 @@ public class RequestMappingDependentConstantChangedTest {
{
List<? extends SymbolInformation> symbols = indexer.getSymbols(pingUri);
for (SymbolInformation s : symbols) {
System.out.println(s.getName());
}
assertSymbolCount(1, symbols);
assertSymbol(pingUri, "@/pong -- GET", "@GetMapping(PongConstantRequestMapping.PONG)");
}
@@ -190,9 +187,6 @@ public class RequestMappingDependentConstantChangedTest {
{
List<? extends SymbolInformation> symbols = indexer.getSymbols(pingUri);
for (SymbolInformation s : symbols) {
System.out.println(s.getName());
}
assertSymbolCount(1, symbols);
assertSymbol(pingUri, "@/pong -- GET", "@GetMapping(PongConstantRequestMapping.PONG)");
}

View File

@@ -446,7 +446,6 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
}
@Test public void testHyperlinkTargets() throws Exception {
System.out.println(">>> testHyperlinkTargets");
IJavaProject p = createPredefinedMavenProject("tricky-getters-boot-1.3.1-app");
useProject(p);
@@ -467,13 +466,11 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
definitionLinkAsserts.assertLinkTargets(editor, "flyway", p, editor.rangeOf("flyway.init-sqls", "flyway.init-sqls"),
method("org.springframework.boot.autoconfigure.flyway.FlywayProperties", "setInitSqls", "java.util.List"));
System.out.println("<<< testHyperlinkTargets");
}
@Test public void testHyperlinkTargetsLoggingLevel() throws Exception {
System.out.println(">>> testHyperlinkTargetsLoggingLevel");
IJavaProject p = createPredefinedMavenProject("tricky-getters-boot-1.3.1-app");
useProject(p);
@@ -484,7 +481,6 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
definitionLinkAsserts.assertLinkTargets(editor, "level", p, editor.rangeOf("logging.level", "logging.level"),
"org.springframework.boot.logging.LoggingApplicationListener");
System.out.println("<<< testHyperlinkTargetsLoggingLevel");
}
@Test public void testReconcile() throws Exception {

View File

@@ -792,9 +792,6 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
//Probably that is why it fails in CI build?
//Let's check:
// IType type = project.findType("com.fasterxml.jackson.databind.SerializationFeature");
// System.out.println(">>> source for: "+type.getFullyQualifiedName());
// System.out.println(downloadSources(type));
// System.out.println("<<< source for: "+type.getFullyQualifiedName());
editor = newEditor(
"spring:\n" +
@@ -824,9 +821,6 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
//Probably that is why it fails in CI build?
//Let's check:
// IType type = project.findType("com.fasterxml.jackson.databind.SerializationFeature");
// System.out.println(">>> source for: "+type.getFullyQualifiedName());
// System.out.println(downloadSources(type));
// System.out.println("<<< source for: "+type.getFullyQualifiedName());
assertCompletionDetails(
"spring:\n" +
@@ -989,7 +983,6 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
" no: \n" +
" good: true\n"
);
System.out.println(editor);
editor.assertProblems(
"extracrap: 8080|Expecting a 'int' but got a 'Mapping' node",
"snuggem|Unknown property",

View File

@@ -198,7 +198,6 @@ public class ProblemTypesToJson {
}
String newContent = gson.toJson(parsed);
System.out.println(newContent);
FileUtils.writeStringToFile(packageJsonFile, newContent);
}

View File

@@ -8,7 +8,7 @@ import * as Net from 'net';
import * as ChildProcess from 'child_process';
import * as CommonsCommands from './commands';
import { RequestType, LanguageClientOptions, Position } from 'vscode-languageclient';
import {LanguageClient, StreamInfo, ServerOptions} from 'vscode-languageclient/node';
import {LanguageClient, StreamInfo, ServerOptions, ExecutableOptions, Executable} from 'vscode-languageclient/node';
import {
Disposable,
window,
@@ -95,29 +95,16 @@ function getJdtUserDefinedJavaHome(): string {
}
export function activate(options: ActivatorOptions, context: VSCode.ExtensionContext): Thenable<LanguageClient> {
let DEBUG = options.DEBUG;
let jvmHeap = getUserDefinedJvmHeap(options.workspaceOptions, options.jvmHeap);
let jvmArgs = getUserDefinedJvmArgs(options.workspaceOptions);
if (options.CONNECT_TO_LS) {
return VSCode.window.showInformationMessage("Start language server")
.then((x) => connectToLS(context, options));
} else {
let clientOptions = options.clientOptions;
const clientOptions = options.clientOptions;
var log_output = VSCode.window.createOutputChannel(options.extensionId + "-debug-log");
log("Activating '" + options.extensionId + "' extension");
function log(msg: string) {
if (log_output) {
log_output.append(msg + "\n");
}
}
function error(msg: string) {
if (log_output) {
log_output.append("ERR: " + msg + "\n");
}
}
const outChennalName = options.extensionId + "-debug-log"
clientOptions.outputChannel = VSCode.window.createOutputChannel(outChennalName);
clientOptions.outputChannelName = outChennalName;
clientOptions.outputChannel.appendLine("Activating '" + options.extensionId + "' extension");
let findJRE = options.preferJdk ? findJdk : findJvm;
@@ -132,7 +119,7 @@ export function activate(options: ActivatorOptions, context: VSCode.ExtensionCon
return;
}
let javaExecutablePath = jvm.getJavaExecutable();
log("Found java exe: " + javaExecutablePath);
clientOptions.outputChannel.appendLine("Found java exe: " + javaExecutablePath);
let version = jvm.getMajorVersion();
if (version<11) {
@@ -144,84 +131,131 @@ export function activate(options: ActivatorOptions, context: VSCode.ExtensionCon
);
return;
}
log("isJavaEightOrHigher => true");
clientOptions.outputChannel.appendLine("isJavaEightOrHigher => true");
function createServer(): Promise<StreamInfo> {
return new Promise((resolve, reject) => {
PortFinder.getPort((err, port) => {
Net.createServer(socket => {
log('Child process connected on port ' + port);
resolve({
reader: socket,
writer: socket
});
})
.listen(port, () => {
let processLaunchoptions = {
cwd: VSCode.workspace.rootPath
};
let logfile : string = options.workspaceOptions.get("logfile") || "/dev/null";
//The logfile = '/dev/null' is handled specifically by the language server process so it works on all OSs.
log('Redirecting server logs to ' + logfile);
const args = [
'-Dspring.lsp.client-port='+port,
'-Dserver.port=' + port,
'-Dsts.lsp.client=vscode',
'-Dsts.log.file=' + logfile,
'-XX:TieredStopAtLevel=1'
];
if (isCheckingJVM(options.workspaceOptions) && options.checkjvm) {
options.checkjvm(context, jvm);
}
if (jvmHeap && !hasHeapArg(jvmArgs)) {
args.unshift("-Xmx"+jvmHeap);
}
if (jvmArgs) {
args.unshift(...jvmArgs);
}
if (DEBUG) {
args.unshift(DEBUG_ARG);
}
let child: ChildProcess.ChildProcess = null;
if (options.explodedLsJarData) {
const explodedLsJarData = options.explodedLsJarData;
const lsRoot = Path.resolve(context.extensionPath, explodedLsJarData.lsLocation);
// Add config file if needed
if (explodedLsJarData.configFileName) {
args.push(`-Dspring.config.location=file:${Path.resolve(lsRoot, `BOOT-INF/classes/${explodedLsJarData.configFileName}`)}`);
}
// Add classpath
const classpath: string[] = [];
classpath.push(Path.resolve(lsRoot, 'BOOT-INF/classes'));
classpath.push(`${Path.resolve(lsRoot, 'BOOT-INF/lib')}${Path.sep}*`);
child = jvm.mainClassLaunch(explodedLsJarData.mainClass, classpath, args, processLaunchoptions);
} else {
// Start the child java process
const launcher = findServerJar(Path.resolve(context.extensionPath, 'jars'));
child = jvm.jarLaunch(launcher, args, processLaunchoptions);
}
if (child) {
child.stdout.on('data', (data) => {
log("" + data);
});
child.stderr.on('data', (data) => {
error("" + data);
})
}
});
});
});
if (process.env['SPRING_LS_USE_SOCKET']) {
return setupLanguageClient(context, createServerOptionsForPortComm(options, context, jvm), options);
} else {
return setupLanguageClient(context, createServerOptions(options, context, jvm), options);
}
return setupLanguageClient(context, createServer, options);
});
}
}
function createServerOptions(options: ActivatorOptions, context: VSCode.ExtensionContext, jvm: JVM, port? : number): Executable {
const executable: Executable = Object.create(null);
const execOptions: ExecutableOptions = Object.create(null);
execOptions.env = Object.assign(process.env);
// execOptions.cwd = VSCode.workspace.rootPath
executable.options = execOptions;
executable.command = jvm.getJavaExecutable();
const vmArgs = prepareJvmArgs(options, context, jvm, port);
addCpAndLauncherToJvmArgs(vmArgs, options, context);
executable.args = vmArgs;
return executable;
}
function createServerOptionsForPortComm(options: ActivatorOptions, context: VSCode.ExtensionContext, jvm: JVM): ServerOptions {
return () =>
new Promise((resolve, reject) => {
PortFinder.getPort((err, port) => {
Net.createServer(socket => {
options.clientOptions.outputChannel.appendLine('Child process connected on port ' + port);
resolve({
reader: socket,
writer: socket
});
})
.listen(port, () => {
let processLaunchoptions = {
cwd: VSCode.workspace.rootPath
};
const args = prepareJvmArgs(options, context, jvm, port);
if (options.explodedLsJarData) {
const explodedLsJarData = options.explodedLsJarData;
const lsRoot = Path.resolve(context.extensionPath, explodedLsJarData.lsLocation);
// Add classpath
const classpath: string[] = [];
classpath.push(Path.resolve(lsRoot, 'BOOT-INF/classes'));
classpath.push(`${Path.resolve(lsRoot, 'BOOT-INF/lib')}${Path.sep}*`);
jvm.mainClassLaunch(explodedLsJarData.mainClass, classpath, args, processLaunchoptions);
} else {
// Start the child java process
const launcher = findServerJar(Path.resolve(context.extensionPath, 'jars'));
jvm.jarLaunch(launcher, args, processLaunchoptions);
}
});
});
});
}
function prepareJvmArgs(options: ActivatorOptions, context: VSCode.ExtensionContext, jvm: JVM, port?: number): string[] {
const DEBUG = options.DEBUG;
const jvmHeap = getUserDefinedJvmHeap(options.workspaceOptions, options.jvmHeap);
const jvmArgs = getUserDefinedJvmArgs(options.workspaceOptions);
let logfile : string = options.workspaceOptions.get("logfile") || "/dev/null";
//The logfile = '/dev/null' is handled specifically by the language server process so it works on all OSs.
options.clientOptions.outputChannel.appendLine('Redirecting server logs to ' + logfile);
const args = [
'-Dsts.lsp.client=vscode',
'-Dsts.log.file=' + logfile,
'-XX:TieredStopAtLevel=1'
];
if (port && port > 0) {
args.push('-Dspring.lsp.client-port='+port);
args.push('-Dserver.port=' + port);
}
if (isCheckingJVM(options.workspaceOptions) && options.checkjvm) {
options.checkjvm(context, jvm);
}
if (jvmHeap && !hasHeapArg(jvmArgs)) {
args.unshift("-Xmx"+jvmHeap);
}
if (jvmArgs) {
args.unshift(...jvmArgs);
}
if (DEBUG) {
args.unshift(DEBUG_ARG);
}
if (options.explodedLsJarData) {
const explodedLsJarData = options.explodedLsJarData;
const lsRoot = Path.resolve(context.extensionPath, explodedLsJarData.lsLocation);
// Add config file if needed
if (explodedLsJarData.configFileName) {
args.push(`-Dspring.config.location=file:${Path.resolve(lsRoot, `BOOT-INF/classes/${explodedLsJarData.configFileName}`)}`);
}
}
return args;
}
function addCpAndLauncherToJvmArgs(args: string[], options: ActivatorOptions, context: VSCode.ExtensionContext) {
if (options.explodedLsJarData) {
const explodedLsJarData = options.explodedLsJarData;
const lsRoot = Path.resolve(context.extensionPath, explodedLsJarData.lsLocation);
// Add classpath
const classpath: string[] = [];
classpath.push(Path.resolve(lsRoot, 'BOOT-INF/classes'));
classpath.push(`${Path.resolve(lsRoot, 'BOOT-INF/lib')}${Path.sep}*`);
args.unshift(classpath.join(Path.delimiter));
args.unshift('-cp');
args.push(explodedLsJarData.mainClass);
} else {
// Start the child java process
args.push('-jar');
const launcher = findServerJar(Path.resolve(context.extensionPath, 'jars'));
args.push(launcher);
}
}
function hasHeapArg(vmargs?: string[]) : boolean {
if (vmargs) {
return vmargs.some(a => a.startsWith("-Xmx"));