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

DynamicObject<JSFunction> context error when using karate.callSingle and karate.merge in karate-config.js #1883

Closed
hueller opened this issue Jan 5, 2022 · 9 comments
Assignees

Comments

@hueller
Copy link

hueller commented Jan 5, 2022

I know that there have already been several bug reports related to DynamicObject context errors, but I'm still able to reproduce an issue also against the current Karate develop branch.

Please find attached my sample project, which contains two Maven projects:

  • myproject (built with Karate Maven archetype and based on Karate develop branch (version 2.0.0))
  • myproject-helpers (contains two .feature files, which are used in myproject)

To reproduce the issue, first myproject-helpers needs to be built (mvn install) and then UsersRunner in myproject can be executed: mvn test -Dtest=UsersRunner

The two .feature files in myproject-helpers are used in the following way in myproject:

utils.feature gets called via call read in the first scenario of users.feature, which in general works fine:

* def uuidUtils = call read('classpath:examples/helpers/utils.feature@getUUIDUtils')
* print uuidUtils.getRandomUUID()

However, it stops working with the DynamicObject context error, when I try to include the second .feature file markers.feature via karate-config.js. This markers.feature file contains a self-validating expression, which I want to make 'globally' available by merging it into the config object:

// Read marker scenarios and merge them into config to make them globally available
var dateMarkers = karate.callSingle('classpath:examples/helpers/markers.feature@getDateMarkers');
config = karate.merge(config, dateMarkers);

karate.callSingle alone doesn't seem to cause an issue. But when also karate.merge gets called, the above mentioned call read('classpath:examples/helpers/utils.feature@getUUIDUtils') fails with the DynamicObject context error.

I have no idea why this is happening and if there are other options to make self-validating expressions globally available, so I appreciate your help! Thanks a lot!

Archive.zip

@ptrthomas
Copy link
Member

@hueller my first reaction is that this will be hard - so I'm going to come back to this later. my advice would be to make any "common" routines you need Java code since I am assuming (just speed reading the above) that you are trying to re-use stuff across 2 java maven modules - which will be a challenge in pure JS

some relevant discussion and work-arounds here (sorry, long read): #1558

the other reason why I will not rush to solve this is that Graal issue number 631 (see link above) may solve this horrible JS limitation once and for all. I need to find time to upgrade karate's graal dep and remove all the ugly JS context-swapping code we have right now

@hueller
Copy link
Author

hueller commented Jan 5, 2022

Ok thanks, but how can I use Java code for common routines without declaring them within JavaScript functions in .feature files? That's what I'm already doing in the attached example:

@ignore
Feature: Utils scenarios

  @getUUIDUtils
  Scenario: UUID Utils
    * def getRandomUUID =
  """
    function() {
      return java.util.UUID.randomUUID() + ''
    }
  """

And yes, what I want to achieve is to define common routines in one shared Maven module, which I can include in multiple concrete Karate projects. As mentioned above, this is working in general, but the additional usage of karate.callSingle and karate.merge in karate-config.js to include shared self-validating expressions seems to brake the whole thing (I forgot to mention in my first post that this was working in old Nashorn times with Karate 0.9.x).

Also the #? EXPR marker seems to work with JavaScript expressions only what I can read in the docs.

@ptrthomas
Copy link
Member

@hueller you can reuse java easily because it just needs to be on the classpath. please refer: https://stackoverflow.com/a/58339662/143475

@hueller
Copy link
Author

hueller commented Jan 12, 2022

Ok, thanks! Looking forward for the Karate release which includes the Graal VM fix.

For now I'll try to implement a workaround to not rely on the karate.merge call anymore (which seems to break my setup) and also on using Java for reusable functions/methods.

@pshrm
Copy link

pshrm commented Jan 21, 2022

@ptrthomas - I am trying to migrate my common utilities JS functions to Java. I use couple of JS functions provided by karate currently. e.g., karate.prevRequest is there a way to replicated them in Java directly?

@ptrthomas
Copy link
Member

@pshrm karate.prevRequest is Java behind the scenes so I don't understand your question. you are welcome to look at the source code and figure it out: https://github.com/karatelabs/karate/blob/v1.2.0.RC1/karate-core/src/main/java/com/intuit/karate/core/ScenarioBridge.java#L521

@ptrthomas
Copy link
Member

tagging a reference for some planned refactoring: oracle/graal#631 (comment)

ptrthomas added a commit that referenced this issue Jul 31, 2022
ptrthomas added a commit that referenced this issue Jul 31, 2022
still an issue with parallel scenario, but no longer the multi-thread issue
guess is that variables are being over-written by another scenario-thread
websocket may not be possible to do with custom js functions
so we will limit or revise existiing documented approach
@ptrthomas ptrthomas self-assigned this Aug 2, 2022
@ptrthomas ptrthomas added bug and removed help wanted labels Aug 2, 2022
@ptrthomas ptrthomas added this to the 1.3.0 milestone Aug 2, 2022
ptrthomas added a commit that referenced this issue Aug 2, 2022
feels good to get rid of that horrible recurse and attach stuff
ptrthomas added a commit that referenced this issue Aug 2, 2022
in small steps because of how much trouble this caused in the past
ptrthomas added a commit that referenced this issue Aug 2, 2022
ptrthomas added a commit that referenced this issue Aug 2, 2022
note that this commit reverts the change made in #1835
ptrthomas added a commit that referenced this issue Aug 2, 2022
my guess is that this was the source of the flakyness and how we swallowed the exception before
ptrthomas added a commit that referenced this issue Aug 2, 2022
this should be the last of the graal upgrade and js fixes
ptrthomas added a commit that referenced this issue Aug 2, 2022
@ptrthomas
Copy link
Member

@hueller I think this is finally fixed ! I haven't tried your sample project yet, and if you can use the develop branch and see if things work fine including karate.merge() that will save me a bit of time

ptrthomas added a commit that referenced this issue Aug 5, 2022
the extra graal value coercion seems to be reason for websocket test being flaky in ci
ptrthomas added a commit that referenced this issue Aug 5, 2022
well, the current working theory is that the more locks and sleeps we put in
the more likely threads run into each other
@ptrthomas
Copy link
Member

1.3.0 released

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

No branches or pull requests

3 participants