Skip to content

Static binding generator fails when using Webpack + Workers #778

Closed

Description

@sis0k0

Example case:
Setup - project with web worker file where the worker imports 'globals'.
If you webpack the project, a bundle named [hash].worker.js will be generated and it will contain the whole tns-core-modules package.
Since tns-core-modules is also contained in the vendor chunk, the static binding generator will fail:

Warning: there already is an extend called com.tns.FragmentClass.
Warning: The static binding generator will generate extend from:b8fc197268e0dd59663c.worker.js implementation
:asbg:generateBindings
Exception in thread "main" java.io.IOException: File already exists. This may lead to undesired behavior. Building 55% > :asbg:generateBindings
Please change the name of one of the extended classes.
/home/svlaeva@bedford.progress.com/nativescript-webpack-workers-issue/platforms/android/src/main/java/com/tns/FragmentClass.java
        at org.nativescript.staticbindinggenerator.Generator.writeBindings(Generator.java:59)
        at org.nativescript.staticbindinggenerator.Main.main(Main.java:15)
:asbg:generateBindings FAILED

Activity

  1. petekanev commented on Jun 8, 2017

    @petekanev
    Contributor

    Starting off I'd like to point something out - that behavior IS expected.

    The build-time exception is often a sign that something isn't quite right with the files - you have dupes, or you extend the same class, with the same name, meaning if the build was uninterrupted - only one of the two extended classes will pass, which may result in unexpected behavior/bugs runtime.

    I think we can make it so the sbg will spit out a warning message when two of the same classes have the same content, and not throw, while still throwing an exception with that particular error message if contents of the two files differs.

  2. danielgek commented on Jun 8, 2017

    @danielgek

    @Pip3r4o i saw your branch about this issue, do you have a build i can test/use ?
    i have a release pending on this :P
    thanks in advance

  3. petekanev commented on Jun 8, 2017

    @petekanev
    Contributor

    @danielgek you can fetch the branch, and build the .jar locally, then simply replace it in build-tools/android-static-binding-generator. (navigate to android-static-binding-generator/project/staticbindinggenerator && ./gradlew build - the output jar will be in build/libs)

    However these changes will not fix or work around the problem that @sis0k0 has described with webpacked workers. While the two files whose contents are being compared may look the same, there is a very important bit (JavaScriptImplementation annotation) that will fail the check.

  4. danielgek commented on Jun 8, 2017

    @danielgek

    @Pip3r4o i was already doing that xD, but yeah i got the same error, thanks for the help !!

  5. PeterStaev commented on Jun 19, 2017

    @PeterStaev

    I'm hitting this same issue when developing plugins that have @Interfaces() decorated classes. So I make changes to the local TS files for the plugin. Then go to the demo project and do a tns run android and very often I get this error because the static binding generated decides to create a new file. I guess happens because it detects that the plugin files have changed (i.e. installed a new version of the plugin) and decides to generate again the Java classes but does not clear the old ones. Also tns run android --clean does not seem to fix the problem and you have to do tns platform clean android to fix the problem.

    In case of plugins the CLI/Runtime should detect that a new version of the plugin is used and should automatically remove the old java classes that have been generated by this plugin so the new ones can be generated successfully. Or it should just override the existing classes with the new ones.

  6. petekanev commented on Jun 19, 2017

    @petekanev
    Contributor

    @PeterStaev I recently pushed a change to the sbg logic to make it less aggressive during a build. That is achieved by always invalidating the list of to-be-generated classes.

  7. PeterStaev commented on Jun 19, 2017

    @PeterStaev

    Thanks @Pip3r4o ! I've just tried the @next of the android runtime and it is working really nice 👍 Will speed up plugin dev tremendously! 😄

  8. mcrvaz commented on Jun 20, 2017

    @mcrvaz

    I was having an issue with a duplicated DropDownAdapter class from nativescript-drop-down and @next solved it.

  9. abhayastudios commented on Jun 30, 2017

    @abhayastudios

    I am still experiencing this issue when running npm run start-android-bundle with NS 3.1.1:

    $ tns info
    All NativeScript components versions information
    ┌──────────────────┬─────────────────┬────────────────┬─────────────┐
    │ Component        │ Current version │ Latest version │ Information │
    │ nativescript     │ 3.1.1           │ 3.1.1          │ Up to date  │
    │ tns-core-modules │ 3.1.0           │ 3.1.0          │ Up to date  │
    │ tns-android      │ 3.1.1           │ 3.1.1          │ Up to date  │
    │ tns-ios          │ 3.1.0           │ 3.1.0          │ Up to date  │
    └──────────────────┴─────────────────┴────────────────┴─────────────┘
    

    Did I understand wrong that this was supposed to be fixed in this version?

  10. petekanev commented on Jul 1, 2017

    @petekanev
    Contributor

    Having duplicate classes with the same name will fail your build, and that is expectrd, yes. Read the error carefully and see where the conflicts are.

  11. abhayastudios commented on Jul 1, 2017

    @abhayastudios

    @Pip3r4o thanks for the reply. As far as I understand, I encounter this issue due to a web worker that I am using in my plugin as is explained in this issue. Shouldn't web workers be supported out of the box?

    I see that @sis0k0 explains that "you don't really need to import globals in your worker" so I tried not to include the globals in the worker, but even then I am getting the same error:

    Running full build
    finished with reading lines with js files
    Warning: there already is an extend called com.tns.FragmentClass.
    Warning: The static binding generator will generate extend from:vendor.js implementation
    :asbg:generateBindings
    Exception in thread "main" java.io.IOException: File already exists. This may lead to undesired behavior.
    Please change the name of one of the extended classes.
    File:/Users/joni/projects/nativescript-webpack-error-app/platforms/android/src/main/java/com/tns/FragmentClass.java Class: com.tns.FragmentClass
            at org.nativescript.staticbindinggenerator.Generator.writeBindings(Generator.java:68)
            at org.nativescript.staticbindinggenerator.Main.main(Main.java:15)
    :asbg:generateBindings FAILED
    
  12. quentinor commented on Jul 19, 2017

    @quentinor

    Hi,

    I believe I am having the same problem as @sis0k0 , trying to webpack an {N} app with a web worker:

    Exception in thread "main" java.io.IOException: File already exists. This may lead to undesired behavior.
    Please change the name of one of the extended classes.
    File:/home/quentin/Projects/hubup-nativescript-clover/platforms/android/src/main/java/com/tns/FragmentClass.java Class: com.tns.FragmentClass
            at org.nativescript.staticbindinggenerator.Generator.writeBindings(Generator.java:68)
            at org.nativescript.staticbindinggenerator.Main.main(Main.java:15)
    :asbg:generateBindings FAILED
    

    I waited a few weeks before migrating to {N} V3, but now, it is becoming more and more pressing that I keep my app up to date :)

    So is there a workaround for workers, or is there a release where this prob is fixed ?

    Thanks

  13. petekanev commented on Jul 24, 2017

    @petekanev
    Contributor

    @quentinor we have not put any specific effort towards resolving this particular issue. We are still deliberating how to best handle the case with webpack, since it essentially pours the scripts you already use in the main bundle into the worker script bundle. The static binding generator does not, at this point, differentiate between a regular script, and one that will be used on a worker thread.

    For the time being, avoid importing the tns-core-modules into a worker script, when webpacking. That should be sufficient to let the android build complete.

  14. added this to the 3.2.0 milestone on Aug 3, 2017
  15. leocrawf commented on Aug 8, 2017

    @leocrawf

    Hello Pip3r4o. You said:" For the time being, avoid importing the tns-core-modules into a worker script, when webpacking. That should be sufficient to let the android build complete."

    How do you do that?

  16. 24 remaining items

  17. erjdriver commented on Oct 4, 2017

    @erjdriver

    Here's the error that gets displayed when i try to webpack on the android

    Note the error "not cacheable"

    `[224] ../node_modules/nativescript-worker-loader!./worker-check-version.ts 119 bytes {0} [not cacheable] [built]
    + 320 hidden modules

    ERROR in [at-loader] ./app/utils.ts:19:37
    TS2307: Cannot find module 'nativescript-worker-loader!./worker-check-version'.`

    When I try to include the file from /app/utils.ts file -I get the cannot-find-module error

  18. abhayastudios commented on Oct 5, 2017

    @abhayastudios

    @erjdriver as far as I know you need to explicitly reference the .js file (not the .ts file) since the .js file is what needs to be executed runtime. I don't know whether webpack transpiles typescript sources for workers as I wrote my worker in plain ES6. However, as a debug step, I would try to manually transpile your .ts file to .js and reference that one just to check whether it works.

    Regarding the FragmentClass exception: are you sure you are using nativescript-dev-webpack ^0.8.0 in your package.json? If so, then try removing the android platform and adding it back again.

  19. erjdriver commented on Oct 5, 2017

    @erjdriver

    @abhayastudios thank you for your suggestions.

    1. dumb question - how do i force a transcompile. In my apps folder there are NO js files - even for the other files. I assume that's because webpack is doing something.

    2. i'm pretty sure - but i'll do your suggestion once I get past resolved issue #40 #1.

  20. abhayastudios commented on Oct 5, 2017

    @abhayastudios

    You can run tsc worker-name.ts which should produce the JavaScript version. You can also copy/paste the TypeScript code into their playground for an online transpilation.

  21. petekanev commented on Oct 5, 2017

    @petekanev
    Contributor

    @erjdriver since your worker is done in TypeScript, did you follow the README steps strictly? Did you make a typings file? -> https://github.com/nativescript/worker-loader#integrating-with-typescript

  22. erjdriver commented on Oct 5, 2017

    @erjdriver

    ok making some progress.

    I added the typings folder in the root and am not getting the module-not-found error any more.

    The build succeeds.

    But when the app tries to run in the emulator.

    I removed and added the android platform before the build.

    `finished with reading lines with js files
    Warning: there already is an extend called com.tns.FragmentClass.
    Warning: The static binding generator will generate extend from:vendor.js implementation
    Exception in thread "main" java.io.IOException: File already exists. This may lead to undesired behavior.
    Please change the name of one of the extended classes.
    File:C:\Users\MyPC\nativescript\test4b\platforms\android\src\main\java\com\tns\FragmentClass.java Class: com.tns.FragmentClass
    at org.nativescript.staticbindinggenerator.Generator.writeBindings(Generator.java:68)
    at org.nativescript.staticbindinggenerator.Main.main(Main.java:15)

    FAILURE: Build failed with an exception.`

  23. erjdriver commented on Oct 10, 2017

    @erjdriver

    This issue is still not fixed - not sure why it was closed.

    Still getting the duplicate FragmentClass error.

    I've commented out all the Worker references and still getting the error.

  24. petekanev commented on Oct 10, 2017

    @petekanev
    Contributor

    @erjdriver please provide a minimalistic sample repository to help us debug the problem, as I am unable to reproduce it on my end.

  25. legioner0 commented on Oct 12, 2017

    @legioner0

    @erjdriver did you try tns platform clean android, as @PeterStaev say? This command fixed FragmentClass error in my project.

  26. PeterStaev commented on Oct 12, 2017

    @PeterStaev

    Seems there is some problem with @next (3.3) version. I just got a PR for the Drop Down plugin to support Angular 4.4 (PeterStaev/NativeScript-Drop-Down#138) and this failed the the CI build with the Fragment class error: https://travis-ci.org/PeterStaev/NativeScript-Drop-Down/jobs/286806719#L3749 .

  27. petekanev commented on Oct 12, 2017

    @petekanev
    Contributor

    @PeterStaev I am not sure it is a problem with the @next of the android runtime. I tested master branch of your plugin's demo (tns build android) with the latest versions of angular and the nativescript-angular plugin. The project built fine without exceptions.

  28. PeterStaev commented on Oct 12, 2017

    @PeterStaev

    @Pip3r4o seems you are correct. It could have been something specific to the specific version that was used in the PR. With the resubmited PR with @next there is no error 👍

  29. petekanev commented on Oct 12, 2017

    @petekanev
    Contributor

    @erjdriver I created a minimalistic sample of loading a worker in typescript, following the nativescript-worker-loader README. You can find the sample in the pete/workertsbranch of the demo-worker repo -> https://github.com/NativeScript/demo-workers/tree/pete/workerts

  30. erjdriver commented on Oct 12, 2017

    @erjdriver

    @Pip3r4o - thanks for getting back to me and taking the time to create the test project.

    I solved the problem.

    The problem was that in my bundle-config.ts file, I had

    global.registerModule("nativescript-telerik-ui/sidedrawer", function () { return require("nativescript-telerik-ui/sidedrawer"); });

    global.registerModule("nativescript-telerik-ui/sidedrawer/drawerpage", () => require("nativescript-telerik-ui/sidedrawer/drawerpage"));

    I was getting the multiple definition of FragmentClass.

    If I comment out the second line - then it works.

    Weird because I got those two lines from some sample projects on github.

    Hopefully this will help someone else...

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions