NativeScript / nativescript-dev-webpack

A package to help with webpacking NativeScript apps.
Apache License 2.0
97 stars 49 forks source link

Nativescript webpack java.lang.RuntimeException: Unable to instantiate service #515

Closed alexma01 closed 6 years ago

alexma01 commented 6 years ago

Issue Checklist

Tell us about the problem

Hi, i have this class:

app/notifications/FirebaseInstanceIDServiceCustom.ts

@JavaProxy("com.tns.notifications.FirebaseInstanceIDServiceCustom")
 class FirebaseInstanceIDServiceCustom extends com.google.firebase.iid.FirebaseInstanceIdService {
    onTokenRefresh(){

        }
    }
}
app/notifications/FirebaseInstanceIDServiceCustom.js (compiled)

var FirebaseInstanceIDServiceCustom = /** @class */ (function (_super) {
    __extends(FirebaseInstanceIDServiceCustom, _super);
    function FirebaseInstanceIDServiceCustom() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    FirebaseInstanceIDServiceCustom.prototype.onTokenRefresh = function () {

    };
    FirebaseInstanceIDServiceCustom = __decorate([
        JavaProxy("com.tns.notifications.FirebaseInstanceIDServiceCustom")
    ], FirebaseInstanceIDServiceCustom);
    return FirebaseInstanceIDServiceCustom;
}(com.google.firebase.iid.FirebaseInstanceIdService));

and this service in AndroidManifest.xml:

<service
    android:name="com.tns.notifications.FirebaseInstanceIDServiceCustom"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
         <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
     </intent-filter>
</service>

but when i run tns run android --bundle i have this error:

System.err: java.lang.RuntimeException: Unable to instantiate service com.tns.notifications.FirebaseInstanceIDServiceCustom: com.tns.NativeScriptException: System.err: System.err: Error: com.tns.NativeScriptException: Failed to find module: "app/notifications/FirebaseInstanceIDServiceCustom.js", relative to: app//

in my com.tns.notifications.FirebaseInstanceIDServiceCustom.java:

package com.tns.notifications;

@com.tns.JavaScriptImplementation(javaScriptFile = "./notifications/FirebaseInstanceIDServiceCustom.js")
public class FirebaseInstanceIDServiceCustom extends com.google.firebase.iid.FirebaseInstanceIdService implements com.tns.NativeScriptHashCodeProvider {
    public FirebaseInstanceIDServiceCustom(){
        super();
        com.tns.Runtime.initInstance(this);
    }

    public void onTokenRefresh()  {
        java.lang.Object[] args = null;
        com.tns.Runtime.callJSMethod(this, "onTokenRefresh", void.class, args);
    }

    public boolean equals__super(java.lang.Object other) {
        return super.equals(other);
    }

    public int hashCode__super() {
        return super.hashCode();
    }

}

Local environment

Project data

{
  "nativescript": {
    "id": "com.**.**",
  "dependencies": {
    "@angular/animations": "~5.2.0",
    "@angular/common": "~5.2.0",
    "@angular/compiler": "~5.2.0",
    "@angular/core": "~5.2.0",
    "@angular/forms": "~5.2.0",
    "@angular/http": "~5.2.0",
    "@angular/platform-browser": "~5.2.0",
    "@angular/platform-browser-dynamic": "~5.2.0",
    "@angular/router": "~5.2.0",
    "angular2-jwt": "^0.2.3",
    "angular2-moment": "^1.8.0",
    "base-64": "^0.1.0",
    "buffer": "^5.0.8",
    "file-system": "^2.2.2",
    "http": "0.0.0",
    "moment-timezone": "^0.5.14",
    "nativescript-angular": "^5.2.0",
    "nativescript-background-http": "^3.1.0",
    "nativescript-camera": "^4.0.2",
    "nativescript-carousel": "^3.1.1",
    "nativescript-checkbox": "^3.0.3",
    "nativescript-drop-down": "^3.2.1",
    "nativescript-geolocation": "^4.2.3",
    "nativescript-google-maps-sdk": "^2.6.0",
    "nativescript-image-cache": "^1.1.6",
    "nativescript-imagepicker": "^5.0.2",
    "nativescript-iqkeyboardmanager": "^1.3.0",
    "nativescript-linearprogressbar-elica": "^1.0.0",
    "nativescript-localize": "^2.1.0",
    "nativescript-localstorage": "^1.1.5",
    "nativescript-number-progressbar": "^1.0.0",
    "nativescript-orientation": "^2.2.0",
    "nativescript-phone": "^1.3.1",
    "nativescript-photoviewer": "^1.4.0",
    "nativescript-pulltorefresh": "^2.1.0",
    "nativescript-theme-core": "~1.0.2",
    "nativescript-ui-chart": "^3.5.0",
    "nativescript-ui-listview": "^3.5.1",
    "ng2-translate": "^5.0.0",
    "path": "^0.12.7",
    "reflect-metadata": "~0.1.8",
    "rxjs": "^5.5.0",
    "tns-core-modules": "^4.0.0-2018-04-26-03",
    "utf8": "^3.0.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "^1.7.4",
    "@angular/compiler-cli": "~5.2.0",
    "@ngtools/webpack": "~1.9.4",
    "babel-traverse": "6.4.5",
    "babel-types": "6.4.5",
    "babylon": "6.4.5",
    "clean-webpack-plugin": "~0.1.19",
    "copy-webpack-plugin": "~4.3.0",
    "css-loader": "~0.28.7",
    "extract-text-webpack-plugin": "~3.0.2",
    "filewalker": "^0.1.3",
    "lazy": "1.0.11",
    "nativescript-dev-typescript": "^0.7.1",
    "nativescript-dev-webpack": "^0.11.0",
    "nativescript-worker-loader": "~0.8.1",
    "raw-loader": "~0.5.1",
    "resolve-url-loader": "~2.2.1",
    "tns-platform-declarations": "^3.4.1",
    "typescript": "~2.6.2",
    "uglifyjs-webpack-plugin": "~1.1.6",
    "webpack": "~3.10.0",
    "webpack-bundle-analyzer": "^2.9.1",
    "webpack-sources": "~1.1.0"
  }
}

const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

module.exports = env => { const platform = env && (env.android && "android" || env.ios && "ios"); if (!platform) { throw new Error("You need to provide a target platform!"); }

const platforms = ["ios", "android"];
const projectRoot = __dirname;
nsWebpack.loadAdditionalPlugins({ projectDir: projectRoot });

// Default destination inside platforms/<platform>/...
const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));
const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS";

const {
    // The 'appPath' and 'appResourcesPath' values are fetched from
    // the nsconfig.json configuration file
    // when bundling with `tns run android|ios --bundle`.
    appPath = "app",
    appResourcesPath = "app/App_Resources",

    // Aot, snapshot, uglify and report can be enabled by providing
    // the `--env.snapshot`, `--env.uglify` or `--env.report` flags
    // when running 'tns run android|ios'
    aot,
    snapshot,
    uglify,
    report,
} = env;
const ngToolsWebpackOptions = { tsConfigPath: join(__dirname, "tsconfig.json") };

const appFullPath = resolve(projectRoot, appPath);
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);

const config = {
    context: appFullPath,
    watchOptions: {
        ignored: [
            appResourcesFullPath,
            // Don't watch hidden files
            "**/.*",
        ]
    },
    target: nativescriptTarget,
    entry: {
        bundle: aot ?
            `./${nsWebpack.getAotEntryModule(appFullPath)}` :
            `./${nsWebpack.getEntryModule(appFullPath)}`,
        vendor: "./vendor",
    },
    output: {
        pathinfo: true,
        path: dist,
        libraryTarget: "commonjs2",
        filename: "[name].js",
    },
    resolve: {
        extensions: [".ts", ".js", ".scss", ".css"],
        // Resolve {N} system modules from tns-core-modules
        modules: [
            resolve(__dirname, "node_modules/tns-core-modules"),
            resolve(__dirname, "node_modules"),
            "node_modules/tns-core-modules",
            "node_modules",
        ],
        alias: {
            '~': appFullPath
        },
        symlinks: true
    },
    resolveLoader: {
        symlinks: false
    },
    node: {
        // Disable node shims that conflict with NativeScript
        "http": false,
        "timers": false,
        "setImmediate": false,
        "fs": "empty",
    },
    module: {
        rules: [
            { test: /\.html$|\.xml$/, use: "raw-loader" },

            // tns-core-modules reads the app.css and its imports using css-loader
            {
                test: /[\/|\\]app\.css$/,
                use: {
                    loader: "css-loader",
                    options: { minimize: false, url: false },
                }
            },
            {
                test: /[\/|\\]app\.scss$/,
                use: [
                    { loader: "css-loader", options: { minimize: false, url: false } },
                    "sass-loader"
                ]
            },

            // Angular components reference css files and their imports using raw-loader
            { test: /\.css$/, exclude: /[\/|\\]app\.css$/, use: "raw-loader" },
            { test: /\.scss$/, exclude: /[\/|\\]app\.scss$/, use: ["raw-loader", "resolve-url-loader", "sass-loader"] },

            // Compile TypeScript files with ahead-of-time compiler.
            { test: /.ts$/, use: [
                "nativescript-dev-webpack/moduleid-compat-loader",
                { loader: "@ngtools/webpack", options: ngToolsWebpackOptions },
            ]},
        ],
    },
    plugins: [
        // Vendor libs go to the vendor.js chunk
        new webpack.optimize.CommonsChunkPlugin({
            name: ["vendor"],
        }),
        // Define useful constants like TNS_WEBPACK
        new webpack.DefinePlugin({
            "global.TNS_WEBPACK": "true",
        }),
        // Remove all files from the out dir.
        new CleanWebpackPlugin([ `${dist}/**/*` ]),
        // Copy native app resources to out dir.
        new CopyWebpackPlugin([
          {
            from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
            to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
            context: projectRoot
          },
        ]),
        // Copy assets to out dir. Add your own globs as needed.
        new CopyWebpackPlugin([
            { from: "fonts/**" },
            { from: "**/*.jpg" },
            { from: "**/*.png" },
            { from: "**/*.xml" },
        ], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
        // Generate a bundle starter script and activate it in package.json
        new nsWebpack.GenerateBundleStarterPlugin([
            "./vendor",
            "./bundle",
        ]),
        // Support for web workers since v3.2
        new NativeScriptWorkerPlugin(),
        // AngularCompilerPlugin with augmented NativeScript filesystem to handle platform specific resource resolution.
        new nsWebpack.NativeScriptAngularCompilerPlugin(
            Object.assign({
                entryModule: resolve(appPath, "app.module#AppModule"),
                skipCodeGeneration: !aot,
                platformOptions: {
                    platform,
                    platforms,
                    // ignore: ["App_Resources"]
                },
            }, ngToolsWebpackOptions)
        ),
        // Does IPC communication with the {N} CLI to notify events when running in watch mode.
        new nsWebpack.WatchStateLoggerPlugin(),
    ],
};
if (report) {
    // Generate report files for bundles content
    config.plugins.push(new BundleAnalyzerPlugin({
        analyzerMode: "static",
        openAnalyzer: false,
        generateStatsFile: true,
        reportFilename: resolve(projectRoot, "report", `report.html`),
        statsFilename: resolve(projectRoot, "report", `stats.json`),
    }));
}
if (snapshot) {
    config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
        chunk: "vendor",
        projectRoot,
        webpackConfig: config,
        targetArchs: ["arm", "arm64", "ia32"],
        tnsJavaClassesOptions: { packages: ["tns-core-modules" ] },
        useLibs: false
    }));
}
if (uglify) {
    config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));

    // Work around an Android issue by setting compress = false
    const compress = platform !== "android";
    config.plugins.push(new UglifyJsPlugin({
        parallel: true,
        uglifyOptions: {
            mangle: { reserved: nsWebpack.uglifyMangleExcludes }, // Deprecated. Remove if using {N} 4+.
            compress,
        },
        cache: join(__dirname, 'webpack-cache/uglify-cache')
    }));
}
return config;

};



[NativeScript Forum]: http://forum.nativescript.org
[issues]: https://github.com/nativescript/nativescript-dev-webpack/issues?utf8=✓&q=is%3Aissue
[demo apps]: ../demo
[documentation]: https://docs.nativescript.org/best-practices/bundling-with-webpack
alexma01 commented 6 years ago

ok i solved problem adding in vendor.android.ts

require("app/notifications/FirebaseInstanceIDServiceCustom");

when i run

tns run android --bundle --env.uglify --env.aot --env.snapshot

its OK but when i run

tns run android --bundle --env.uglify --env.aot --env.snapshot --release ........

i have this error:

Unable to instantiate service com.tns.notifications.FirebaseInstanceIDServiceCustom: com.tns.NativeScriptException: Failed to create JavaScript extend wrapper for class 'com/tns/notifications/FirebaseInstanceIDServiceCustom'
Burgov commented 6 years ago

I'm running into a similar error and found that either removing --release OR --env.snapshot resolves the error. Can you confirm that @alexma01 ?

alexma01 commented 6 years ago

Hi @Burgov , hi added a java classes into webpack.config.ts and REMOVED from vendor.android.ts

if (snapshot) {
        config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
            chunk: "vendor",
            projectRoot,
            webpackConfig: config,
            targetArchs: ["arm", "arm64", "ia32"],
            tnsJavaClassesOptions: { 
                packages: ["tns-core-modules" ],
                modules: [  
                    'app/notifications/FirebaseInstanceIDServiceCustom.js',
                    'app/notifications/FirebaseMessagingServiceCustom.js',
                    'app/notifications/NotificationsReceiverCustom.js'
                ]
            },
            useLibs: false
        }));
    }

and i solved problem.

Now i can run tns run android --bundle --env.uglify --env.aot --env.snapshot --release ........