VSCode extension issues

Tags: #<Tag:0x00007fc8f95d9610>

I ran into a couple of issues in conjunction with UoM that the VSC extension complains about (0.8.2 and 1.0beta, too). Irrititating that these actually work, it’s just VSC not to believe it.

Is it actually a problem of the language server or a VSC problem ?

  1. itemName is of type Number:Power and the line
    itemName.postUpdate(new QuantityType<Power>(p + "W")) results in
    Ambiguous feature call.
    The extension methods
    postUpdate(Item, State) in BusEvent and postUpdate(Item, Number) in BusEvent both match. org.eclipse.xtext.xbase.validation.IssueCodes.ambiguous_feature_call)

  2. using QuantityType<DateTime> gives
    DateTime cannot be resolved to a type.(org.eclipse.xtext.diagnostics.Diagnostic.Linking)
    Strange anyway that I need to use DateTime rather than Time as in the .items file it has to be a Number:Time

  3. I have a simple lambda val Functions$Function2 <QuantityType<Number>,QuantityType<Number>,QuantityType<Number>> minimum = [ m, n |
    if (m > n) return n else return m ]
    If called with more specific data types such as QuantityType<Energy>, VSC/LSP complains
    Type mismatch: cannot convert from QuantityType<Number> to QuantityType<Energy>
    which is sort of correct all by itself (to cast would require to supply the unit, too), but as said the code actually works.

  1. This one is interesting. And it does in fact work. when it runs? This is the same error that occurs when one tries to postUpdate or sendCommand a DecimalType. DecimalType is both a DecimalType and a Number and there is a separate postUpdate/sendCommand method for each type. The end result is there is no way for the engine to tell which method you really want to call.

Looking at the JavaDocs for QuantityType shows that indeed, QuantityType inherits from Number and implements State. So it is in fact both.

Unfortunately postUpdate and sendCommand are not actually implemented by the Items themselves (and I don’t understand how these methods get injected to the Item class in Rules DSL) so I can’t look any further in that direction.

But based on the above, I would expect this to fail at runtime too. It’s very interesting if it is not. I do think the error is legitimate though so my recommendation is to call toString on your QuantityType (of just pass p + "W" and let OH create the QuantityType for you) or cast your QuantityType to State.

    itemName.postUpdate(p + "W") // you might need a space there between p and W in the end String, I'm not sure
    itemName.postUpdate(new QuantityType<Power>(p + "W").toString)
    itemName.postUpdate(new QuantityType<Power>(p + "W") as State)
  1. I don’t think that is correct. It should be Time. The actual units are implemented by a third party library/Java standard. There is no javax.measure.quantity.DateTime there but there is a Time. However, openHAB does some weird stuff to Time that allows one to use Temporal String formatting to format the state on sitemaps/MainUI. For example, I use %1$tH:%1$tM:%1$tS for a Number:Time Item to get hours:minutes:seconds formatting for the remaining runtime on my UPS.

So there might be something like that going on. But if there is, searching through the JavaDocs shows there is no DateTime class defined anywhere I can find so I think that <DateTime> is incorrect. Have you tried Time? What lead you to using DateTime in the first place?

Again, without some more information this looks like a legitimate error too.

  1. It’s weird that this works too. I don’t think it should but Rules DSL tries really hard to figure out type at runtime so it must be figuring it out.

I think this is a legitimate error too because QuantityType expects a javax.measure.Quantity<?> to be between the < > and java.lang.Number does not implement that interface. So the code is in fact incorrect from a type perspective. But Rules DSL doesn’t really worry too much about type until runtime. And I think at runtime it goes through the types of the two Objects looking for a match and if it finds a match uses that. So even though Number is incorrect, passing it a Number:Energy is correct but it can’t know that until runtime.

You can probably make the error go away (but probably get a warning in exchange) by changing the types from QuantityType<Number> to QuantityType<?> or perhaps QuantityType<Quantity> (you’ll probably have to import Quantity. You might even be able to get away with just QuantityType without the < >.

So, the tl;dr of it all is I think the language server and VSCode are working correctly. These are in fact errors. But the loosey-goosey way Rules DSL actually handles types at runtime it’s clearly able to muddle through and succeed despite the errors. Though I’m really surprised that 1 works. It didn’t use to.

Thanks for your input. Yes I’m confused too.

Do you know where the error originates from, is it VSC ?
I don’t know but am inclined to believe because if it was the LSP server why should the parser accept a different syntax than the LSP server of the same openHAB instance.

Using Time instead of DateTime in 2) just doesn’t work that’s how I ended up there:

2021-03-31 17:53:36.741 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'Test.rules'
2021-03-31 17:53:36.815 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'Test.rules' has errors, therefore ignoring it: [93,67]: no viable alternative at input 'Time'

On 3), well, passing Number isn’t entirely incorrect, is it ? It’s the inheritance class … so just like you can use GenericItem for anything in a lambda, you can use QuantityType<Number> instead of QuantityType<Energy> or any other UoM type as all UoM actually inherit Number i.e. are Number:xxx . I just looked it up, I even use Number instead of QuantityType and it works.

I do not. I would assume it’s the LSP but if that were the case I’d expect the errors to appear in the logs too. I don’t think that the extension is all that smart, depending on the LSP for most of the heavy lifting for finding errors. But I could be wrong on that.

Did you try to import it or use the fully qualified name of javax.measure.quantity.Time?

This is one of the newer units and maybe it’s not imported by default like Power is.

If using units like Power and Energy and such work without imports, an issue should be filed to include Time (and any other missing units) too.

Looking at the JavaDocs:

  • QuantityType<T extends javax.measure.Quantity<T>>: tells me that QuantityType requires a Quantity<T> to be between the < >.
  • Looking at Quantity shows that it is an Interface, not a Class. And it does not inherit from java.lang.Number.

Thus, based on looking at just the types, QuantityType<Number> is incorrect because Number isn’t a Quantity. What I don’t know how to interpret (I’ve been away from Java for too long) is what the <T> on the Quantity Interface means. It seems to be recursive but it works so it doesn’t really matter that we understand it here.

QuantityType itself though does inherit from Number. So it would be valid to do something like new QuantityType<Power>(p+"W") as Number. But Quantity doesn’t nor do any of the things that implement Quantity (e.g. here is Power Power (Units of Measurement API 2.1.2 API)). And it wouldn’t make sense to because Number is a Class and Quantity is an Interface and an Interface cannot inherit from a Class, only the other way around is allowed.

I really have no good idea for why it would work beyond the fact that when the Rules engine gets to running those lines of code, it all but ignores the specified types and instead just looks at the types of the actual Objects to see if the give operation is supported.

It might be worth taking a step back. The < > isn’t a way to specify the type of an Object. It’s a way to specify the type that the Object works with. For example, List<String> myList doesn’t convert the List to become a String. Instead it’s a way to specify that myList only works with Strings. You can’t (or at least should be able to but who knows with Rules DSL) call myList.add(5). 5 isn’t a String so that should generate an error.

The same is happening with QuantityType. The <Power> is indicating that this particular QuantityType works with a Power Quantity. Number isn’t a Quantity so it is not really allowed between the < >. Based on the code, only Quantity types are allowed between the < >. The fact that it works at all with Number is frankly a mystery. It shouldn’t and in a more strongly typed language it wouldn’t. And all of this stuff is actually Java, not Rules DSL or Xtend so it should be strongly typed.

I used to be a big booster of Rules DSL, and there are still things I like about it, but it’s weirdness like this which has made me move away. There is too much unexplained spooky magic going on behind the scenes which makes it challenging to predict exactly what will and won’t work.

No, what do you mean by the FQN ?

Where are you now, Python or JS ?

The class name is Time. But in order to call it just by the class name you have to import it. OH imports all sorts of stuff for you by default in Rules DSL (more spooky magic).

The FQN is javax.measure.quantity.Time. That includes the full package name. You can reference a class by its FQN even without importing it. So new QuantityType<javax.measure.quantity.Time> should work even without importing Time at the top of the .rules file. The import would be

import javax.measure.quantity.Time

With that you should be able to just use new QuantityType<Time>.

I’ve recently discovered that imports don’t work when using Rules DSL in the UI so I expect referencing classes by the FQN is going come up a lot more often on the forum in the future.

I’m on JS but not because I like it better. It comes with OH and so it has fewer extra dependencies which makes it so I can write libraries that are easier to share.

But I like Python better over all. The only problem is it all but requires the use of the Helper Libraries to use it as efficiently as one can write rules in Rules DSL.

So if you are looking for a recommendation, I’d say Python with the Helper Libraries if you plan on continuing to use text based rule files and JavaScript if you plan on writing rules through MainUI. The lack of the helper libraries is less pronounced when writing rules through the UI because most of the stuff related to actually defining the rule itself is handled outside of the code. But that comes with it’s own limitations as it means you can’t actually define variables outside the code either (no global variables). There is a way to preserve a variable from one run to the next of the rule though so you can still manage Timers and such within a Script Action, you just can’t share that Timer with another Rule.

The extension itself does not provide any code checking on it’s own currently.
And i am not aware of any other extensions/functions that provide checking for rules files currently,
so it should come from the remote lsp server, which gets registered to check rules files when activated.

You could simply check how the extension behaves, when you turn of remote lsp in the settings.
I would expect the complete checking to stop then.

We have some local LSP server in the extension but i am not sure if and what it does currently.
I can say that it is started with the extension, but from my view nearly all checking should be done with the remote one currently.

in the openHAB console?
I am not aware that they share logging features in parallel currently.

I tried that already to no avail. Just wanted to make sure we understand the same.
QuantityType<DateTime> works but still gives VSC error, QuantityType<Time> does not compile.
I’ve resorted to use QuantityType<Number> now, seems to work.
(EDITED)

Might that be the source of code being warned of although the code itself works (remotely) ?
Any means to find out ?

I doubt that this is the source.

This is the Document Validation code for the local part:

As you see:

WIP this does not do anything yet

It is just a boilerplate introduced some while ago.
What may work from the local LSP part (not tested though) is item completion while typing (only with http connections).
Those should then get suggested in the code editor.

*** EDITED ***

Hmm. It now happened to me at least twice that at times VSC was not showing any errors then when opening the same fileset again later it was suddenly full of (correct) warnings on my code.
I believe it has simply stopped working in the first place.

One thing to irritate was VSC kept complaining about deprecated parameters. There weren’t any in settings.json but turned out there’s also C:\Users<MyWinUser>.vscode\extensions\openhab.openhab-1.0.0-ci-5aaea7a\package.json` and it still had those old parameters. When I deleted them there the warning disappeared.
VSC was also spitting errors on the host it couldn’t connect to.
That package.json file also contained an old (now wrong) hostname parameter for the host to connect to and after replacing that the warning disappeared.
So thing is package.json seems to have precedence over settings.json ??

I also got the output below:

Any hint how to proceed from here to debug what’s going on ?

openHAB vscode extension has been activated
[Error - 19:20:11] Request textDocument/definition failed.
  Message: Internal error.
  Code: -32603 
java.util.concurrent.CompletionException: java.lang.ClassCastException: class org.eclipse.xtext.common.types.access.TypeResource cannot be cast to class org.eclipse.xtext.resource.XtextResource (org.eclipse.xtext.common.types.access.TypeResource is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @d67b05; org.eclipse.xtext.resource.XtextResource is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @2d855)
	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:331)
	at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:346)
	at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:704)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
	at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2088)
	at org.eclipse.xtext.ide.server.concurrent.AbstractRequest.logAndCompleteExceptionally(AbstractRequest.java:73)
	at org.eclipse.xtext.ide.server.concurrent.ReadRequest.lambda$doRun$0(ReadRequest.java:69)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	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:834)
Caused by: java.lang.ClassCastException: class org.eclipse.xtext.common.types.access.TypeResource cannot be cast to class org.eclipse.xtext.resource.XtextResource (org.eclipse.xtext.common.types.access.TypeResource is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @d67b05; org.eclipse.xtext.resource.XtextResource is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @2d855)
	at org.eclipse.xtext.ide.server.WorkspaceManager.doRead(WorkspaceManager.java:436)
	at org.eclipse.xtext.ide.server.findReferences.WorkspaceResourceAccess.readOnly(WorkspaceResourceAccess.java:36)
	at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.doRead(DocumentSymbolService.java:332)
	at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.getDefinitions(DocumentSymbolService.java:112)
	at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.getDefinitions(DocumentSymbolService.java:99)
	at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$definition$24(LanguageServerImpl.java:603)
	at org.eclipse.xtext.ide.server.WorkspaceManager.doRead(WorkspaceManager.java:438)
	at org.eclipse.xtext.ide.server.LanguageServerImpl.definition(LanguageServerImpl.java:602)
	at org.eclipse.xtext.ide.server.LanguageServerImpl.definition(LanguageServerImpl.java:590)
	at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$definition$23(LanguageServerImpl.java:581)
	at org.eclipse.xtext.ide.server.concurrent.ReadRequest.lambda$doRun$0(ReadRequest.java:66)
	... 5 more

EDIT on VSC start I get this on the OH server, reproduceably so. Running 1.0beta about 3 days old

2021-04-04 19:19:53.837 [INFO ] [ext.common.types.util.TypeReferences] - Couldn't find JvmType for name 'org.openhab.core.model.script.actions.Semantics' in context org.eclipse.xtext.xbase.resource.BatchLinkableResource@d073ff uri='file:///etc/openhab/rules/Energiemanagement.rules'
java.lang.IllegalStateException: Resource has not been loaded
        at org.eclipse.xtext.common.types.access.reflect.ReflectionTypeProvider.findTypeByClass(ReflectionTypeProvider.java:200) ~[bundleFile:?]
        at org.eclipse.xtext.common.types.access.reflect.ReflectionTypeProvider.findTypeByClass(ReflectionTypeProvider.java:151) ~[bundleFile:?]
        at org.eclipse.xtext.common.types.access.reflect.ReflectionTypeProvider.findTypeByName(ReflectionTypeProvider.java:88) ~[bundleFile:?]
        at org.eclipse.xtext.common.types.util.TypeReferences.findDeclaredType(TypeReferences.java:256) [bundleFile:?]
        at org.eclipse.xtext.common.types.util.TypeReferences.findDeclaredType(TypeReferences.java:233) [bundleFile:?]
        at org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedFeatures.getTypes(ImplicitlyImportedFeatures.java:82) [bundleFile:?]
        at org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedFeatures.getExtensionClasses(ImplicitlyImportedFeatures.java:76) [bundleFile:?]
        at org.eclipse.xtext.xbase.scoping.batch.XbaseBatchScopeProvider.newSession(XbaseBatchScopeProvider.java:121) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.DefaultReentrantTypeResolver.resolve(DefaultReentrantTypeResolver.java:164) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.DefaultReentrantTypeResolver.reentrantResolve(DefaultReentrantTypeResolver.java:140) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$LazyResolvedTypes.resolveTypes(CachingBatchTypeResolver.java:81) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$2.process(CachingBatchTypeResolver.java:58) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver$2.process(CachingBatchTypeResolver.java:54) [bundleFile:?]
        at org.eclipse.xtext.util.concurrent.IUnitOfWork$Void.exec(IUnitOfWork.java:38) [bundleFile:?]
        at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:135) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver.doResolveTypes(CachingBatchTypeResolver.java:54) [bundleFile:?]
        at org.eclipse.xtext.xbase.typesystem.internal.AbstractBatchTypeResolver.resolveTypes(AbstractBatchTypeResolver.java:70) [bundleFile:?]
        at org.eclipse.xtext.xbase.resource.BatchLinkingService.resolveBatched(BatchLinkingService.java:72) [bundleFile:?]
        at org.eclipse.xtext.xbase.resource.BatchLinkableResource.resolveLazyCrossReferences(BatchLinkableResource.java:166) [bundleFile:?]
        at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:505) [bundleFile:?]
        at org.eclipse.xtext.build.IncrementalBuilder$InternalStatefulIncrementalBuilder.lambda$launch$2(IncrementalBuilder.java:266) [bundleFile:?]
        at com.google.common.collect.Iterators$6.transform(Iterators.java:783) [bundleFile:?]
        at com.google.common.collect.TransformedIterator.next(TransformedIterator.java:47) [bundleFile:?]
        at com.google.common.collect.FluentIterable.copyInto(FluentIterable.java:791) [bundleFile:?]
        at org.eclipse.xtext.build.ClusteringStorageAwareResourceLoader.executeClustered(ClusteringStorageAwareResourceLoader.java:69) [bundleFile:?]
        at org.eclipse.xtext.build.BuildContext.executeClustered(BuildContext.java:55) [bundleFile:?]
        at org.eclipse.xtext.build.IncrementalBuilder$InternalStatefulIncrementalBuilder.launch(IncrementalBuilder.java:259) [bundleFile:?]
        at org.eclipse.xtext.build.IncrementalBuilder.build(IncrementalBuilder.java:404) [bundleFile:?]
        at org.eclipse.xtext.build.IncrementalBuilder.build(IncrementalBuilder.java:386) [bundleFile:?]
        at org.eclipse.xtext.ide.server.ProjectManager.doBuild(ProjectManager.java:106) [bundleFile:?]
        at org.eclipse.xtext.ide.server.BuildManager.internalBuild(BuildManager.java:190) [bundleFile:?]
        at org.eclipse.xtext.ide.server.WorkspaceManager.lambda$didChangeFiles$4(WorkspaceManager.java:279) [bundleFile:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$runBuildable$15(LanguageServerImpl.java:453) [bundleFile:?]
        at org.eclipse.xtext.ide.server.concurrent.WriteRequest.run(WriteRequest.java:52) [bundleFile:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]

Package.json

The documented hierarchy is pretty clear for settings.
It will choose form the following sources in the presented order:

  • Default value
    (from package JSON)
  • Global settings value
    (Changed/Configured in the user settings in vscode)
  • Workspace settings
    (Can be done via editor or directly with the settings.json in your .vscode folder)
  • Other language activated specific workspace settings
    (No deeper knowledge from my side but i don’t think that it affects us.)

So what may happened is that vscode does not clean out those folders very well during an update and knows some default value somewhere, where it should not be.
I tried to suppress deprecated parameter warnings, when there was just a default value in place.

Maybe we should point to the stackoverflow article for completely uninstalling a extension befor an update.

About the long warning messages

Those errors are send from the remote Language server of your openHAB instance.
Maybe @wborn can give some information. He fixed the last problems on LSP side.

I am not able to do anything over there.
The Language Server is implemented as a bundle in Java in openHAB core.

Possible, when the connection is erroring.
It will not try to reopen after some tries until you restart the extension, from what i know.

I’m still getting ‘deprecated’ warnings on every start.
I’ve browsed settings.json and package.json but I’m still getting this warning.
Global settings go to settings.json don’t they? So that should cover your possibilities.

Could you please at least add an output which parameter this refers to ? I likely have one that I thought is current but the extension considers it to not be - just that I do notknow which one that is.

Gnah.
I had something like this built in already, but it just produces an output when a deprecated setting “is used by an extension part” but not when it is set at all.

That’s not how it was supposed to be, but it seems that it has anded up the wrong way in a refactoring.
I will put out a list of deprecated parameters in the openHAB extension Output.

Should we add a Button to the warning to open the output directly?

Edit:

image
Showcase

I will link the beta version when it is available.

1 Like

Thanks. Hmm, it says

Usage of deprecated config => openhab.consoleCommand <= detected

But isn’t that the correct, new name ? At least the settings page says so.

Do you have configured the consoleCommand on purpose?
How did you configure it, if the answer is yes? (User or workspace setting?)
Can you also check if you still have openhab.karafCommand configured somewhere maybe?

I will try to reproduce the behavior based on your config situation in my debugging environment then.

yes, user settings

It was indeed a small bug in the karaf parameter check.

Continuing here, since the anonuncement is closed and the issue is discussed here with its history:

Did you check you configuration in all possible places?!

User settings
Workspace settings?

Here is a gif of how i would search for the specific setting in the different scopes and reset it to default:

Since there are many ways to configure the extension, i can only point to the settings doc article for further investigation.

It show possible paths where settings might be stored and hot to fully rest user settings.

Anyway i think it would be good to give an indicator on which scope(s) a deprecated setting is modified in one of the next extension versions.
I will prepare and contribute this extended logging.

I only have user settings and it’s right there. No .vscode directories, I checked.