usethesource / rascal-language-servers

An LSP server for Rascal which includes an easy-to-use LSP generator for languages implemented in Rascal, and an interactive terminal REPL.
BSD 2-Clause "Simplified" License
14 stars 8 forks source link

Implement cross-project linking in VSCode for project with Java code #111

Open rodinaarssen opened 2 years ago

rodinaarssen commented 2 years ago

As the Java classpath is fixed at JVM startup time, Java classes need to be loaded using other classloaders.

jurgenvinju commented 2 years ago

This is a duplicate of #109 ;-)

jurgenvinju commented 2 years ago

Or an extension of #109; because there we did not talk about Java classes but rather about Rascal source files.

jurgenvinju commented 2 years ago

For this to work for both source project and deployed extensions, we also need to solve #110

rodinaarssen commented 2 years ago

Ah, that's what you get from not submitting immediately.

How about Java classes in jar files?

jurgenvinju commented 2 years ago

I think #109 and #110 should both resolve this somehow. The classpath variable of PathConfig needs similar treatment. For example, if plugin://<libName> points to the root of the class files then lib://<libName> is enough to add to the classpath of PathConfig to fix this.

jurgenvinju commented 2 years ago

and classpath is used by the Evaluator in rascal-lsp to recreate ClassLoader instances from these source locations which are then used by JavaBridge to load the injected class files.

O yes, that also means that plugin:// must also implement IClassLoaderLocationResolver (or something in that vain). That way you can hide where exactly in a plugin's private filesystem location the .class files are stored, without having to adapt the plugin://<libName> URI.

jurgenvinju commented 2 years ago

And that's why it is so good that every registered language has its own Evaluator, because all this stuff is bound at Evaluator instance-creation-time.

And that's why if you change dependencies mid-flight, it's ok after you call registerLanguage again because that will trigger the loading of a new Evaluator (MUST CHECK)

jurgenvinju commented 2 years ago

und und und, ein Katz ist kein Hund

jurgenvinju commented 2 years ago
public interface IClassloaderLocationResolver {
    /**
     * @return the scheme this resolver supports
     */
    String scheme();

    /**
     * Produce a classloader for the given location.
     * 
     * @param  loc a location with loc.getScheme().equals(this.getScheme())
     * @param  parent Classloader to defer to when a needed class is not provided directly by the returned classloader
     * 
     * @return a classloader corresponding to the given loc, with parent classloader `parent` and never null.
     * @throws IOException when the location can not be resolved even though the scheme matches, 
     *         or something else goes wrong while loading the classloader itself.
     */
    ClassLoader getClassLoader(ISourceLocation loc, ClassLoader  parent) throws IOException;
}

Yes, I believe implementing this interface for the new plugin:// scheme of #110 should automatically fix #111, but only if we also fix #109 (because otherwise it only works for level 2 VScode instances and we want LSPs to work in level1)

DavyLandman commented 2 years ago

I think this works after some recent changes, right @jurgenvinju and @rodinaarssen ?

jurgenvinju commented 2 years ago

no there is a list of TODO's to make this work properly.

DavyLandman commented 2 years ago

okay, well at least it has improved since opening this issue, so that's progress.

jurgenvinju commented 2 years ago

definitely. to finalize this we need to come up with a design for #110, or we have to find another way how to discover and inject jar files from third-party rascal extensions into the classpath of a current project or a current extension. This is related to some of the functionality we got from OSGI in Eclipse when we used Bundle-Require between Rascal projects.

aukeroorda commented 2 years ago

Hi - I'm commenting here since I think this issue is the same as what I am running into. In short, is there any update on this?

I have a DSL which uses functionality that is provided via Java bindings. However, when adding these Java bindings, the language cannot be successfully registered anymore, as it results in an exception where it cannot link the method, because the class is not found. The stacktrace of this exception can be seen near the end of the logs:

Language Parametric Rascal Language Server output ```rascal 2022-05-04 13:34:35,703 main DEBUG null 2.1.1-SNAPSHOT initializing configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@198b6731 2022-05-04 13:34:35,720 main DEBUG Installed 1 script engine 2022-05-04 13:34:35,920 main DEBUG Attempting to use org.apache.logging.log4j.jul.CoreLoggerAdapter 2022-05-04 13:34:35,924 main INFO Registered Log4j as the java.util.logging.LogManager. WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance. Warning: Nashorn engine is planned to be removed from a future JDK release 2022-05-04 13:34:36,359 main DEBUG Oracle Nashorn version: 11.0.14.1, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory 2022-05-04 13:34:36,360 main DEBUG PluginManager 'Core' found 127 plugins 2022-05-04 13:34:36,360 main DEBUG PluginManager 'Level' found 0 plugins 2022-05-04 13:34:36,364 main DEBUG PluginManager 'Lookup' found 16 plugins 2022-05-04 13:34:36,367 main DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. 2022-05-04 13:34:36,383 main DEBUG PluginManager 'TypeConverter' found 26 plugins 2022-05-04 13:34:36,394 main DEBUG createAppenderRef(ref="Console", level="null", Filter=null) 2022-05-04 13:34:36,394 main DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger]. 2022-05-04 13:34:36,398 main DEBUG createLogger(additivity="null", level="DEBUG", includeLocation="null", ={Console}, ={}, Configuration(DefaultLogger), Filter=null) 2022-05-04 13:34:36,399 main DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin]. 2022-05-04 13:34:36,400 main DEBUG createLoggers(={root}) 2022-05-04 13:34:36,402 main DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout]. 2022-05-04 13:34:36,408 main DEBUG PatternLayout$Builder(pattern="%d [%t] %p - %c %m%n", PatternSelector=null, Configuration(DefaultLogger), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null") 2022-05-04 13:34:36,408 main DEBUG PluginManager 'Converter' found 45 plugins 2022-05-04 13:34:36,416 main DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender]. 2022-05-04 13:34:36,421 main DEBUG ConsoleAppender$Builder(target="SYSTEM_ERR", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d [%t] %p - %c %m%n), name="Console", Configuration(DefaultLogger), Filter=null, ={}) 2022-05-04 13:34:36,423 main DEBUG Starting OutputStreamManager SYSTEM_ERR.false.false 2022-05-04 13:34:36,424 main DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin]. 2022-05-04 13:34:36,425 main DEBUG createAppenders(={Console}) 2022-05-04 13:34:36,425 main DEBUG Configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@198b6731 initialized 2022-05-04 13:34:41,433 main DEBUG Starting configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@198b6731 2022-05-04 13:34:41,434 main DEBUG Started configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@198b6731 OK. 2022-05-04 13:34:41,435 main DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false-1 2022-05-04 13:34:41,435 main DEBUG OutputStream closed 2022-05-04 13:34:41,435 main DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false-1, all resources released: true 2022-05-04 13:34:41,435 main DEBUG Appender DefaultConsole-1 stopped with status true 2022-05-04 13:34:41,436 main DEBUG Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@1f021e6c OK 2022-05-04 13:34:41,498 main DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc 2022-05-04 13:34:41,500 main DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=StatusLogger 2022-05-04 13:34:41,502 main DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=ContextSelector 2022-05-04 13:34:41,503 main DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Loggers,name= 2022-05-04 13:34:41,505 main DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Appenders,name=Console 2022-05-04 13:34:41,507 main DEBUG org.apache.logging.log4j.core.util.SystemClock does not support precise timestamps. 2022-05-04 13:34:41,509 main DEBUG Reconfiguration complete for context[name=277050dc] at URI NULL_SOURCE (org.apache.logging.log4j.core.LoggerContext@76c3e77a) with optional ClassLoader: null 2022-05-04 13:34:41,509 main DEBUG Shutdown hook enabled. Registering a new one. 2022-05-04 13:34:41,510 main DEBUG LoggerContext[name=277050dc, org.apache.logging.log4j.core.LoggerContext@76c3e77a] started OK. 2022-05-04 13:34:41,519 [main] INFO - org.rascalmpl.vscode.lsp.BaseLanguageServer Starting Rascal Language Server: 2.1.1-SNAPSHOT at ${maven.build.timestamp} INFO: detected |lib://rascal-lsp| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal-lsp.jar!/| INFO: detected |lib://rascal| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal.jar!/| INFO: detected |lib://rascal-core| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal-core.jar!/| INFO: detected |lib://typepal| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/typepal.jar!/| 2022-05-04 13:34:41,843 [pool-3-thread-1] INFO - org.rascalmpl.vscode.lsp.BaseLanguageServer.ActualLanguageServer LSP connection started 2022-05-04 13:34:41,858 [pool-3-thread-1] DEBUG - org.rascalmpl.vscode.lsp.BaseLanguageServer.ActualLanguageServer Initialized LSP connection with capabilities: InitializeResult [ capabilities = ServerCapabilities [ textDocumentSync = Either [ left = Full right = null ] hoverProvider = Either [ left = true right = null ] completionProvider = null signatureHelpProvider = null definitionProvider = Either [ left = true right = null ] typeDefinitionProvider = null implementationProvider = Either [ left = true right = null ] referencesProvider = Either [ left = true right = null ] documentHighlightProvider = null documentSymbolProvider = Either [ left = true right = null ] workspaceSymbolProvider = null codeActionProvider = null codeLensProvider = CodeLensOptions [ resolveProvider = false workDoneProgress = null ] documentFormattingProvider = null documentRangeFormattingProvider = null documentOnTypeFormattingProvider = null renameProvider = null documentLinkProvider = null colorProvider = null foldingRangeProvider = Either [ left = true right = null ] declarationProvider = null executeCommandProvider = ExecuteCommandOptions [ commands = SingletonList ( "rascal-meta-command" ) workDoneProgress = null ] workspace = WorkspaceServerCapabilities [ workspaceFolders = WorkspaceFoldersOptions [ supported = true changeNotifications = Either [ left = null right = true ] ] fileOperations = null ] typeHierarchyProvider = null callHierarchyProvider = null selectionRangeProvider = null linkedEditingRangeProvider = null semanticTokensProvider = SemanticTokensWithRegistrationOptions [ legend = SemanticTokensLegend [ tokenTypes = ArrayList ( "entity.name", "entity.other.inherited-class", "entity.name.section", "entity.name.tag", "entity.other.attribute-name", "variable", "variable.language", "variable.parameter", "variable.function", "constant", "constant.numeric", "constant.language", "constant.character.escape", "storage.type", "storage.modifier", "support", "keyword", "keyword.control", "keyword.operator", "keyword.declaration", "string", "comment", "invalid", "invalid.deprecated", "comment.block.documentation", "comment.block", "comment.single", "comment", "constant.character.escape", "constant.language", "constant.numeric.complex.imaginary", "constant.numeric.complex.real", "constant.numeric.complex", "constant.numeric.float.binary", "constant.numeric.float.decimal", "constant.numeric.float.hexadecimal", "constant.numeric.float.octal", "constant.numeric.float.other", "constant.numeric.float", "constant.numeric.integer.binary", "constant.numeric.integer.decimal", "constant.numeric.integer.hexadecimal", "constant.numeric.integer.octal", "constant.numeric.integer.other", "constant.numeric.integer", "constant.numeric", "constant.other.placeholder", "constant.other", "constant", "entity.name.class.forward-decl", "entity.name.class", "entity.name.constant", "entity.name.enum", "entity.name.function.constructor", "entity.name.function.destructor", "entity.name.function", "entity.name.impl", "entity.name.interface", "entity.name.label", "entity.name.namespace", "entity.name.section", "entity.name.struct", "entity.name.tag", "entity.name.trait", "entity.name.type", "entity.name.union", "entity.name", "entity.other.attribute-name", "entity.other.inherited-class", "entity", "invalid.deprecated", "invalid.illegal", "invalid", "keyword.control.conditional", "keyword.control.import", "keyword.control", "keyword.declaration.class", "keyword.declaration.enum", "keyword.declaration.function", "keyword.declaration.impl", "keyword.declaration.interface", "keyword.declaration.struct", "keyword.declaration.trait", "keyword.declaration.type", "keyword.declaration.union", "keyword.declaration", "keyword.operator.arithmetic", "keyword.operator.assignment", "keyword.operator.bitwise", "keyword.operator.logical", "keyword.operator.word", "keyword.operator", "keyword.other", "keyword", "markup.bold", "markup.deleted", "markup.heading", "markup.inserted", "markup.italic", "markup.list.numbered", "markup.list.unnumbered", "markup.other", "markup.quote", "markup.raw.block", "markup.raw.inline", "markup.underline.link", "markup.underline", "markup", "meta.annotation.identifier", "meta.annotation.parameters", "meta.annotation", "meta.block", "meta.braces", "meta.brackets", "meta.class", "meta.enum", "meta.function-call", "meta.function.parameters", "meta.function.return-type", "meta.function", "meta.group", "meta.impl", "meta.interface", "meta.interpolation", "meta.namespace", "meta.paragraph", "meta.parens", "meta.path", "meta.preprocessor", "meta.string", "meta.struct", "meta.tag", "meta.toc-list", "meta.trait", "meta.type", "meta.union", "meta", "punctuation.accessor", "punctuation.definition.annotation", "punctuation.definition.comment", "punctuation.definition.keyword", "punctuation.definition.string.begin", "punctuation.definition.string.end", "punctuation.definition.variable", "punctuation.section.block.begin", "punctuation.section.block.end", "punctuation.section.braces.begin", "punctuation.section.braces.end", "punctuation.section.brackets.begin", "punctuation.section.brackets.end", "punctuation.section.group.begin", "punctuation.section.group.end", "punctuation.section.interpolation.begin", "punctuation.section.interpolation.end", "punctuation.section.parens.begin", "punctuation.section.parens.end", "punctuation.separator.continuation", "punctuation.separator", "punctuation.terminator", "source", "storage.modifier", "storage.type.class", "storage.type.enum", "storage.type.function", "storage.type.impl", "storage.type.interface", "storage.type.struct", "storage.type.trait", "storage.type.union", "storage.type", "storage.type", "string.quoted.double", "string.quoted.other", "string.quoted.single", "string.quoted.triple", "string.regexp", "string.unquoted", "string", "support.class", "support.constant", "support.function", "support.module", "support.type", "text.html", "text.xml", "text", "variable.annotation", "variable.function", "variable.language", "variable.other.constant", "variable.other.member", "variable.other.readwrite", "variable.other", "variable.parameter" ) tokenModifiers = EmptyList () ] range = null full = Either [ left = true right = null ] documentSelector = null id = null workDoneProgress = null ] monikerProvider = null experimental = null ] serverInfo = null ] 2022-05-04 13:34:41,969 pool-2-thread-1 DEBUG Not in a ServletContext environment, thus not loading WebLookup plugin. 2022-05-04 13:34:41,972 pool-2-thread-1 DEBUG PluginManager 'Converter' found 45 plugins 2022-05-04 13:34:41,973 pool-2-thread-1 DEBUG Starting OutputStreamManager SYSTEM_OUT.false.false-2 2022-05-04 13:34:41,973 pool-2-thread-1 DEBUG Starting LoggerContext[name=Default, org.apache.logging.log4j.core.LoggerContext@b07f5c3]... 2022-05-04 13:34:41,974 pool-2-thread-1 DEBUG Reconfiguration started for context[name=Default] at URI null (org.apache.logging.log4j.core.LoggerContext@b07f5c3) with optional ClassLoader: null 2022-05-04 13:34:41,974 pool-2-thread-1 DEBUG Using configurationFactory org.apache.logging.log4j.core.config.ConfigurationFactory$Factory@3f3668e6 2022-05-04 13:34:41,973 Thread Context Data Task DEBUG Initializing Thread Context Data Service Providers 2022-05-04 13:34:41,974 pool-2-thread-1 DEBUG Not in a ServletContext environment, thus not loading WebLookup plugin. 2022-05-04 13:34:41,974 Thread Context Data Task DEBUG Thread Context Data Service Provider initialization complete 2022-05-04 13:34:41,975 pool-2-thread-1 DEBUG null 2.1.1-SNAPSHOT initializing configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@7329a0f1 2022-05-04 13:34:41,976 pool-2-thread-1 DEBUG Installed 1 script engine Warning: Nashorn engine is planned to be removed from a future JDK release 2022-05-04 13:34:42,004 pool-2-thread-1 DEBUG Oracle Nashorn version: 11.0.14.1, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory 2022-05-04 13:34:42,005 pool-2-thread-1 DEBUG PluginManager 'Core' found 127 plugins 2022-05-04 13:34:42,005 pool-2-thread-1 DEBUG PluginManager 'Level' found 0 plugins 2022-05-04 13:34:42,005 pool-2-thread-1 DEBUG PluginManager 'Lookup' found 16 plugins 2022-05-04 13:34:42,006 pool-2-thread-1 DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. 2022-05-04 13:34:42,006 pool-2-thread-1 DEBUG createAppenderRef(ref="Console", level="null", Filter=null) 2022-05-04 13:34:42,007 pool-2-thread-1 DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger]. 2022-05-04 13:34:42,007 pool-2-thread-1 DEBUG createLogger(additivity="null", level="DEBUG", includeLocation="null", ={Console}, ={}, Configuration(DefaultLogger), Filter=null) 2022-05-04 13:34:42,008 pool-2-thread-1 DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin]. 2022-05-04 13:34:42,009 pool-2-thread-1 DEBUG createLoggers(={root}) 2022-05-04 13:34:42,009 pool-2-thread-1 DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout]. 2022-05-04 13:34:42,010 pool-2-thread-1 DEBUG PatternLayout$Builder(pattern="%d [%t] %p - %c %m%n", PatternSelector=null, Configuration(DefaultLogger), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null") 2022-05-04 13:34:42,011 pool-2-thread-1 DEBUG PluginManager 'Converter' found 45 plugins 2022-05-04 13:34:42,011 pool-2-thread-1 DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender]. 2022-05-04 13:34:42,012 pool-2-thread-1 DEBUG ConsoleAppender$Builder(target="SYSTEM_ERR", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d [%t] %p - %c %m%n), name="Console", Configuration(DefaultLogger), Filter=null, ={}) 2022-05-04 13:34:42,014 pool-2-thread-1 DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin]. 2022-05-04 13:34:42,014 pool-2-thread-1 DEBUG createAppenders(={Console}) 2022-05-04 13:34:42,015 pool-2-thread-1 DEBUG Configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@7329a0f1 initialized 2022-05-04 13:34:42,015 pool-2-thread-1 DEBUG Starting configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@7329a0f1 2022-05-04 13:34:42,015 pool-2-thread-1 DEBUG Started configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration@7329a0f1 OK. 2022-05-04 13:34:42,016 pool-2-thread-1 DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false-2 2022-05-04 13:34:42,016 pool-2-thread-1 DEBUG OutputStream closed 2022-05-04 13:34:42,016 pool-2-thread-1 DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false-2, all resources released: true 2022-05-04 13:34:42,016 pool-2-thread-1 DEBUG Appender DefaultConsole-2 stopped with status true 2022-05-04 13:34:42,017 pool-2-thread-1 DEBUG Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@ef26377 OK 2022-05-04 13:34:42,018 pool-2-thread-1 DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc 2022-05-04 13:34:42,019 pool-2-thread-1 DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=StatusLogger 2022-05-04 13:34:42,020 pool-2-thread-1 DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=ContextSelector 2022-05-04 13:34:42,021 pool-2-thread-1 DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Loggers,name= 2022-05-04 13:34:42,021 pool-2-thread-1 DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Appenders,name=Console 2022-05-04 13:34:42,022 pool-2-thread-1 DEBUG Reconfiguration complete for context[name=Default] at URI NULL_SOURCE (org.apache.logging.log4j.core.LoggerContext@b07f5c3) with optional ClassLoader: null 2022-05-04 13:34:42,022 pool-2-thread-1 DEBUG Shutdown hook enabled. Registering a new one. 2022-05-04 13:34:42,022 pool-2-thread-1 DEBUG LoggerContext[name=Default, org.apache.logging.log4j.core.LoggerContext@b07f5c3] started OK. 2022-05-04 13:34:42,031 [pool-2-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Creating new progress bar: T3f2c86c8151b291ba0 Loading evaluator for StateMachineLanguage [] 2022-05-04 13:34:42,036 [pool-3-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Valid initialized progress bar: T3f2c86c8151b291ba0 INFO: resolved |lib://typepal| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/typepal.jar!/| INFO: resolved |lib://rascal-core| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal-core.jar!/| INFO: resolved |lib://rascal-lsp| at |jar+file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal-lsp.jar!/| 2022-05-04 13:34:45,938 [pool-2-thread-1] WARN - Evaluator: evaluator for StateMachineLanguage |project://my-app/src/CorelLanguageServer.rsc|(43,26,<4,0>,<4,26>) : Could not load RascalJavaBindings due to: Cannot link method com.mycompany.app.App because: class not found at |project://my-app/src/CorelLanguageServer.rsc|(43,26,<4,0>,<4,26>) org.rascalmpl.exceptions.JavaMethodLink: Cannot link method com.mycompany.app.App because: class not found at org.rascalmpl.interpreter.utils.JavaBridge.getJavaClassInstance(JavaBridge.java:432) at org.rascalmpl.interpreter.result.JavaMethod.(JavaMethod.java:95) at org.rascalmpl.interpreter.result.JavaMethod.(JavaMethod.java:52) at org.rascalmpl.semantics.dynamic.FunctionDeclaration$Abstract.interpret(FunctionDeclaration.java:61) at org.rascalmpl.semantics.dynamic.Declaration$Function.interpret(Declaration.java:117) at org.rascalmpl.semantics.dynamic.Toplevel$GivenVisibility.interpret(Toplevel.java:35) at org.rascalmpl.semantics.dynamic.Module$Default.interpret(Module.java:79) at org.rascalmpl.semantics.dynamic.Import.loadModule(Import.java:319) at org.rascalmpl.semantics.dynamic.Import.importModule(Import.java:240) at org.rascalmpl.semantics.dynamic.Import$Default.interpret(Import.java:206) at org.rascalmpl.semantics.dynamic.Import.evalImport(Import.java:477) at org.rascalmpl.semantics.dynamic.Import.parseModuleAndFragments(Import.java:442) at org.rascalmpl.interpreter.Evaluator.parseModuleAndFragments(Evaluator.java:1416) at org.rascalmpl.interpreter.Evaluator.parseModuleAndFragments(Evaluator.java:1410) at org.rascalmpl.semantics.dynamic.Import.buildModule(Import.java:378) at org.rascalmpl.semantics.dynamic.Import.loadModule(Import.java:306) at org.rascalmpl.semantics.dynamic.Import.importModule(Import.java:240) at org.rascalmpl.interpreter.Evaluator.doImport(Evaluator.java:1144) at org.rascalmpl.vscode.lsp.util.EvaluatorUtil.lambda$makeFutureEvaluator$2(EvaluatorUtil.java:138) at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) 2022-05-04 13:34:45,959 [pool-2-thread-1] WARN - Evaluator: evaluator for StateMachineLanguage |project://my-app/src/CorelLanguageServer.rsc|(43,26,<4,0>,<4,26>) : Could not import module RascalJavaBindings: Cannot link method com.mycompany.app.App because: class not found Advice: |http://tutor.rascal-mpl.org/Errors/Static/ModuleImport/ModuleImport.html| 2022-05-04 13:34:55,551 [pool-2-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Finishing progress bar: T3f2c86c8151b291ba0 - Loading evaluator for StateMachineLanguage 2022-05-04 13:34:55,553 [pool-2-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Finished progress bar: T3f2c86c8151b291ba0 - Loading evaluator for StateMachineLanguage 2022-05-04 13:34:55,571 [pool-2-thread-2] INFO - Evaluator: evaluator for StateMachineLanguage Creating new progress bar: T73700d5a177db7fd44 StateMachineLanguage: StateMachineLanguage: loading contributions [] 2022-05-04 13:34:55,572 [pool-3-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Valid initialized progress bar: T73700d5a177db7fd44 2022-05-04 13:34:55,579 [pool-2-thread-2] INFO - Evaluator: evaluator for StateMachineLanguage Finishing progress bar: T73700d5a177db7fd44 - StateMachineLanguage: StateMachineLanguage: loading contributions 2022-05-04 13:34:55,579 [pool-2-thread-2] INFO - Evaluator: evaluator for StateMachineLanguage Finished progress bar: T73700d5a177db7fd44 - StateMachineLanguage: StateMachineLanguage: loading contributions ```
getProjectPathConfig ```rascal rascal>getProjectPathConfig(|project://my-app/|); PathConfig: pathConfig( javaCompilerPath=[ |file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal-lsp.jar|, |file:///Users/auke/.vscode/extensions/usethesource.rascalmpl-0.2.1/assets/jars/rascal.jar|, |file:///Users/auke/.m2/repository/frinklang/frink/22.4.18/frink-22.4.18.jar| ], bin=|target://my-app|, classloaders=[ |lib://rascal-lsp|, |file:///Users/auke/.m2/repository/frinklang/frink/22.4.18/frink-22.4.18.jar|, |target://my-app|, |system:///| ], libs=[ |lib://rascal|, |lib://rascal-lsp|, |file:///Users/auke/.m2/repository/frinklang/frink/22.4.18/frink-22.4.18.jar| ], srcs=[|project://my-app/src|], courses=[]) ```

To me, it looks familiar to an issue I had earlier (#156), but I don't see how I can apply the same solution here.

jurgenvinju commented 2 years ago

@aukeroorda you are right; this is a similar issue, but now the code is running in a different JVM instance. With #156 we were running a JVM instance per terminal, but registered languages are loaded all in the same "LSP multiplexer" JVM instance, the "Parameterized LSP".

@DavyLandman @rodinaarssen the question is why the classpath as listed in pathConfig.classloaders is not used by the JavaBridge that is used by the Evaluator that is constructed for the registered DSL.

I don't have time today, but that is where our fix should focus on. I really don't want to start a JVM instance for every language; so please don't consider that as a solution.

jurgenvinju commented 2 years ago

@rodinaarssen @DavyLandman I'm not clear on the status of this functionality. Is this still broken or did you fix it while doing other fixes?

DavyLandman commented 2 years ago

Sorry, we have not fixed this yet, as we are not currently running into this (pure rascal all the way ;) )

But we have run into this in the past.

jurgenvinju commented 2 years ago

ok then I'll put in on my agenda

aukeroorda commented 2 years ago

Hi - Thanks for looking into this again!

I wanted to provide you with the repository I use to test this, but first I did a validation run myself. Here I noticed multiple things:

  1. There are new rainbow brackets in VScode
  2. Somehow, the Language Parametric Rascal Language Server did not crash, even with the Java bindings in use?

This second part took my by surprise, as it seemed like the issue was silently fixed! However, this prompted me to look into where and how I use the java bindings. They were used in the picoSummarizer section of the language server, but the resulting values of the java calls where never used and, I assume, therefore optimized away. I updated my test language to actually use the value in a different section picoHinter of the language server, and now it crashes again. I moved it to the picoHinter section since I can observe the output of this directly in the editor when opening a demo.pico file.

Reproduction

Therefore I would like to provide the reproduction steps for this, as well as the somewhat minimal example repository. The repository is available at this skeleton repo on the java-bindings-in-language-server branch. To clone this branch directly:

git clone -b java-bindings-in-language-server https://github.com/aukeroorda/rascal-lsp-skeletons.git

Steps:

  1. Navigate to the rascal-lsp-skeletons/my-appdirectory:
    cd rascal-lsp-skeletons/my-app
  2. Let maven do its thing:
    mvn verify
  3. Open the project in VScode:
    code .
  4. Open the file CorelLanguageServer.rsc, and click Run in new Rascal terminal above the main() function
  5. Navigate to the output tab and select Language Parametric Rascal Language Server in the dropdown to view the error in the logs:
    Language Parametric Rascal Language Server log
2022-06-02 12:49:23,372 [pool-2-thread-36] INFO - Evaluator: evaluator for StateMachineLanguage Creating new progress bar: T22cdd9ff382c0a23d6 Loading evaluator for StateMachineLanguage []
2022-06-02 12:49:23,380 [pool-3-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Valid initialized progress bar: T22cdd9ff382c0a23d6
2022-06-02 12:49:26,031 [pool-2-thread-36] WARN - Evaluator: evaluator for StateMachineLanguage |project://my-app/src/CorelLanguageServer.rsc|(43,26,<4,0>,<4,26>) : Could not load RascalJavaBindings due to: Cannot link method com.mycompany.app.App because: class not found at |project://my-app/src/CorelLanguageServer.rsc|(43,26,<4,0>,<4,26>)
org.rascalmpl.exceptions.JavaMethodLink: Cannot link method com.mycompany.app.App because: class not found
    at org.rascalmpl.interpreter.utils.JavaBridge.getJavaClassInstance(JavaBridge.java:432)
    at org.rascalmpl.interpreter.result.JavaMethod.<init>(JavaMethod.java:95)
    at org.rascalmpl.interpreter.result.JavaMethod.<init>(JavaMethod.java:52)
    at org.rascalmpl.semantics.dynamic.FunctionDeclaration$Abstract.interpret(FunctionDeclaration.java:61)
    at org.rascalmpl.semantics.dynamic.Declaration$Function.interpret(Declaration.java:117)
    at org.rascalmpl.semantics.dynamic.Toplevel$GivenVisibility.interpret(Toplevel.java:35)
    at org.rascalmpl.semantics.dynamic.Module$Default.interpret(Module.java:79)
    at org.rascalmpl.semantics.dynamic.Import.loadModule(Import.java:319)
    at org.rascalmpl.semantics.dynamic.Import.importModule(Import.java:240)
    at org.rascalmpl.semantics.dynamic.Import$Default.interpret(Import.java:206)
    at org.rascalmpl.semantics.dynamic.Import.evalImport(Import.java:477)
    at org.rascalmpl.semantics.dynamic.Import.parseModuleAndFragments(Import.java:442)
    at org.rascalmpl.interpreter.Evaluator.parseModuleAndFragments(Evaluator.java:1416)
    at org.rascalmpl.interpreter.Evaluator.parseModuleAndFragments(Evaluator.java:1410)
    at org.rascalmpl.semantics.dynamic.Import.buildModule(Import.java:378)
    at org.rascalmpl.semantics.dynamic.Import.loadModule(Import.java:306)
    at org.rascalmpl.semantics.dynamic.Import.importModule(Import.java:240)
    at org.rascalmpl.interpreter.Evaluator.doImport(Evaluator.java:1144)
    at org.rascalmpl.vscode.lsp.util.EvaluatorUtil.lambda$makeFutureEvaluator$2(EvaluatorUtil.java:138)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
2022-06-02 12:49:26,032 [pool-2-thread-36] WARN - Evaluator: evaluator for StateMachineLanguage |project://my-app/src/CorelLanguageServer.rsc|(43,26,<4,0>,<4,26>) : Could not import module RascalJavaBindings: Cannot link method com.mycompany.app.App because: class not found
Advice: |http://tutor.rascal-mpl.org/Errors/Static/ModuleImport/ModuleImport.html|
2022-06-02 12:49:29,814 [pool-2-thread-36] INFO - Evaluator: evaluator for StateMachineLanguage Finishing progress bar: T22cdd9ff382c0a23d6 - Loading evaluator for StateMachineLanguage
2022-06-02 12:49:29,815 [pool-2-thread-36] INFO - Evaluator: evaluator for StateMachineLanguage Finished progress bar: T22cdd9ff382c0a23d6 - Loading evaluator for StateMachineLanguage
2022-06-02 12:49:29,816 [pool-2-thread-37] INFO - Evaluator: evaluator for StateMachineLanguage Creating new progress bar: T396db75c3937aa5e01 StateMachineLanguage: StateMachineLanguage: loading contributions []
2022-06-02 12:49:29,817 [pool-3-thread-1] INFO - Evaluator: evaluator for StateMachineLanguage Valid initialized progress bar: T396db75c3937aa5e01
2022-06-02 12:49:29,818 [pool-2-thread-37] INFO - Evaluator: evaluator for StateMachineLanguage Finishing progress bar: T396db75c3937aa5e01 - StateMachineLanguage: StateMachineLanguage: loading contributions
2022-06-02 12:49:29,818 [pool-2-thread-37] INFO - Evaluator: evaluator for StateMachineLanguage Finished progress bar: T396db75c3937aa5e01 - StateMachineLanguage: StateMachineLanguage: loading contributions

jurgenvinju commented 2 years ago

Ok thanks! This is very helpful @aukeroorda

jurgenvinju commented 2 years ago

I believe that the above is caused by the brittleness of the target folder. In several cases, I have observed the situation where .class files are moved by VScode calling the mvn clean command (I guess), and then mvn compile again but perhaps too late for an LSP instance or a terminal to load the classes.

The "workaround" is to type mvn compile in the project before registerLanguage or before starting a terminal.

jurgenvinju commented 2 years ago

The same solution as in #156 (workaround) could work, because instead of the target://myLib folder (which resolves to file:///...myLib/target/classes, a reference to the jar file would not be as unstable as the contents of the target folder.

jurgenvinju commented 2 years ago

There is something to be said for a solution that knows how to run mvn compiler:compile just before reloading the new classes if they are there. But we don't want to do this at every command on the REPL... Before a registerLanguage is feasible..