Skip to content

Commit 79b27a2

Browse files
authored
Merge pull request angelozerr#7 from ddekany/pr-embedded-lsp-server-2
Starting the LSP server locally inside the JVM (second take)
2 parents 2a4c755 + c042e9e commit 79b27a2

File tree

10 files changed

+341
-192
lines changed

10 files changed

+341
-192
lines changed

.gitignore

+36-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,36 @@
1-
.settings
2-
/bin
3-
/.project
4-
target
1+
build/
2+
.out/
3+
bin/
4+
.bin/
5+
target/
6+
7+
/gradle.properties
8+
/archive/
9+
/META-INF
10+
11+
.classpath
12+
.project
13+
.settings
14+
15+
.idea/
16+
*.iml
17+
*.iws
18+
*.ipr
19+
.idea_modules/
20+
**/out/
21+
22+
*.tmp
23+
*.bak
24+
*.swp
25+
*~
26+
27+
.gradle
28+
29+
.DS_Store*
30+
.AppleDouble
31+
.LSOverride
32+
33+
.directory
34+
.Trash*
35+
36+
**/adhoctest/

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,17 @@ Once https://github.com/mickaelistria/eclipse-bluesky/issues/63 will work in Pho
4141

4242
HTML syntax coloration (managed with TextMate) and HTML completion, mark occurrences, etc is not a part of this plugin. I suggest you that you install https://github.com/mickaelistria/eclipse-bluesky
4343
which provides those features.
44+
45+
Development in Eclipse
46+
======================
47+
48+
1. Use "Eclipse for Committers" (Photon M6 as of this writing).
49+
50+
2. In Eclipse, "File" / "Import..." / "Existing Maven Projects". Point at the `lsp4e-freemarker` project root directory, add all the Maven projects it finds.
51+
52+
3. Now go to "Window" / "Preferences" / "Plug-in Development" / "Target Platform", and Select "lsp4e-freemarker" (this only appears if you have imported the "target-platform" Maven project earlier).
53+
After this, there shouldn't be more errors in the project (no dependency classes that aren't found).
54+
55+
4. To try the plugin, right click on the `org.eclipse.lsp4j.freemarker` project, then "Run as" / "Eclipse Application".
56+
(TODO: Currently that will fail with `Application "org.eclipse.ui.ide.workbench" could not be found in the registry`. I have worked that around by adding
57+
`<location path="${eclipse_home}" type="Directory"/>` to the target platform, but of course there must be a better way.)

org.eclipse.lsp4e.freemarker/META-INF/MANIFEST.MF

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ Require-Bundle: org.eclipse.lsp4e,
1414
org.eclipse.jface,
1515
org.eclipse.ui.workbench.texteditor,
1616
org.eclipse.ui.editors,
17-
org.eclipse.ui.genericeditor,
18-
org.eclipse.jdt.launching
17+
org.eclipse.ui.genericeditor
1918
Bundle-Activator: org.eclipse.lsp4e.freemarker.FreemarkerPlugin
2019
Bundle-ActivationPolicy: lazy
2120
Eclipse-BundleShape: dir

org.eclipse.lsp4e.freemarker/plugin.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<extension
3535
point="org.eclipse.lsp4e.languageServer">
3636
<server
37-
class="org.eclipse.lsp4e.freemarker.FreemarkerLanguageServer"
37+
class="org.eclipse.lsp4e.freemarker.FreemarkerStreamConnectionProvider"
3838
id="org.eclipse.lsp4e.freemarker"
3939
label="Freemarker Language Server" >
4040
</server>
Binary file not shown.

org.eclipse.lsp4e.freemarker/src/org/eclipse/lsp4e/freemarker/FreemarkerLanguageServer.java

-179
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Copyright (c) 2018 Angelo ZERR, Daniel Dekany.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
10+
*/
11+
package org.eclipse.lsp4e.freemarker;
12+
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.io.OutputStream;
16+
import java.lang.reflect.InvocationTargetException;
17+
import java.lang.reflect.Method;
18+
import java.net.URL;
19+
import java.net.URLClassLoader;
20+
import java.util.Arrays;
21+
import java.util.concurrent.Future;
22+
23+
import org.eclipse.core.runtime.Platform;
24+
import org.osgi.framework.Bundle;
25+
26+
/**
27+
* Starts the FreeMarker LSP server inside the current JVM, and connects to it.
28+
*/
29+
public class FreemarkerStreamConnectionProvider extends LocalStreamConnectionProvider {
30+
31+
public FreemarkerStreamConnectionProvider() {
32+
super(FreemarkerPlugin.getDefault().getLog(), FreemarkerPlugin.getPluginId());
33+
}
34+
35+
private static final String LANGUAGE_SERVER_JAR_ENTRY_NAME = "server/freemarker-languageserver-all.jar"; //$NON-NLS-1$
36+
private static final String LANGUAGE_SERVER_LAUNCHER_CLASS_NAME = "freemarker.ext.languageserver.FreemarkerServerLauncher"; //$NON-NLS-1$
37+
38+
@Override
39+
protected LocalServer launchServer(InputStream clientToServerStream, OutputStream serverToClientStream)
40+
throws IOException {
41+
URL[] classPath = getFreemarkerLanguageServerClassPath();
42+
logInfo("Using class path: " + Arrays.toString(classPath));
43+
44+
URLClassLoader dynamicJarClassLoader = new URLClassLoader(classPath);
45+
46+
Method launcherMethod;
47+
try {
48+
Class<?> launcherClass = dynamicJarClassLoader.loadClass(LANGUAGE_SERVER_LAUNCHER_CLASS_NAME);
49+
launcherMethod = launcherClass.getMethod("launch", //$NON-NLS-1$
50+
new Class<?>[] { InputStream.class, OutputStream.class });
51+
} catch (Exception e) {
52+
throw new RuntimeException(
53+
"Couldn't get launcher class and method via Java reflection (using class path: "
54+
+ Arrays.toString(classPath) + "); see cause exception", e); //$NON-NLS-2$
55+
}
56+
Future<?> launchedFuture;
57+
try {
58+
launchedFuture = (Future<?>) launcherMethod.invoke(null, clientToServerStream, serverToClientStream);
59+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
60+
throw new RuntimeException("Error when calling launcher method; see cause exception", e); //$NON-NLS-1$
61+
}
62+
63+
return new LocalServer(launchedFuture) {
64+
@Override
65+
public void stop() {
66+
super.stop();
67+
try {
68+
dynamicJarClassLoader.close();
69+
} catch (IOException e) {
70+
logError("Error when closing the dynamic jar class-loader", e); //$NON-NLS-1$
71+
}
72+
}
73+
};
74+
}
75+
76+
private URL[] getFreemarkerLanguageServerClassPath() {
77+
Bundle bundle = Platform.getBundle(FreemarkerPlugin.PLUGIN_ID);
78+
if (bundle == null) {
79+
throw new RuntimeException("Bundle " + FreemarkerPlugin.PLUGIN_ID + " not found"); //$NON-NLS-1$
80+
}
81+
82+
URL languageServerJarURL = bundle.getEntry(LANGUAGE_SERVER_JAR_ENTRY_NAME);
83+
if (languageServerJarURL == null) {
84+
throw new RuntimeException(
85+
"Entity " + LANGUAGE_SERVER_JAR_ENTRY_NAME + " not found in bundle " + FreemarkerPlugin.PLUGIN_ID); //$NON-NLS-1$
86+
}
87+
88+
// TODO: Add freemarker.jar from the user project here, if it's found and has
89+
// high enough version, otherwise add freemarker.jar from this plugin.
90+
// (Currently, freemarker.jar is bundled into the language server jar.)
91+
92+
return new URL[] { languageServerJarURL };
93+
}
94+
95+
}

0 commit comments

Comments
 (0)