Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

4.15.1 broken scope: ZonedDateTime and others no longer available unless specifically imported #438

Closed
jimtng opened this issue Nov 30, 2021 · 16 comments · Fixed by #444
Closed
Labels

Comments

@jimtng
Copy link
Collaborator

jimtng commented Nov 30, 2021

Just upgraded my library from 4.14 to 4.17 and all my scripts using ZonedDateTime broke because now I need to issue an explicit java_import Java::JavaTime::ZonedDateTime inside the rule / method. Importing it globally at the top of the script didn't work.

@jimtng
Copy link
Collaborator Author

jimtng commented Nov 30, 2021

Probably yet another case of #348 but this worked on 4.14

@jimtng jimtng closed this as completed Nov 30, 2021
@ccutrer
Copy link
Collaborator

ccutrer commented Nov 30, 2021

This sounds different. #348 is where the top level constant gets replaced by the actual Java class instead of the Ruby proxy class for the Java class. If it's just not defined at all anymore, it's possible some require or import changed within the library that no longer puts it in the top level. I'm not sure if this is considered a bug in our interface. I know our docs mention ZonedDateTime, but not I'm not sure if they say "the thing returned from this is a ZonedDateTime and so you can treat it as one" (do the top level constant going missing wouldn't be a bug) or if they say "create a ZonedDateTime and pass it in" (in which case it probably should be considered a bug).

@jimtng
Copy link
Collaborator Author

jimtng commented Nov 30, 2021

I am a bit confused with this. In my production system, in one test.rb it works fine without importing ZonedDateTime both outside a rule, and inside a rule's run block. So it seems to behave the same as before.

Yet in another rule file of the same system, it gave me an error if I didn't import ZonedDateTime.

01:13:07.445 [ERROR] [yobj.OpenHAB.DSL.Rules.AutomationRule] - undefined method `now' for nil:NilClass (NoMethodError)

If I find more info I'll reopen this issue.

@jimtng jimtng changed the title 4.14 -> 4.17 ZonedDateTime no longer available by default 4.15.1 broken scope: ZonedDateTime and others no longer available unless specifically imported Dec 1, 2021
@jimtng
Copy link
Collaborator Author

jimtng commented Dec 1, 2021

I tracked down the exact version when this problem started to 4.15.1.

@jimtng jimtng reopened this Dec 1, 2021
@jimtng
Copy link
Collaborator Author

jimtng commented Dec 1, 2021

I cannot explain this. With 4.15.0 this problem doesn't happen. With 4.15.1, it happens. But if I changed the return value of OpenHAB::DSL::Rules::rule method from returning rule to returning config, the problem didn't happen. Changed it back to returning rule, and the problem happened again.

I tried changing my openhab version, from 3.1.0 to 3.2M4 to 3.2 snapshot, this doesn't make a difference.

A simple way to reproduce it on my system:

conf/automation/jsr223/ruby/personal/test1.rb

require 'openhab'

rule 'T1' do
  received_command DimmerItem1
  run do
    logger.error("Test1: #{Java::JavaTime::ZonedDateTime.now}") ## This works all the time
    logger.error("Test1: #{ZonedDateTime.now}") ## This caused an error when rule method returns rule instead of config
  end
end

Then send a command to DimmerItem1 from the console (or from another rules file)

The error:

20:48:59.931 [ERROR] [yobj.OpenHAB.DSL.Rules.AutomationRule] - undefined method `now' for nil:NilClass (NoMethodError)
In rule: T1
/openhab/conf/automation/jsr223/ruby/test1.rb:5:in `block in <main>'

There are NO errors if I sent the command from within the same rules file (i.e. from within test1.rb)

What's strange is I cannot reproduce this using cucumber test (running on a different machine) even on 4.19.

@jimtng
Copy link
Collaborator Author

jimtng commented Dec 1, 2021

returning nil inside rule works too.

      #
      # Create a new rule
      #
      # @param [String] rule_name <description>
      # @yield [] Block executed in context of a RuleConfig
      #
      #
      def rule(rule_name, &block)
        @rule_name = rule_name
        config = RuleConfig.new(rule_name, block.binding)
        config.instance_exec(config, &block)
        config.guard = Guard::Guard.new(only_if: config.only_if, not_if: config.not_if)
        logger.trace { config.inspect }
        process_rule_config(config)
        nil # <======================== This made it work
      rescue StandardError => e
        re_raise_with_backtrace(e)
      end

@jimtng
Copy link
Collaborator Author

jimtng commented Dec 1, 2021

It seems that what really matters is the return value of the entire rules file, which goes back to OpenHAB core's scriptengine.eval(). Although openhab core doesn't actually check / save the return value of engine.eval().

If I added nil (or anything else other than the rule object), it's fine.

i.e.

require 'openhab'

rule 'T1' do
  received_command DimmerItem1
  run do
    logger.error("Test1: #{ZonedDateTime.now}") 
  end
end

# RETURN SOMETHING ELSE BACK TO scriptengine.eval()
nil

@jimtng
Copy link
Collaborator Author

jimtng commented Dec 1, 2021

@boc-tothefuture @ccutrer can you reproduce this issue on your production system?

@github-actions
Copy link

github-actions bot commented Dec 1, 2021

🎉 This issue has been resolved in version 4.20.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@jimtng
Copy link
Collaborator Author

jimtng commented Dec 12, 2021

This problem seems to be back in the current 3.2 snapshot after 3.2M5.

07:01:49.386 [ERROR] [yobj.OpenHAB.DSL.Rules.AutomationRule] - undefined method `now' for #<Java::JavaLang::Class: java.time.ZonedDateTime> (NoMethodError)

@jimtng jimtng reopened this Dec 12, 2021
@boc-tothefuture
Copy link
Owner

If you return config instead of nil does it work?

@jimtng
Copy link
Collaborator Author

jimtng commented Dec 18, 2021

If you return config instead of nil does it work?

I don't understand why returning config caused a problem before.

Now returning something at the end of the script doesn't fix it. Tested on 3.2.0RC1, this script failed:

require 'openhab'

rule 'test2' do
  received_command DimmerItem1
  run { logger.error("Test: #{ZonedDateTime.now}") }
end

DimmerItem1 << ON
23:19:10.686 [ERROR] [yobj.OpenHAB.DSL.Rules.AutomationRule] - undefined method `now' for #<Java::JavaLang::Class: java.time.ZonedDateTime> (NoMethodError)
In rule: test2
/openhab/conf/automation/jsr223/ruby/test2.rb:5:in `block in <main>'

Note the error is now different to the previous issue. Previously ZonedDateTime is nilClass. Now it's Java::JavaLang::Class which seems to be related to #448

@ccutrer
Copy link
Collaborator

ccutrer commented Dec 18, 2021

Hmm so returning NilClass is a bit unusual. Normally if a constant is missing you get a NameError. Might just be something about how JRuby dynamically imports constants (I.e. org.openhab.core.SomeClass is technically a chain of method calls, and NOT constant resolution from Ruby's perspective, and thus could result in nil being returned instead of throwing a NameError).

@boc-tothefuture
Copy link
Owner

Did we check if this broke when we changed context type to singlethread?

@jimtng
Copy link
Collaborator Author

jimtng commented Dec 21, 2021

I just upgraded to 3.2-release. I tried setting context type to threadsafe and the problem remains.

@jimtng
Copy link
Collaborator Author

jimtng commented Jan 10, 2022

I believe the problem is caused by the issue described in #482 and not the same as the original issue reported here. So I'll close this and track the issue in #482.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants