Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starting the LSP server locally inside the JVM (second take) #7

Merged
merged 9 commits into from
Apr 8, 2018
40 changes: 36 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
.settings
/bin
/.project
target
build/
.out/
bin/
.bin/
target/

/gradle.properties
/archive/
/META-INF

.classpath
.project
.settings

.idea/
*.iml
*.iws
*.ipr
.idea_modules/
**/out/

*.tmp
*.bak
*.swp
*~

.gradle

.DS_Store*
.AppleDouble
.LSOverride

.directory
.Trash*

**/adhoctest/
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@ Once https://github.com/mickaelistria/eclipse-bluesky/issues/63 will work in Pho

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
which provides those features.

Development in Eclipse
======================

1. Use "Eclipse for Committers" (Photon M6 as of this writing).

2. In Eclipse, "File" / "Import..." / "Existing Maven Projects". Point at the `lsp4e-freemarker` project root directory, add all the Maven projects it finds.

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).
After this, there shouldn't be more errors in the project (no dependency classes that aren't found).

4. To try the plugin, right click on the `org.eclipse.lsp4j.freemarker` project, then "Run as" / "Eclipse Application".
(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
`<location path="${eclipse_home}" type="Directory"/>` to the target platform, but of course there must be a better way.)
3 changes: 1 addition & 2 deletions org.eclipse.lsp4e.freemarker/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ Require-Bundle: org.eclipse.lsp4e,
org.eclipse.jface,
org.eclipse.ui.workbench.texteditor,
org.eclipse.ui.editors,
org.eclipse.ui.genericeditor,
org.eclipse.jdt.launching
org.eclipse.ui.genericeditor
Bundle-Activator: org.eclipse.lsp4e.freemarker.FreemarkerPlugin
Bundle-ActivationPolicy: lazy
Eclipse-BundleShape: dir
2 changes: 1 addition & 1 deletion org.eclipse.lsp4e.freemarker/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<extension
point="org.eclipse.lsp4e.languageServer">
<server
class="org.eclipse.lsp4e.freemarker.FreemarkerLanguageServer"
class="org.eclipse.lsp4e.freemarker.FreemarkerStreamConnectionProvider"
id="org.eclipse.lsp4e.freemarker"
label="Freemarker Language Server" >
</server>
Expand Down
Binary file not shown.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* Copyright (c) 2018 Angelo ZERR, Daniel Dekany.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Angelo Zerr <[email protected]> - initial API and implementation
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add your name

*/
package org.eclipse.lsp4e.freemarker;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.concurrent.Future;

import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;

/**
* Starts the FreeMarker LSP server inside the current JVM, and connects to it.
*/
public class FreemarkerStreamConnectionProvider extends LocalStreamConnectionProvider {

public FreemarkerStreamConnectionProvider() {
super(FreemarkerPlugin.getDefault().getLog(), FreemarkerPlugin.getPluginId());
}

private static final String LANGUAGE_SERVER_JAR_ENTRY_NAME = "server/freemarker-languageserver-all.jar"; //$NON-NLS-1$
private static final String LANGUAGE_SERVER_LAUNCHER_CLASS_NAME = "freemarker.ext.languageserver.FreemarkerServerLauncher"; //$NON-NLS-1$

@Override
protected LocalServer launchServer(InputStream clientToServerStream, OutputStream serverToClientStream)
throws IOException {
URL[] classPath = getFreemarkerLanguageServerClassPath();
logInfo("Using class path: " + Arrays.toString(classPath));

URLClassLoader dynamicJarClassLoader = new URLClassLoader(classPath);

Method launcherMethod;
try {
Class<?> launcherClass = dynamicJarClassLoader.loadClass(LANGUAGE_SERVER_LAUNCHER_CLASS_NAME);
launcherMethod = launcherClass.getMethod("launch", //$NON-NLS-1$
new Class<?>[] { InputStream.class, OutputStream.class });
} catch (Exception e) {
throw new RuntimeException(
"Couldn't get launcher class and method via Java reflection (using class path: "
+ Arrays.toString(classPath) + "); see cause exception", e); //$NON-NLS-2$
}
Future<?> launchedFuture;
try {
launchedFuture = (Future<?>) launcherMethod.invoke(null, clientToServerStream, serverToClientStream);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException("Error when calling launcher method; see cause exception", e); //$NON-NLS-1$
}

return new LocalServer(launchedFuture) {
@Override
public void stop() {
super.stop();
try {
dynamicJarClassLoader.close();
} catch (IOException e) {
logError("Error when closing the dynamic jar class-loader", e); //$NON-NLS-1$
}
}
};
}

private URL[] getFreemarkerLanguageServerClassPath() {
Bundle bundle = Platform.getBundle(FreemarkerPlugin.PLUGIN_ID);
if (bundle == null) {
throw new RuntimeException("Bundle " + FreemarkerPlugin.PLUGIN_ID + " not found"); //$NON-NLS-1$
}

URL languageServerJarURL = bundle.getEntry(LANGUAGE_SERVER_JAR_ENTRY_NAME);
if (languageServerJarURL == null) {
throw new RuntimeException(
"Entity " + LANGUAGE_SERVER_JAR_ENTRY_NAME + " not found in bundle " + FreemarkerPlugin.PLUGIN_ID); //$NON-NLS-1$
}

// TODO: Add freemarker.jar from the user project here, if it's found and has
// high enough version, otherwise add freemarker.jar from this plugin.
// (Currently, freemarker.jar is bundled into the language server jar.)

return new URL[] { languageServerJarURL };
}

}
Loading