Skip to content

Commit

Permalink
Generate native binary
Browse files Browse the repository at this point in the history
Use GraalVM's `native-image` feature to generate a executable.
Run `./mvnw package -Pnative -DskipTests` in order to generate an
executable under `org.eclipse.lemminx/target`.

Adopted from [PR 673](#673)

A part of #314.

Signed-off-by: Fred Bricon <[email protected]>
Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
fbricon authored and datho7561 committed Aug 27, 2020
1 parent a3a043b commit 182cbd8
Show file tree
Hide file tree
Showing 10 changed files with 1,670 additions and 57 deletions.
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,34 @@ this.forward(clientConnection, serverConnection)
socket.connect(socketPort)
```

Generating a native binary (WIP):
---------------------------------
To generate a native binary:
- [Install GraalVM 20.2.0](https://www.graalvm.org/docs/getting-started/#install-graalvm)
- In a terminal, run `gu install native-image`
- Execute a Maven build activating the `native` profile: `./mvnw clean package -Pnative -DskipTests`
- It will generate a native binary in `org.eclipse.lemminx/target/lemminx-{os.name}-{version}`

OS specific instructions:
- __Fedora__:
- Make sure that you have installed the static versions of the C++ standard library
- __Windows__:
- When installing native-image, please note that `gu` is an existing alias in PowerShell.
Remove the alias with `Remote-Item alias:gu -Force`, refer to `gu` with the absolute path, or use `gu` under `cmd.exe`.
- Make sure to run the Maven wrapper in the "Native Tools Command Prompt".
This command prompt can be obtained through installing the Windows SDK or Visual Studio, as
mentioned in the [GraalVM installation instructions](https://www.graalvm.org/docs/getting-started-with-graalvm/windows/).

`native-image` Development Instructions:
- Reflection:
- If you need to use reflection to access a private field/method, simply register the field/methods that you access in `reflect-config.json`
- If you need to parse some JSON using Gson, make sure to register the fields and methods of the class that you are parsing into in `reflect-config.json`
- Recursively, for all classes that it has, including `enum`s
- Settings are all deserialized, so whenever a setting is added, this must be done and tested
- Manually test the binary and check the logs for reflection errors/NPEs
- Snippets:
- If you are creating a new snippet file, make sure to register it under `org.eclipse.lemminx/src/main/resources/META-INF/resource-config.json`

Maven coordinates:
------------------

Expand Down Expand Up @@ -119,8 +147,8 @@ Here are some clients consuming this XML Language Server:
* [Spring Tools 4](https:/spring-projects/sts4) - re-using the XML parser for Spring-specific analysis and content-assist
* Vim/Neovim with [coc-xml](https:/fannheyward/coc-xml)
* Emacs with [lsp-mode](https:/emacs-lsp/lsp-mode)


Extensions
----------

Expand Down
83 changes: 66 additions & 17 deletions org.eclipse.lemminx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
<dev.build.timestamp>${maven.build.timestamp}</dev.build.timestamp>
<cbi.jarsigner.skip>true</cbi.jarsigner.skip>
<graalvm.version>20.2.0</graalvm.version>
</properties>
<build>
<resources>
Expand Down Expand Up @@ -48,25 +49,27 @@
<artifactId>git-commit-id-plugin</artifactId>
<version>4.0.0</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/../.git</dotGitDirectory>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<includeOnlyProperties>
<includeOnlyProperty>^git.commit.id.abbrev$</includeOnlyProperty>
<includeOnlyProperty>^git.commit.message.short$</includeOnlyProperty>
<includeOnlyProperty>^git.branch$</includeOnlyProperty>
<includeOnlyProperty>^git.build.version$</includeOnlyProperty>
</includeOnlyProperties>
<gitDescribe><skip>true</skip></gitDescribe>
<dotGitDirectory>${project.basedir}/../.git</dotGitDirectory>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<includeOnlyProperties>
<includeOnlyProperty>^git.commit.id.abbrev$</includeOnlyProperty>
<includeOnlyProperty>^git.commit.message.short$</includeOnlyProperty>
<includeOnlyProperty>^git.branch$</includeOnlyProperty>
<includeOnlyProperty>^git.build.version$</includeOnlyProperty>
</includeOnlyProperties>
<gitDescribe>
<skip>true</skip>
</gitDescribe>
</configuration>
</plugin>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
Expand Down Expand Up @@ -112,6 +115,53 @@
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>detect</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>native-image-maven-plugin</artifactId>
<version>${graalvm.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<skip>false</skip>
<imageName>lemminx-${os.detected.classifier}-${project.version}</imageName>
<buildArgs>
--no-fallback
-H:EnableURLProtocols=https,http
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>generate-p2</id>
<build>
Expand Down Expand Up @@ -204,5 +254,4 @@
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
Expand All @@ -27,7 +27,7 @@

/**
* GSON deserializer to build Snippet from vscode JSON snippet.
*
*
* @author Angelo ZERR
*
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/**
* XSD documentation
*
*
* Represents documentation coming from an XML schema file
*/
public class XSDDocumentation {
Expand All @@ -38,10 +38,12 @@ public XSDDocumentation(XSObjectList annotations, SchemaDocumentationType docStr
this(annotations, null, docStrategy, convertToPlainText);
}

public XSDDocumentation(XSObjectList annotations, String value, SchemaDocumentationType docStrategy, boolean convertToPlainText) {
public XSDDocumentation(XSObjectList annotations, String value, SchemaDocumentationType docStrategy,
boolean convertToPlainText) {
List<String> documentation = Collections.emptyList();
List<String> appinfo = Collections.emptyList();
switch(docStrategy) {

switch (docStrategy) {
case all: {
documentation = XSDAnnotationModel.getDocumentation(annotations, value);
appinfo = XSDAnnotationModel.getAppInfo(annotations, value);
Expand All @@ -55,14 +57,14 @@ public XSDDocumentation(XSObjectList annotations, String value, SchemaDocumentat
appinfo = XSDAnnotationModel.getAppInfo(annotations, value);
break;
}
case none:{
case none: {
break;
}
}

if (convertToPlainText) {
// convert content to plain text

// if the content contains html tags, converting to plaintext
// will remove them
convertToPlainText(documentation);
Expand All @@ -74,19 +76,17 @@ public XSDDocumentation(XSObjectList annotations, String value, SchemaDocumentat
this.strategy = docStrategy;
this.prefix = XSDAnnotationModel.getPrefix(annotations, value);
}

/**
* Returns formatted documentation that displays
* contents of the documentation element (if exists) and the appinfo
* element (if exists).
*
* The returned documentation will return raw html if
* <code>html</code> is true. Otherwise, the returned documentation
* will be plaintext.
*
* Returns formatted documentation that displays contents of the documentation
* element (if exists) and the appinfo element (if exists).
*
* The returned documentation will return raw html if <code>html</code> is true.
* Otherwise, the returned documentation will be plaintext.
*
* @param html if true, the return value will contain raw html
* @return formatted documentation that displays
* contents of the documentation element (if exists) and the appinfo
* element (if exists)
* @return formatted documentation that displays contents of the documentation
* element (if exists) and the appinfo element (if exists)
*/
public String getFormattedDocumentation(boolean html) {
StringBuilder result = new StringBuilder();
Expand All @@ -97,15 +97,14 @@ public String getFormattedDocumentation(boolean html) {
}

/**
* Returns true if documentation title (ie, xs:documentation, xs:appinfo)
* should be preprended to the documentation
*
* @return true if documentation title (ie, xs:documentation, xs:appinfo)
* should be preprended to the documentation
* Returns true if documentation title (ie, xs:documentation, xs:appinfo) should
* be preprended to the documentation
*
* @return true if documentation title (ie, xs:documentation, xs:appinfo) should
* be preprended to the documentation
*/
private boolean prependTitleCheck() {
return this.documentation.size() > 0 && this.appinfo.size() > 0
&& strategy == SchemaDocumentationType.all;
return this.documentation.size() > 0 && this.appinfo.size() > 0 && strategy == SchemaDocumentationType.all;
}

private static void convertToPlainText(List<String> list) {
Expand All @@ -116,13 +115,13 @@ private static void convertToPlainText(List<String> list) {
}
}

private static String getFormatted(String prefix, String elementName, List<String> content,
boolean prependTitles, boolean html) {
private static String getFormatted(String prefix, String elementName, List<String> content, boolean prependTitles,
boolean html) {
StringBuilder result = new StringBuilder();
if (prependTitles) {
result.append(applyPrefix(prefix, elementName, html));
}
for (String doc: content) {
for (String doc : content) {
if (!StringUtils.isBlank(doc)) {
if (html) {
result.append("<p>");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
*
*/
public class XMLPreferences {

public static final QuoteStyle DEFAULT_QUOTE_STYLE = QuoteStyle.doubleQuotes;

public static final SchemaDocumentationType DEFAULT_SCHEMA_DOCUMENTATION_TYPE = SchemaDocumentationType.all;

private QuoteStyle quoteStyle;
Expand All @@ -32,9 +32,9 @@ public XMLPreferences() {

/**
* Returns the actual quotation value as a char.
*
*
* Either a {@code '} or {@code "}.
*
*
* Defaults to {@code "}.
*/
public char getQuotationAsChar() {
Expand All @@ -44,9 +44,9 @@ public char getQuotationAsChar() {

/**
* Returns the actual quotation value as a String.
*
*
* Either a {@code '} or {@code "}.
*
*
* Defaults to {@code "}.
*/
public String getQuotationAsString() {
Expand All @@ -55,7 +55,7 @@ public String getQuotationAsString() {

/**
* Sets the quote style
*
*
* @param quoteStyle
*/
public void setQuoteStyle(QuoteStyle quoteStyle) {
Expand All @@ -64,7 +64,7 @@ public void setQuoteStyle(QuoteStyle quoteStyle) {

/**
* Returns the quote style
*
*
* @return
*/
public QuoteStyle getQuoteStyle() {
Expand All @@ -80,7 +80,7 @@ public SchemaDocumentationType getShowSchemaDocumentationType() {

/**
* Sets the showSchemaDocumentationType
*
*
* @param showSchemaDocumentationType
*/
public void setShowSchemaDocumentationType(SchemaDocumentationType showSchemaDocumentationType) {
Expand All @@ -90,7 +90,7 @@ public void setShowSchemaDocumentationType(SchemaDocumentationType showSchemaDoc
/**
* Merges the contents of <code>newPreferences</code> to the current
* <code>XMLPreferences</code> instance
*
*
* @param newPreferences
*/
public void merge(XMLPreferences newPreferences) {
Expand Down
4 changes: 4 additions & 0 deletions org.eclipse.lemminx/src/main/resources/META-INF/extra.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name":"org.eclipse.lemminx.services.extensions.IXMLExtension",
"allDeclaredMethods":true
},
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
["org.eclipse.lemminx.customservice.XMLLanguageClientAPI","org.eclipse.lsp4j.jsonrpc.Endpoint"]
]
Loading

0 comments on commit 182cbd8

Please sign in to comment.