Git Product home page Git Product logo

j2cl's Introduction

J2CL · Build Status

Seamless Java in JavaScript applications that tightly optimizes with Closure Compiler


J2CL is a powerful, simple and lightweight transpiler from Java to Closure style JavaScript.

  • Get the best out of Java and JavaScript. You no longer need to choose between the two or lock into a specific framework or a language. Choose the right language at the right place and hire the best talent for the job.

  • Get it correct the first time. The robust run-time type checking based on the strong Java type system combined with the advanced cross language type checks catches your mistakes early on.

  • Provides massive code reuse. J2CL closely follows the Java language semantics. This reduces surprises, enables reuse across different platforms and brings most popular Java libraries into your toolkit including Guava, Dagger and AutoValue.

  • Modern, fresh and blazing fast. Powered by Bazel, J2CL provides a fast and modern development experience that will make you smile and keep you productive.

  • Road tested and trusted. J2CL is the underlying technology of the most advanced GSuite apps developed by Google including GMail, Inbox, Docs, Slides and Calendar.

Guides

Get Support

Caveat Emptor

J2CL is production ready and actively used by many of Google's products, but the process of adapting workflows and tooling for the open-source version is not yet finalized.

Wasm support is fully working but should be considered as work-in-progress since the related parts of the spec is not finalized yet. We are working closely with W3C and V8 team to finalize it and make it available in all browsers.

You can see what we are working on here.

Last, the workflow is not yet supported in Windows. You can contribute to make this a reality. Coordinate and follow the progress of this effort here. For developers that want to use Windows as their platform we recommend installing under WSL (Windows Subsystem for Linux).

Stay tuned!

J2CL vs. GWT?

In early 2015, Google GWT team made a difficult but necessary decision to work on a new alternative product to enable Java for the Web.

It was mostly due to changing trends in the web ecosystem and our new internal customers who were looking at Java on the Web not as an isolated ecosystem but an integral part of their larger stack. It required a completely new vision to create tools from the ground up, that are tightly integrated with the rest of the ecosystem. A modern architecture, that is reliable, fast and provides a quick iteration cycle.

There was no practical way to achieve those goals completely incrementally out of GWT. We started from scratch using everything we learned from working on GWT over the years. In the meantime, we kept GWT steering committee members in the loop and gave contributors very early access so they could decide to build the next version of GWT on J2CL.

The strategy has now evolved GWT3 to an SDK focused on libraries and enterprise tooling which was one of the strongest points of GWT all along.

We think that such separation of concerns is crucial part of the success of the both projects and will provide the best results for the open source community.

Contributing

Read how to contribute to J2CL.

Licensing

Please refer to the license file.

Disclaimers

J2CL is not an official Google product and is currently in 'alpha' release for developer preview.

j2cl's People

Contributors

12wrigja avatar brad4d avatar cpovirk avatar cushon avatar dankurka avatar eamonnmcmanus avatar gkdn avatar impanyu avatar jdramaix avatar jparachoniak avatar kevinoconnor7 avatar kluever avatar lauraharker avatar martinkretzschmar avatar mollyibot avatar niloc132 avatar noamrabbani avatar nreid260 avatar obinnabii avatar ptmphuong avatar realityforge avatar ringw avatar rluble avatar stalcup avatar stefanhaustein avatar tadeegan avatar tbroyer avatar tjgq avatar treblereel avatar varomodt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

j2cl's Issues

j2cl_workspace.bzl: Make GWT dependency reproducible

Is your feature request related to a problem? Please describe.
I spent half an hour today to find the source of a mysterious NullPointerException-related error that appeared after upgrading to the latest commit. When trying to build a minimal testcase for a bug report. the error disappeared.

Turns out: GWT has also updated to make this work, yet Bazel still had the old GWT tarball for "https://gwt.googlesource.com/gwt/+archive/master.tar.gz" (https://github.com/google/j2cl/blob/master/build_defs/internal_do_not_use/j2cl_workspace.bzl#L149) in its cache.

Describe the solution you'd like
Make the GWT dependency somehow reproducible.

Describe alternatives you've considered
Running bazel clean --expunge every time a J2CL-related problem occurs on all machines.

Additional context

Is there a plan to support chunking?

If this question is related to build, please include version of Bazel that you are running J2CL with:

Build label: 0.27.0
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Mon Jun 17 13:03:58 2019 (1560776638)
Build timestamp: 1560776638
Build timestamp as int: 1560776638

I'm wondering if J2CL plans to support JS chunking? We are very happy with J2CL so far. But, if we want to build a large application and serve it efficiently, we're worried about packaging everything up in one JS target.

Surely Gmail, Calendar, and the other examples cited, must have some wiring for chunking built in. Just curious if there is a plan or ideas to do this with J2CL.

I am a Java developer interested in contributing.

Hi guys, I didn't see a better place documented to ask this so hopefully this is the right location.

I am a Java developer with 15 years experience who is looking for an OSS project to contribute to and this one looked interesting. Are you currently looking for developer contributors?

My primary skill set also includes Oracle, Perl and Linux. I am also proficient in JavaScript, JSON, XML, AJAX, HTML, CSS, Node and Python.

Thanks and please let me know.

Help with modified sample (Calendar cannot be resolved to a type)

I was wondering if you could help me understand what it is missing. I am unable to build after adding some imports and calls to the "j2cl\samples\helloworld\src\main\java\com\google\j2cl\samples\helloworldlib\HelloWorld.java" as follows:

package com.google.j2cl.samples.helloworldlib;

import jsinterop.annotations.JsType;
import java.util.Date;
import java.util.Calendar;

/**
 * A simple hello world example.
 *
 * <p>Note that it is marked as @JsType as we would like to call have whole class available to use
 * from JavaScript.
 */
@JsType
public class HelloWorld {

  public static String getHelloWorld() {
    **Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 0);
    Date tod = new Date();
    return "Hello from Java!" + tod.toString() + " " + cal.toString();
  }
}

Running bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworld --incompatible_disable_deprecated_attr_params=false --verbose_failures gives me the following:

[587 / 606] Transpiling to JavaScript @com_google_j2cl//jre/java:jre; 30s worker ... (4 actions, 3 running)
ERROR: D:/devtools/eclipse/neon/workspace/j2cl/samples/helloworld/src/main/java/com/google/j2cl/samples/helloworldlib/BUILD:13:1: Transpiling to JavaScript //src/main/java/com/google/j2cl/samples/helloworldlib:helloworldlib failed (Exit 1)
Error:C:\Users\user\AppData\Local\Temp\j2cl_sources4775520020060075074\src\main\java\com\google\j2cl\samples\helloworldlib\HelloWorld.java:20: The import java.util.Calendar cannot be resolved
Error:C:\Users\user\AppData\Local\Temp\j2cl_sources4775520020060075074\src\main\java\com\google\j2cl\samples\helloworldlib\HelloWorld.java:32: Calendar cannot be resolved to a type
Error:C:\Users\user\AppData\Local\Temp\j2cl_sources4775520020060075074\src\main\java\com\google\j2cl\samples\helloworldlib\HelloWorld.java:32: Calendar cannot be resolved
Error:C:\Users\user\AppData\Local\Temp\j2cl_sources4775520020060075074\src\main\java\com\google\j2cl\samples\helloworldlib\HelloWorld.java:33: Calendar cannot be resolved to a variable
4 error(s), 0 warning(s).
Target //src/main/java/com/google/j2cl/samples/helloworld:helloworld failed to build
INFO: Elapsed time: 237.551s, Critical Path: 86.52s
INFO: 568 processes: 529 local, 39 worker.
FAILED: Build did NOT complete successfully
FAILED: Build did NOT complete successfully

I'm completely new to this bazel, GWT, Closure, transpilers world, so being able to setup bazel and build (behind a corporate NTLM proxy) the provided sample was already a personal achievement. However, I'm still struggling to understand how to make j2cl work with simple JDK imports and maven stored libraries (it would be nice if you could provide more examples... perhaps how to transpile a Java class that uses guava.jar from a maven repository).

Build label: 0.29.0
Build target: bazel-out/x64_windows-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Wed Aug 28 14:35:37 2019 (1567002937)
Build timestamp: 1567002937
Build timestamp as int: 1567002937

Thanks in advance!

MethodSorters.java in the wrong folder

Describe the bug
MethodSorters.java in the wrong folder org/junit/runner, but should be org/junit/runners

To Reproduce
Check package in the java file vs. folder of the file

Expected behavior
Move MethodSorters.java to org/junit/runners

Can't build the whole sample workspace

Describe the bug
Can't build the whole sample workspace

To Reproduce
I run bazel build //... in the sample folder. I got the following message:

[kostik@kostik-laptop helloworld]$ bazel build //...
INFO: SHA256 (https://github.com/google/j2cl/archive/master.zip) = b207fe05be1ce2f9f3a48bfa7c1e805045ea6adcc1df51ec7e9822bb5286c66c
ERROR: /home/kostik/Projects/j2cl/samples/helloworld/javatests/com/google/j2cl/samples/helloworldlib/BUILD:3:1: file '@com_google_j2cl//build_defs:rules.bzl' does not contain symbol 'j2cl_test'
ERROR: /home/kostik/Projects/j2cl/samples/helloworld/javatests/com/google/j2cl/samples/helloworldlib/BUILD:5:1: name 'j2cl_test' is not defined (did you mean 'java_test'?)
ERROR: package contains errors: javatests/com/google/j2cl/samples/helloworldlib
ERROR: error loading package 'javatests/com/google/j2cl/samples/helloworldlib': Package 'javatests/com/google/j2cl/samples/helloworldlib' contains errors
INFO: Elapsed time: 2.569s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (3 packages loaded)

I tried both zip version and local repo version

Expected behavior
Expect it to be build fine.

undeclared inclusion(s) in rule '@com_google_protobuf//:protoc_lib'

Hi

I am getting the following output when trying to build the helloworld using bazel on OS X.
It looks like I'm missing something related to protobuf. I'm used to gradle and GWT but completely new to j2cl and bazel.

Is there something I forgot to setup?

/private/var/tmp/_bazel_dvekeman/5beb477a3151b2f6be589952cc7c0456/external/com_google_protobuf/BUILD:260:1: undeclared inclusion(s) in rule '@com_google_protobuf//:protoc_lib':
this rule is missing dependency declarations for the following files included by 'external/com_google_protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc':

(see bottom for the full output)

OS: OS X High Sierra (10.13.6)

Bazel version:
(note: I tried with bazel installed as a binary as well as bazel installed using Homebrew.)

Build label: 0.18.1-homebrew
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Fri Nov 2 11:16:56 2018 (1541157416)
Build timestamp: 1541157416
Build timestamp as int: 1541157416
helloworld (master) $ bazel build --verbose_failures src/main/java/com/google/j2cl/samples/helloworld:helloworld
INFO: Analysed target //src/main/java/com/google/j2cl/samples/helloworld:helloworld (0 packages loaded).
INFO: Found 1 target...
ERROR: /private/var/tmp/_bazel_dvekeman/5beb477a3151b2f6be589952cc7c0456/external/com_google_protobuf/BUILD:260:1: undeclared inclusion(s) in rule '@com_google_protobuf//:protoc_lib':
this rule is missing dependency declarations for the following files included by 'external/com_google_protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc':
  '/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/stdlib.h'
  '/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/Availability.h'
 ...
 '/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/math.h'
Target //src/main/java/com/google/j2cl/samples/helloworld:helloworld failed to build
INFO: Elapsed time: 3.578s, Critical Path: 3.31s
INFO: 229 processes: 229 local.
FAILED: Build did NOT complete successfully

(full stack: https://gist.github.com/dvekeman/eaae8301c96e00022d63771c8300ab5d)

update made it bit more scroll friendly..

Cannot pass CSS into `j2cl_application`

Describe the bug
The rules_closure package has a rule called closure_js_binary, which J2CL uses to build Closure JS binaries.

The closure_js_binary declaration supports a CSS flag, which accepts a closure_css_binary rule, so that style rewriting can be enabled through GSS.

When using j2cl_application, however, there is no css attribute that can be passed through to Closure. This is true also of js_devserver, which j2cl_application additionally calls into to enable local dev server support.

To Reproduce

  1. use J2CL
  2. try to pass css into j2cl_application
  3. it doesn't work

Bazel version
Please include version of Bazel that you are running J2CL with:

Build label: 0.27.0
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Mon Jun 17 13:03:58 2019 (1560776638)
Build timestamp: 1560776638
Build timestamp as int: 1560776638

Expected behavior

  1. it shouldn't eat arguments you pass through to other libraries?
  2. but it does?

IllegalArgumentException when a method reference for a varags method is passed as a @JsFunction interface with more parameters

J2CL compilation fails when trying to compile the following code:

JsArray<Function> myArray = new JsArray<>();
myArray.forEach(Function::call);

The stacktrace is the following:

com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalArgumentException
    at com.google.common.util.concurrent.Futures.wrapAndThrowUnchecked (Futures.java:1329)
    at com.google.common.util.concurrent.Futures.getUnchecked (Futures.java:1314)
    at com.google.j2cl.transpiler.J2clTranspiler.transpile (J2clTranspiler.java:110)
    at com.vertispan.j2cl.DevMode.transpile (DevMode.java:497)
    at com.vertispan.j2cl.DevMode.main (DevMode.java:384)

@niloc132 traced back the issue to this check failing:

      if (!targetMethodDescriptor.isStatic()
          && (qualifier == null || qualifier instanceof JavaScriptConstructorReference)) {
        // The qualifier for the instance method becomes the first parameter. Method references to
        // instance methods without an explicit qualifier use the first parameter in the functional
        // interface as the qualifier for the method call.
        checkArgument(
            parameters.size() == targetMethodDescriptor.getParameterTypeDescriptors().size() + 1);
        qualifier = parameters.get(0).getReference();
        forwardingParameters = parameters.subList(1, parameters.size());
      }

The forEach call get expanded to:

myArray.forEach((f, index, arr) -> f.call(index, arr));

Te expanded version compiles without issue.

Rename BUILD to BUILD.bazel

It seems that the preferred name for bazel build files is BUILD.bazel according to bazelbuild/bazel#4517

Would this project (and jsinterop-generator and elemental2) accept PRs that moved to the preferred build file name?

System.getProperty doesn't seem to work

Describe the bug
I'm trying to use System.getProperty to access a Closure --define=, provided via defs. I can't seem to get it to work no matter what I do.

To Reproduce
Example.java:

package app;
import jsinterop.annotations.JsType;

@JsType
public class Config {
  public static String getAppVersion() {
    return System.getProperty("APP_VERSION", "default_java");
  }
}

module.js:

goog.module('app');

/**
 * Defines the app version.
 *
 * @public
 * @define {!string} APP_VERSION
 */
const version = goog.define('APP_VERSION', 'default_js');

exports = {
  version: version
};

config-test.js:

goog.setTestOnly();

const app = goog.require('app');
const Config = goog.require('app.Config');


testSuite({
  testFrameworkVersion() {
    // tests framework version from JS
    assert(!!app.version);
  },

  testCompareVersions() {
    // tests framework version from J2CL
    assertEquals(
        app.version,
        Config.getAppVersion());
  }
});

BUILD.bazel:

package(default_visibility = ["//visibility:public"])
load("@com_google_j2cl//build_defs:rules.bzl", "j2cl_library")
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_test")

j2cl_library(
    name = "Config",
    srcs = ["Config.java"],
)

closure_js_test(
    name = name,
    srcs = "config-test.js",
    html = "config_test.html",
    deps = [
      "@io_bazel_rules_closure//closure/library:testing",
      ":Config",
    ],
    defs = [
        "--define=APP_VERSION=abc123",
    ],
)

(config_test.html omitted because it basically just includes the JS).

The build then fails with the following exception:

java.lang.NullPointerException: NAME APP_VERSION 20 [length: 41] [source_file: bazel-out/darwin-dbg/bin/java/app/Config.js.zip!/app/Config.impl.java.js]
	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:895)
	at com.google.javascript.jscomp.RemoveUnusedCode.getVarForNameNode(RemoveUnusedCode.java:719)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseNameNode(RemoveUnusedCode.java:574)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseNode(RemoveUnusedCode.java:420)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseChildren(RemoveUnusedCode.java:1122)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseCall(RemoveUnusedCode.java:631)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseNode(RemoveUnusedCode.java:348)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseChildren(RemoveUnusedCode.java:1122)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseNode(RemoveUnusedCode.java:429)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseChildren(RemoveUnusedCode.java:1122)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseFunction(RemoveUnusedCode.java:1258)
	at com.google.javascript.jscomp.RemoveUnusedCode.access$1200(RemoveUnusedCode.java:93)
	at com.google.javascript.jscomp.RemoveUnusedCode$Continuation.apply(RemoveUnusedCode.java:1586)
	at com.google.javascript.jscomp.RemoveUnusedCode.traverseAndRemoveUnusedReferences(RemoveUnusedCode.java:269)
	at com.google.javascript.jscomp.RemoveUnusedCode.process(RemoveUnusedCode.java:250)
	at com.google.javascript.jscomp.PhaseOptimizer$NamedPass.process(PhaseOptimizer.java:317)
	at com.google.javascript.jscomp.PhaseOptimizer.process(PhaseOptimizer.java:232)
	at com.google.javascript.jscomp.Compiler.performOptimizations(Compiler.java:2418)
	at com.google.javascript.jscomp.Compiler.lambda$stage2Passes$1(Compiler.java:799)
	at com.google.javascript.jscomp.CompilerExecutor$2.call(CompilerExecutor.java:102)
	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)

Outputs

goog.module('app.Config$impl');

const j_l_Object = goog.require('java.lang.Object$impl');
const $Util = goog.require('nativebootstrap.Util$impl');

class Config extends j_l_Object {
 
 constructor() {
  Config.$clinit();
  super();
  this.$ctor__app_Config__();
 }
 
 $ctor__gust_Config__() {
  this.$ctor__java_lang_Object__();
 }
 /** @return {?string} */
 static getAppVersion() {
  Config.$clinit();
  return $Util.$getDefine("APP_VERSION", "default_java");
 }
 
 static $clinit() {
  Config.$clinit = () =>{};
  Config.$loadModules();
  j_l_Object.$clinit();
 }
 /** @return {boolean} */
 static $isInstance(/** ? */ instance) {
  return instance instanceof Config;
 }
 
 static $loadModules() {}
 
}
$Util.$setClassMetadata(Config, 'app.Config');

exports = Config; 
//# sourceMappingURL=Config.js.map

Bazel version
2.0.0

Expected behavior
I would expect it not to error, firstly. Then, I would expect it to emit abc123 in place of the string in the define.

If I leave the define unspecified, the error disappears, but then, of course, the default string is used, which fails the test.

System.getProperty doesn't emit goog.require

Observed in jsinterop-base, where jsinterop.js contains the following:

/**
 * This file provides the @defines for jsinterop configuration options.
 * See InternalPreconditions.java for details.
 */

goog.provide('jsinterop');

// Note that disabling checking only disables it for production.

/** @define {string} */
goog.define('jsinterop.checks', 'DISABLED');

Then, InternalPreconditions.java uses this:

private static final boolean IS_TYPE_CHECKED = 
                getProperty("jsinterop.checks").equals("ENABLED");

Currently, System.getProperty is implemented with JsMethod for J2CL (and a magic method for gwt2):

  @JsMethod(name = "$getDefine", namespace = "nativebootstrap.Util")
  public static native String getProperty(String key);

The Util.$getDefine method only calls goog.getObjectByName with the parameter, not a compiletime string, and closure-compiler doesn't seem to be able to detect this anyway.

The result is a runtime NPE in both BUNDLE and ADVANCED compilation modes, unless jsinterop.js is manually added as an --entry_point, or a new define is added to the build directly (and in that case, --define isn't used by BUNDLE, by design).

Historically, it looks like J2CL used to have a pass which would examine System.getProperty calls and do something with them - perhaps the same idea could be used again to emit goog.require calls to correctly require that non-native.js files are loaded.

This might be worth generalizing, so that non-native.js files can be depended on in general? It would add an extra step to use a system property which isn't ideal, but does prevent the need for j2cl to recognize specific pieces of code to be transpiled.

This would also allow jre.js to keep working if classMetadata and checkedMode were moved - while there is a goog.provide('jre.checks') in that file, nothing actually ever depends on jre.checks, so could stop working if the file were split into one file per provide.

JsInterop namespace seems to require being a closure namespace

This seems to be a fairly recent change. As an example, to expose JS static fields on a class:

@JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
public class Node extends JavaScriptObject {
  /**
   * The node is an {@link Element}.
   */
  @JsProperty(namespace = "Node")
  public static short ELEMENT_NODE;

References to these end up being compiled to $synthetic__Node.ELEMENT_NODE, where $synthetic__Node is defined as

let $synthetic__Node = goog.forwardDeclare('Node');

This way of referencing the native Node type seems to be an error in closure-compiler's ADVANCED mode:

Element$$Overlay.impl.java.js:5: ERROR - Imported Closure namespace "Node" never defined.

If this is a deliberate breaking change, it seems easy enough to work around, if a bit ugly, by moving the namespace to the name, and repeating the field's java name in the string:

  @JsProperty(namespace = JsPackage.GLOBAL, name = "Node.ELEMENT_NODE")
  public static short ELEMENT_NODE;

This results in the expected compiled JS: Node.ELEMENT_NODE.

Confusing errors if you use closure_repositories() and setup_j2cl_workspace()

Our project was already using rules_closure. When I added setup_j2cl_workspace() to the WORKSPACE I get a confusing error:

ERROR: /home/ribrdb/Derivita/WORKSPACE:450:1: Traceback (most recent call last):
        File "/home/ribrdb/Derivita/WORKSPACE", line 450
                setup_j2cl_workspace()
        File "/home/ribrdb/.cache/bazel/_bazel_ryan/a393754d6dfbc9daf01e7035f8b22381/external/com_google_j2cl/build_defs/internal_do_not_use/j2cl_workspace.bzl", line 14, in setup_j2cl_workspace
                native.maven_jar(name = "com_google_auto_common", a...")
Cannot redefine repository after any load statement in the WORKSPACE file (for repository 'com_google_auto_common')
ERROR: Error evaluating WORKSPACE file

Maybe you should do something like:

if "io_bazel_rules_closure" not in native.existing_rules():
    closure_repositories(
        omit_com_google_protobuf = True,
        omit_com_google_auto_common = True,
    )

Support the workflow under Windows.

The current release does not work under Windows.

There are a few known issues:

  1. bazel and all the required dependencies are cumbersome to setup in Windows.
  2. some path handling in J2CL does not work well with windows paths.

Detailed documentation on how to setup under Windows would be very helpful and address the first point.

For now we recommend to use WSL under Windows 10.

helloworld_dev_server and helloworld_dev don't generate source maps

Describe the bug
No source map is generated when running the helloworld_dev_server task or the helloworld_dev task.

To Reproduce
cd samples/helloworld
ibazel run src/main/java/com/google/j2cl/samples/helloworld:helloworld_dev_server

Navigating to the source map's url (http://localhost:6006/HelloWorld.js.map) shows this error message instead of a source map:
"No srcs found in transitive closure with path component prefix matching request path."

Similarly, a dev build using bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworld_dev generates an empty file for the source map:
bazel-bin/src/main/java/com/google/j2cl/samples/helloworld/helloworld_dev.js.map

Bazel version
Build label: 1.1.0
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Mon Oct 21 08:47:13 2019 (1571647633)
Build timestamp: 1571647633
Build timestamp as int: 1571647633

Expected behavior
I'd like to have source maps for my J2CL projects during development to aid in debugging. Without this, it is a step backwards from GWT 2.

Using @JsProperty for properties with periods in the name causes type errors

Hi, thanks for your work on this project!
I'm not entirely sure whether this is a bug or a feature request, but definitely an interesting case I ran into.

Describe the bug

I am trying to use the (archived, yet still in prod) Settings API in B2G using JsInterop types. Very briefly, the SettingsLock#get(key) method takes a settings key (which is generally one of these), and returns a DOMRequest object. If reading from settings succeeds, the request's result object will look something like this:

"result": {
  "deviceinfo.os": "2.0.0"
}

So, in this case, the value I am interested in is "2.0.0".

Here is a very simplified version of the types I'm using:

// Navigator.java

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class Navigator {

    @JsProperty(name = "mozSettings")
    public native SettingsManager getSettings();
}

// SettingsManager.java

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class SettingsManager {

    @JsMethod
    public native SettingsLock createLock();
}

// SettingsLock.java

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class SettingsLock {

    @JsMethod
    public native <T> DOMRequest<T> get(String key);
}

// Callback.java

@JsFunction
public class Callback {
    public run();
}

// DOMRequest.java

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class DOMRequest<T> {

    @JsProperty
    public native T getResult();

    @JsProperty(name = "onsuccess")
    public native void setOnSuccess(Callback onSuccess);
}

// DeviceOSResult.java

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class DeviceOSResult {

    @JsProperty(name = "deviceinfo.os")
    public native String getDeviceOS();
}

And then I would want to use this like so:

// DeviceSettings.java

public class DeviceSettings {

    public void getDeviceOS(Navigator navigator) {
        SettingsLock lock = navigator.getSettings().createLock();
        DOMRequest<DeviceOSResult> request = lock.get("deviceinfo.os");
        request.setOnSuccess(() -> {
            String os = request.getResult().getDeviceOS();
            // Do something with OS
        });
    }
}

This code transpiles to (simplified):

var os = request.result.deviceinfo.os;

And then instead of the value, as you may expect, I get:

TypeError: Cannot read property 'os' of undefined

You can try reproduce this with the code above.

Expected behavior

This is definitely a strange API, and indeed it was not accepted and didn't make it's way into the spec. It is still implemented in B2G, however, and there are devices in the wild using it.

That being said, ideally, I would expect this to transpile to something like:

var os = request.result["deviceinfo.os"];

However, I would be happy to hear from you all if there might be a better, simpler way of getting this value from the result object, since this is such a niche API.
So I'm happy to hear other options or discuss how to potentially fix properties like this.

Either way, thank you for you time! 💟💟💟

How to convert arbitrary maven dependency to j2cl_library in Bazel

I am attempting to convert a simple project to j2cl using Bazel but I am unable to figure out how to turn an arbitrary dependency into a j2cl_library. I can not find any examples that do not define j2cl_library in terms of local source.

So if I have a maven dependency of my application that I want to compile against. It includes annotations that drive an annotation processor.

The dependency (that includes annotations) is declared via:

maven_jar(
    name = "org_realityforge_arez_core",
    artifact = "org.realityforge.arez:arez-core:0.132",
    sha1 = "6ee17e9fa56cfac5236c3a36b9e11bc0772825fc",
)

The annotation processor is declared via:

maven_jar(
    name = "org_realityforge_arez_processor",
    artifact = "org.realityforge.arez:arez-processor:0.132",
    sha1 = "8d81984baf6273a3f8cae8cc2701cb3807921dab",
)

java_plugin(
    name = "arez_processor",
    processor_class = "arez.processor.ArezProcessor",
    deps = ["@org_realityforge_arez_processor//jar"],
)

The build of my code is defined via

j2cl_import(
    name = "org_realityforge_arez_core-j2cl",
    jar = "@org_realityforge_arez_core//jar",
)

j2cl_library(
    name = "react4j-todomvc-j2cl",
    srcs = glob(["src/main/java/react4j/todomvc/**/*.java"]),
    plugins = ["arez_processor"],
    deps = [
        "org_realityforge_arez_core-j2cl",
        ...
    ],
)

This get's my local code compiled but obviously does not j2cl compile that arez_core dependency. The assumption being that j2cl_import is only really for "annotations" and other .class file inclusions in the compile but it does not trigger a j2cl compile. So I end up with with my local source code compiled but not arez-core.

For a a simple reproduction of this issue you can see the code at

https://github.com/react4j/react4j-todomvc/tree/raw_bazel_j2cl

A log of a failed build is available at

https://travis-ci.org/react4j/react4j-todomvc/builds/500993432

It is probably fairly obvious what my problem is for a bazel user but if you could point me in the right direction that would be fasntastic.

Can't run integration tests

Describe the bug
When I run the test command I got errors
[kostik@kostik-laptop j2cl]$ bazel test //transpiler/javatests/com/google/j2cl/transpiler/integration/...
ERROR: /home/kostik/Projects/j2cl/transpiler/javatests/com/google/j2cl/transpiler/integration/box2d/BUILD:8:1: no such package 'third_party/java/jbox2d': BUILD file not found on package path and referenced by '//transpiler/javatests/com/google/j2cl/transpiler/integration/box2d:box2d_j2cl'
ERROR: Analysis of target '//transpiler/javatests/com/google/j2cl/transpiler/integration/box2d_noclassmetadata_checksmin:compiled_test_bin' failed; build aborted: no such package 'third_party/java/jbox2d': BUILD file not found on package path
INFO: Elapsed time: 2.386s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (230 packages loaded, 65 targets configured)
FAILED: Build did NOT complete successfully (230 packages loaded, 65 targets configured)
currently loading: jre/java/javaemul/internal/vmbootstrap/primitives

To Reproduce
See the command above

Expected behavior
Tests pass or at least run successfully to completion.

Importing annotated bytecode

Describe the bug
I'm trying to import a JAR of JsInterop-annotated Java bytecode, and it isn't working :(

To Reproduce

Setup/inputs

I'm trying to compile the following Kotlin object via J2CL:

package javatests.language

import jsinterop.annotations.JsType

@JsType
class KotlinObject {
  fun hello(): String = "Kotlin"
}

I set it up via these Bazel rules:

def _cross_kt_lib(name, srcs, deps = []):
        kt_jvm_library(
            name = "%s-kt" % name,
            srcs = srcs,
            deps = [
                "@com_google_j2cl//:jsinterop-annotations",
            ] + deps,
        )

        j2cl_import(
            name = "%s-j2cl" % name,
            jar = ":%s-kt" % name,
        )

cross_lib(
    name = "KotlinObject",
    srcs = ["KotlinObject.kt"],
    deps = [":JavaObject"],
)

Then, I invoke it via JS:

goog.module('main');

const KotlinObject = goog.require('javatests.language.KotlinObject');


/**
 * Main function, dispatched on page load.
 */
function main() {
  console.log(`Hello from ${KotlinObject.hello()}!`);
}

// Bind `main` to page load.
window.addEventListener('load', main);

Which I build via:

closure_js_library(
    name = "main",
    srcs = ["main.js"],
    deps = [
        ":KotlinObject-j2cl",
    ],
)

j2cl_application(
    name = "example",
    entry_points = ["main"],
    deps = [":main"],
)

Outputs

The problem is, the outputs end up empty:

KotlinObject-j2cl.i.js:

(empty)

KotlinObject-j2cl.js.zip: Does not exist

Also, the build fails with the following error:

ERROR: /.../javatests/language/BUILD.bazel:29:1: Checking 1 JS files in //javatests/language:main failed (Exit 1)
javatests/language/main.js:5: ERROR - Namespace not provided by any srcs or direct deps of //javatests/language:main.
const KotlinObject = goog.require('javatests.language.KotlinObject');
                                  ^
  ProTip: "CR_NOT_PROVIDED" or "strictDependencies" can be added to the `suppress` attribute of:
  //javatests/language:main

1 error(s), 0 warning(s)

Target //javatests/language:example failed to build

Bazel version

Bazelisk version: development
Build label: 2.0.0
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Thu Dec 19 12:33:30 2019 (1576758810)
Build timestamp: 1576758810
Build timestamp as int: 1576758810

Expected behavior
Since the Kotlin source would have been converted to Java bytecode by the time it is loaded by j2cl_import, I would imagine it would work to produce J2CL-driven JS, with Kotlin as the original source?

Packaging J2clCommandLineRunner as a standalone binary

I'd like to build j2cl as a standalone binary to be used in a non-bazel build system (buck). I fond that it will probably be easiest to build j2cl with bazel, get the binary and use that in buck (as opposed to building j2cl in buck and using the build target).

The issue I'm encountering is the size of the runfiles - it's more than 500MB, which seems like a lot to include in a single cli tool, Also, from what I understand from the documentation, those runfiles are needed in order to run J2clCommandLineRunner.

I'm new to bazel and j2cl, so I might be doing something wrong. Here's what I'm doing:

JC2CL_DIR=/data/users/${USER}/j2cl_build
mkdir $JC2CL_DIR
cd $JC2CL_DIR

git clone https://github.com/google/j2cl.git --depth=1

# Build

cd $JC2CL_DIR/j2cl

bazel build transpiler/java/com/google/j2cl/transpiler:J2clCommandLineRunner

# Put the result files in a single place
OUT_DIR=$JC2CL_DIR/out
mkdir -p $OUT_DIR
cp ./bazel-bin/transpiler/java/com/google/j2cl/transpiler/J2clCommandLineRunner $OUT_DIR
cp ./bazel-bin/transpiler/java/com/google/j2cl/transpiler/J2clCommandLineRunner.runfiles $OUT_DIR -L -r

Note the -L when copying the runfiles - as I can't rely on cache - as I want to distribute this binary to other machines.

$ cd out
$ du . -sh
582M	.
$ ls -l
total 16
-r-xr-xr-x. 1 XXX users 14223 Feb  2 22:38 J2clCommandLineRunner
drwxr-xr-x. 1 XXX users  1118 Feb  2 22:38 J2clCommandLineRunner.runfiles
$

Am I doing something wrong? Is there a better way to package J2clCommandLineRunner?

Thanks!

If this question is related to build, please include version of Bazel that you are running J2CL with:
$ bazel version

$ bazel version
Build label: 2.0.0
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Thu Dec 19 12:30:18 2019 (1576758618)
Build timestamp: 1576758618
Build timestamp as int: 1576758618

Non-trivial example?

This looks pretty great (in theory). However, I fear that, like many google open-source projects, the tech is amazing but detailed explanations and non-trivial real-world examples are missing. Two years later the googlers responsible for maintaining the repo get assigned to other projects, lose interest, and it's left to die on the vine.

What's the long-term plan here?

Error when using a lambda which works when replaced with anonymous class

Describe the bug
I have a certain implementation that where i am initializing a field using lambda as the following form

private SenderSupplier senderSupplier = new SenderSupplier(() -> new RequestSender<R, S>() {
    });

which fails the j2cl compilation, when i change the implementation to use anonymous class it works.

private SenderSupplier senderSupplier = new SenderSupplier(new Supplier<RequestRestSender>() {
        @Override
        public RequestRestSender get() {
            return new RequestSender<R, S>() {
            };
        }
    });

To Reproduce
I have a fork of this j2cl repository in which the bug is reproducible here

https://github.com/vegegoku/j2cl

the bug is reproduced in the j2cl hello World sample

$ cd j2cl/samples/helloworld
$ bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworld

The exception

DEBUG: Rule 'io_bazel_rules_closure' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "bb2e546beaeeb7d69bf5d5fbde94efcb8ae216b6d585942e02cfea7f8609747c"
DEBUG: Rule 'bazel_skylib' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "bce240a0749dfc52fab20dce400b4d5cf7c28b239d64f8fd1762b3c9470121d8"
DEBUG: Rule 'com_google_protobuf' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "9510dd2afc29e7245e9e884336f848c8a6600a14ae726adb6befdb4f786f0be2"
DEBUG: Rule 'org_gwtproject_gwt' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "f081f0c1f4f31a8be012c5d479777db13d01db5c8c73edf6a8800d9458b7b553"
INFO: Analysed target //src/main/java/com/google/j2cl/samples/helloworld:helloworld (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /mnt/CODE/GIT/J2CL/j2cl/samples/helloworld/src/main/java/com/google/j2cl/samples/helloworldlib/BUILD:12:1: Transpiling to JavaScript //src/main/java/com/google/j2cl/samples/helloworldlib:helloworldlib failed: Worker process did not return a WorkResponse:

---8<---8<--- Start of log snippet, file at /home/vegegoku/.cache/bazel/_bazel_vegegoku/c180e8a0f82bbd4569c981778e99438b/bazel-workers/worker-10-J2cl.log ---8<---8<---
[... truncated ...]
e)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
        at com.google.j2cl.ast.AstUtils.clone(AstUtils.java:672)
        at com.google.j2cl.ast.MethodCall.clone(MethodCall.java:97)
        at com.google.j2cl.ast.MethodCall.clone(MethodCall.java:29)
        at com.google.j2cl.ast.AstUtils.lambda$clone$0(AstUtils.java:672)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
        at com.google.j2cl.ast.AstUtils.clone(AstUtils.java:672)
        at com.google.j2cl.ast.visitors.NormalizeConstructors$2.rewriteNewInstance(NormalizeConstructors.java:330)
        at com.google.j2cl.ast.visitors.NormalizeConstructors$2.rewriteNewInstance(NormalizeConstructors.java:321)
        at com.google.j2cl.ast.AbstractRewriter.postProcessNewInstance(AbstractRewriter.java:987)
        at com.google.j2cl.ast.Visitor_NewInstance.visit(Visitor_NewInstance.java:16)
        at com.google.j2cl.ast.NewInstance.accept(NewInstance.java:82)
        at com.google.j2cl.ast.Visitor_BinaryExpression.visitMembers(Visitor_BinaryExpression.java:36)
        at com.google.j2cl.ast.Visitor_BinaryExpression.visit(Visitor_BinaryExpression.java:14)
        at com.google.j2cl.ast.BinaryExpression.accept(BinaryExpression.java:110)
        at com.google.j2cl.ast.Visitor_ExpressionStatement.visitMembers(Visitor_ExpressionStatement.java:33)
        at com.google.j2cl.ast.Visitor_ExpressionStatement.visit(Visitor_ExpressionStatement.java:14)
        at com.google.j2cl.ast.ExpressionStatement.accept(ExpressionStatement.java:46)
        at com.google.j2cl.ast.VisitorUtils.visitList(VisitorUtils.java:28)
        at com.google.j2cl.ast.Visitor_Block.visitMembers(Visitor_Block.java:32)
        at com.google.j2cl.ast.Visitor_Block.visit(Visitor_Block.java:14)
        at com.google.j2cl.ast.Block.accept(Block.java:53)
        at com.google.j2cl.ast.Visitor_Method.visitMembers(Visitor_Method.java:37)
        at com.google.j2cl.ast.Visitor_Method.visit(Visitor_Method.java:14)
        at com.google.j2cl.ast.Method.accept(Method.java:156)
        at com.google.j2cl.ast.VisitorUtils.visitList(VisitorUtils.java:28)
        at com.google.j2cl.ast.Visitor_Type.visitMembers(Visitor_Type.java:39)
        at com.google.j2cl.ast.Visitor_Type.visit(Visitor_Type.java:14)
        at com.google.j2cl.ast.Type.accept(Type.java:324)
        at com.google.j2cl.ast.VisitorUtils.visitList(VisitorUtils.java:28)
        at com.google.j2cl.ast.Visitor_CompilationUnit.visitMembers(Visitor_CompilationUnit.java:36)
        at com.google.j2cl.ast.Visitor_CompilationUnit.visit(Visitor_CompilationUnit.java:14)
        at com.google.j2cl.ast.CompilationUnit.accept(CompilationUnit.java:83)
        at com.google.j2cl.ast.visitors.NormalizeConstructors.rewriteNewInstances(NormalizeConstructors.java:320)
        at com.google.j2cl.ast.visitors.NormalizeConstructors.applyTo(NormalizeConstructors.java:123)
        at com.google.j2cl.transpiler.J2clTranspiler.normalizeUnits(J2clTranspiler.java:256)
        at com.google.j2cl.transpiler.J2clTranspiler.transpileImpl(J2clTranspiler.java:134)
        at com.google.j2cl.transpiler.J2clTranspiler.lambda$transpile$0(J2clTranspiler.java:107)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
---8<---8<--- End of log snippet, 2957 chars omitted ---8<---8<---
Target //src/main/java/com/google/j2cl/samples/helloworld:helloworld failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.269s, Critical Path: 0.09s
INFO: 2 processes: 1 local, 1 worker.
FAILED: Build did NOT complete successfully

Bazel version

WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
Build label: 0.24.0
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Tue Mar 26 16:12:02 2019 (1553616722)
Build timestamp: 1553616722
Build timestamp as int: 1553616722

Expected behavior
I expect the code with the lambda to transpile successfully.

HelloWorld sample source maps support

Does the current version of j2cl support sourcemaps?

Chrome's DevTool doesn't show HelloWorld.java in sources list. Also I see next log output in terminal when launching dev server through ibazel:

INFO: 750µs /0:0:0:0:0:0:0:1:38796 404 GET /HelloWorld.js.map

It seems like reference to the sources presents in js, but the web server cannot find requested resource.

Guava and EventBus

Hi,

We have project, that is written in Java and using J2ObjC used in both iOS and Android (as platform independend backend). The idea is to use same Java code in Electron app.

Part of our core architecture is usage of EventBus. We are using it for message broadcasting etc. It depends on reflection and that is not supported in j2cl.

The question is - how do you handle EventBus usage? It is part of Guava and I believe it is used in some Google projects as well.

Thanks!

Jindrich

Annotations required?

Is it possible convert a third-party library from source without the JsInterop annotations? I noticed that Guava already has the annotations included in its source and it's mentioned in the docs that it can be used with J2CL. What about other libraries ... like Log4J for instance?

FAILED: Build did NOT complete successfully

gcc-c++.x86_64 0:4.8.5-36.el7
CentOS Linux release 7.6.1810 (Core)

git clone https://github.com/google/j2cl.git
cd j2cl/samples/helloworld
bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworld

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 


[root@nodejs helloworld]# bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworld
INFO: Invocation ID: d6f32888-4450-42d4-ba4f-d876c36267ae
DEBUG: Rule 'com_google_j2cl' modified arguments {"sha256": "709ec52666421ca58f36067647fd8c5713bf375e9837bf2956e5bdd4d408989c"}
DEBUG: Rule 'io_bazel_rules_closure' modified arguments {"sha256": "45bff60125c4a9f54885100d27e9d94d443a85d7972ec61c98d09b5e3bc9e860"}
DEBUG: Rule 'org_gwtproject_gwt' modified arguments {"sha256": "823f139c9c21dd8279f0935516c54001555839e595f3c26b7184ac958cc4df1c"}
DEBUG: Rule 'com_google_protobuf' modified arguments {"sha256": "9510dd2afc29e7245e9e884336f848c8a6600a14ae726adb6befdb4f786f0be2"}
INFO: Analysed target //src/main/java/com/google/j2cl/samples/helloworld:helloworld (2 packages loaded, 246 targets configured).
INFO: Found 1 target...
ERROR: /root/.cache/bazel/_bazel_root/6079736e018d98f577dd81710783266d/external/bazel_tools/tools/jdk/BUILD:188:1: SkylarkAction external/bazel_tools/tools/jdk/platformclasspath.jar failed (Exit 1)
Exception in thread "main" java.lang.IllegalArgumentException: external/local_jdk
        at jdk.compiler/com.sun.tools.javac.file.Locations$SystemModulesLocationHandler.update(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.file.Locations$SystemModulesLocationHandler.handleOption(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.file.Locations.handleOption(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.file.BaseFileManager.handleOption(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.file.BaseFileManager$2.handleFileManagerOption(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.main.Option.process(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.main.Option.handleOption(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.file.BaseFileManager.handleOption(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.main.Arguments.doProcessArgs(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.main.Arguments.processArgs(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.main.Arguments.init(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.api.JavacTool.getTask(Unknown Source)
        at DumpPlatformClassPath.dumpJDK9AndNewerBootClassPath(DumpPlatformClassPath.java:106)
        at DumpPlatformClassPath.main(DumpPlatformClassPath.java:67)
Target //src/main/java/com/google/j2cl/samples/helloworld:helloworld failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 169.421s, Critical Path: 12.56s
INFO: 183 processes: 183 local.
FAILED: Build did NOT complete successfully
[root@nodejs helloworld]# 



Which JRE classes are implemented?

Hi,

is there somewhere described, which standard JRE classes are already included, which are planned and which not?

For example I tried ByteBuffer and and I get:

The import java.nio.ByteBuffer cannot be resolved

so that it looks like it is not there. It would be nice to have overview what is there and what not.

Thanks!

Jindrich

Can't build J2CL app with JDK 11 toolchain

Describe the bug
I am building my J2CL app within a codebase that must also support Java 11, for the server-side components. However, when I change my Java toolchain to JDK11, J2CL fails to run properly.

To Reproduce

  1. Clone J2CL
  2. Go into the example directory (cd samples/helloworld)
  3. Run echo "2.0.0" > .bazelversion"
  4. Rename WORKSPACE.remote > WORKSPACE and WORKSPACE > WORKSPACE.local
  5. Build with regular flags first, observe that it completes (bazelisk build //...)
  6. Run bazelisk build --java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 //...
  7. See error:
➜  helloworld git:(473aa0a2e) ✗ bazelisk build --java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 //...
DEBUG: Rule 'com_google_j2cl' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "cae6e4ffee354e9cc0fbb440a1b0898b1ab587a8dfab505782d220aa2e85a3fc"
DEBUG: Call stack for the definition of repository 'com_google_j2cl' which is a http_archive (rule definition at /private/var/tmp/_bazel_sam/f203f916dd852e7c2460b49941242252/external/bazel_tools/tools/build_defs/repo/http.bzl:292:16):
 - /Volumes/PITBULL/Vault/GUST/vendor/bazel/j2cl/samples/helloworld/WORKSPACE:6:1
INFO: Build option --java_toolchain has changed, discarding analysis cache.
INFO: Analyzed 10 targets (0 packages loaded, 2054 targets configured).
INFO: Found 10 targets...
ERROR: /private/var/tmp/_bazel_sam/f203f916dd852e7c2460b49941242252/external/com_google_j2cl/jre/java/BUILD:59:1: Building external/com_google_j2cl/jre/java/libjre_bootclasspath.jar (6 source files) failed (Exit 1)
external/com_google_j2cl/jre/java/javasynth/LambdaMetafactory.java:14: error: package exists in another module: java.base
package java.lang.invoke;
^
external/com_google_j2cl/jre/java/javasynth/MethodHandle.java:14: error: package exists in another module: java.base
package java.lang.invoke;
^
external/com_google_j2cl/jre/java/javasynth/MethodHandles.java:14: error: package exists in another module: java.base
package java.lang.invoke;
^
external/com_google_j2cl/jre/java/javasynth/MethodType.java:14: error: package exists in another module: java.base
package java.lang.invoke;
^
external/com_google_j2cl/jre/java/javasynth/NoSuchFieldError.java:14: error: package exists in another module: java.base
package java.lang;
^
external/com_google_j2cl/jre/java/javasynth/SerializedLambda.java:14: error: package exists in another module: java.base
package java.lang.invoke;
^
INFO: Elapsed time: 2.352s, Critical Path: 1.67s
INFO: 2 processes: 2 local.
FAILED: Build did NOT complete successfully

Bazel version
2.0.0

Expected behavior
I would expect it to at least build, even if it must enforce Java 8 language semantics. Perhaps there would be a way to force a JDK8 toolchain for J2CL targets?

JRE gives warning for unusedLocalVariables

JRE gives warnings for unusedLocalVariables. This is due to missing suppress for hand-rolled JavaScript classes.
The fix is easy but more important is to make sure our conformance test (jre/javatests:conformance_binary) catches such issues.

javax.annotation emulation not copied from GWT

While the j2cl-maven-plugin explicitly didn't support past java 8, we were able to add the jsr250 jar to the classpath that j2cl takes so that it could get javax.annotation.Generated, this doesn't work in java9+. Some annotation processors when running java9+ automatically switch to javax.annotation.processing.Generated, which isn't published in any annotation jar that I can find, but is assumed to be in the JRE.

See google/dagger#880 as an example of this - none of the annotation processors I could find inside of j2cl seem to emit either annotation.


The most straightforward solution appears to be that the jre.jar needs to include this, as gwt2 does. Presently, the mirroring rule only copies the java.* emulation, so this needs to be expanded to javax.* as well.

As I understand bazel, this first requires a change to be made to gwt, something like adding this to user/BUILD.bazel, matching the existing java_emul filegroup:

filegroup(
    name = "javax_emul",
    srcs = glob(["super/com/google/gwt/emul/javax/**/*.java"]),
)

With that change made, a new alias can be added in j2cl's third_party/BUILD, like this:

alias(
    name = "gwt_javax_emul",
    actual = "@org_gwtproject_gwt//user:javax_emul",
)

and then also update jre/java:jre to include that target as an entry in mirrored_files.


If approved, I'll start the change on gwt2 so that we can consider this change here in j2cl as well? Alternatively, if there is a deliberate reason that these are not included in jre.jar, I would still like to add this target to gwt (or consider another approach that you would accept), so that external users of j2cl are able to use dagger2 and other annotation processors in their projects, even under java9+.

Error when transpiling native JsType with a matching .native.js

I know the title makes it look like I'm an idiot, but I think this is reasonable given a few factors - not least of which is "the error message is just this side of useless".

Say you have a class that represents some extern'd type - the class is then annotated with @JsType(isNative=true), etc. The Java type doesn't seem as though it should have any native.js, naturally, since it is a native type.

Now say that one of the @JsOverlay methods wants to call System.getProperty("foo") for some reason - it is legal and expected to put overlay methods in native jstypes, and it seems reasonable then to also put other supported Java in there, rather than specify a subset of Java which can be called.

Unfortunately, in order to legally call System.getProperty and have the @define included properly (see #1), the only workaround I'm aware of is to make a matching .native.js with a goog.require("myproperty") in it.

Currently, you get this error:

Error: Unused native file 'path/to/MyNativeType.native.js'.

This makes sense inside the compiler since the native.js file wasn't consumed - but for a user to see this error, it doesn't tell them what they did wrong.

Some possible fixes:

  • Incorporate native.js content into MyNativeType$$Overlay impl js output, so that @JsOverlays that happen to rely on arbitrary code in the .native.js still work correctly. It is clear to me why this is a bad idea, you end up with the possibility of a "native overlay", where it is "native" to reference the code in .native.js, but an "overlay" since it goes in $$Overlay.
  • Encourage "holder" types for system properties, and clarify the error as to why the native.js was unused.

Example for use with protocol buffers

Is your feature request related to a problem? Please describe.
We use Protobuf objects extensively in our stack, including protobuf-js objects. We're wondering what the best way would be to plugin with protobuf-js, from J2CL.

Describe the solution you'd like
An example, perhaps in the JS Interop Cookbook, of how one would go about using protobuf objects in J2CL effectively.

Describe alternatives you've considered

  1. We've thought about using the Java proto objects, but we have no idea if those will convert properly, or be as tightly optimized as protobuf-js is.

  2. Otherwise, we could write bindings to call into the protobuf objects (for example, like this), but the surface area of those bindings would be huge and hard to maintain.

  3. We've thought about writing a protoc plugin to generate these files, but that's beyond the scope of our team's skills right now

Clarify supported Java versions

Hi,

Thank you for this project!

For now, I cannot find the information on supported Java versions: 8 / 11 ? It is still source to source transpiler ? Do you expect any delays with support of the upcoming Java versions ?

liveload url should not be hardcoded as localhost

Describe the bug

A clear and concise description of what the bug is.

<script src="http://localhost:35729/livereload.js"></script>

To Reproduce
run sample helloworld, open the address displayed in the ibazel run :helloworld_dev_server stdin output in another device in the same network.

Expected behavior

usually, I develop in one machine and watch the liveload in another machine.

<script src="http://$host:35729/livereload.js"></script>

the $host should be window.location.hostname

Build fails with Bazel 0.22

Building the sample app, as per the homepage instructions:

$ cd j2cl/samples/helloworld
$ bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworld

fails when Bazel 0.22 is used. The build does succeed when using an earlier version of Bazel (i.e. 0.20).

Seems to be related with the following issue in Bazel:
bazelbuild/rules_k8s#240

Failure snippet:

ivan:~/git/j2cl/samples/helloworld$ bazel build src/main/java/com/google/j2cl/samples/helloworld:helloworl
d
INFO: Invocation ID: cc751874-1c19-47e0-88c3-b072148f2d6a
INFO: SHA256 (https://github.com/google/protobuf/archive/v3.6.1.zip) = d7a221b3d4fb4f05b7473795ccea9e05dab3b8721f6286a95
fffbffc2d926f8b
DEBUG: Rule 'com_google_protobuf' modified arguments {"sha256": "d7a221b3d4fb4f05b7473795ccea9e05dab3b8721f6286a95fffbff
c2d926f8b"}
ERROR: /home/ivan/.cache/bazel/_bazel_ivan/d8cb0f6f207e8ad017218e077f95b544/external/com_google_protobuf/BUILD:573:1: Tr
aceback (most recent call last):
        File "/home/ivan/.cache/bazel/_bazel_ivan/d8cb0f6f207e8ad017218e077f95b544/external/com_google_protobuf/BUILD",
line 573
                internal_gen_well_known_protos_java(srcs = WELL_KNOWN_PROTOS)
        File "/home/ivan/.cache/bazel/_bazel_ivan/d8cb0f6f207e8ad017218e077f95b544/external/com_google_protobuf/protobuf
.bzl", line 269, in internal_gen_well_known_protos_java
                Label(("%s//protobuf_java" % REPOSITOR...))
        File "/home/ivan/.cache/bazel/_bazel_ivan/d8cb0f6f207e8ad017218e077f95b544/external/com_google_protobuf/protobuf
.bzl", line 269, in Label
                REPOSITORY_NAME
builtin variable 'REPOSITORY_NAME' is referenced before assignment.
ERROR: /home/ivan/.cache/bazel/_bazel_ivan/d8cb0f6f207e8ad017218e077f95b544/external/com_google_protobuf/BUILD:577:1: Ta
rget '@com_google_protobuf//:jdk9' contains an error and its package is in error and referenced by '@com_google_protobuf
//:protobuf_java'
ERROR: /home/ivan/.cache/bazel/_bazel_ivan/d8cb0f6f207e8ad017218e077f95b544/external/com_google_javascript_closure_compi
ler/BUILD:7:1: Target '@com_google_protobuf//:protobuf_java' contains an error and its package is in error and reference
d by '@com_google_javascript_closure_compiler//:com_google_javascript_closure_compiler'
ERROR: Analysis of target '//src/main/java/com/google/j2cl/samples/helloworld:helloworld' failed; build aborted: Analysi
s failed
INFO: Elapsed time: 74.961s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (84 packages loaded, 801 targets configured)
    Fetching @org_gwtproject_gwt; fetching 36s
ivan:~/git/j2cl/samples/helloworld$

Integer overflow semantics are not document

The emulation limitations doesn't mention that the behavior for integer overflow is different from java, however I hit a bug because java code was assuming that adding two ints results in a 32 bit int.

Default methods on interface implemented by abstract class can not be called via super

It seems that this particular scenario does not generate valid code. The easiest way to explain the scenario is with a snippet of code:

interface MyExtension
{
  default void myAction()
  {
  }
}

abstract class MyComponent
  implements MyExtension
{
}

class Generated_MyComponent
  extends MyComponent
{
  public void myAction()
  {
    super.myAction();
  }
}

If this is compiled the super.myAction() line will result in an error message such as:

out/sources/Generated_MyComponent.java:21: WARNING - Abstract super method module$exports$MyComponent$impl.prototype.m_myAction__ cannot be called
    super.myAction();
    ^^^^^^^^^^^^^^^^^

At runtime you end up with a call() on an undefined.

A repository containing code to reproduce this is at https://github.com/realityforge-experiments/jcl-test/tree/DefaultMethodError (but it requires access to vertispan to run the build).

@niloc132 performed a preliminary analysis and to paraphrase his analysis - The abstract superclass MyComponent does not get the "Default method forwarding stub" added. In the concrete subclass Generated_MyComponent the forwarding stub is not added as the method is overridden and it is assumed that it won't be needed. However the code assumes that it can call the superclass as needed however it can not as the method is marked as @abstract.

Hopefully @niloc132 can correct any mistakes in translation and describe the ways he tried to fix it.

Windows 10: Building "HelloWorld" trying to create temp dir in C:\WINDOWS

Error: Cannot create temporary directory: C:\WINDOWS\j2cl_sources15492327304741498378

Platform: Windows 10.

warning: File for type 'com.google.j2cl.ast.Rewriter' created in the last round will not be subject to annotation processing.
ERROR: C:/users/vgole/_bazel_vgole/ksuaangi/external/com_google_j2cl/jre/java/BUILD:17:1: Stripping @GwtIncompatible failed (Exit 1): GwtIncompatibleStripper_w
orker.exe failed: error executing command
  cd C:/users/vgole/_bazel_vgole/ksuaangi/execroot/com_google_j2cl_samples_helloworld
  SET LANG=en_US.UTF-8
  bazel-out/host/bin/external/com_google_j2cl/tools/java/com/google/j2cl/tools/gwtincompatible/GwtIncompatibleStripper_worker.exe @bazel-out/x64_windows-fastbu
ild/bin/external/com_google_j2cl/jre/java/jre_stripped-src.jar-0.params
Error: Cannot create temporary directory: C:\WINDOWS\j2cl_sources15492327304741498378.

Packaging externs and *.native.js files

Several of the libraries I am attempting to convert across to J2CL are designed as a combination of java, closure externs, closure modules and non-closure compatible javascript. In most cases the expectation is that the library will be developed and then published to some artifact repository ala Maven Central. While the producers are unlikely to be able to move to Bazel in the short term, we are hoping to move the consumers to Bazel where possible.

As an example I am going to use react4j (although we have several similar libraries). It ships a react4j-core artifact which contains java that can easily be added to srcs in j2cl_library to get it transpiled. But the *.native.js (i.e. ReactConfig.native.js), the associated closure modules (i.e. react4j.js) and the externs (i.e. react.externs.js are not included in the j2cl_library as the srcs property only seems to gather *.java source code.

As a result I manually extract the js, put it in the local filesystem and add it to the srcs using a manual process. This is obviously sub-optimal.

I am wondering what the best solution for this is?

Possibilities include:

  • using http_archive and treating the jar as a "repository". Including a file such as META-INF/bazel/BUILD that declares the dependency. Seems neat if somewhat non-standard but closely aligns with the "use the repository" approach that seems to be common with the way that google works
  • Updating the j2cl macro to add the .jar types as possible js sources
  • Add another macro that does some unzipping/extracting magic to create a local repository
  • Something else I have not thought of?

Or maybe I am going about this all wrong...

NPE when compiling simple enum class with lambda expressions

Describe the bug
I have a simple enum java class that define an inner Functional interface, the interface is used a constructor argument for the enum class, enum entires are defined passing a lambada expression of that functional interface.

compiling with j2cl throws a NullPointerException.

To Reproduce
we can reproduce this issue in using the hello world sample:

  • add the following class next to the HelloWorld.java
package com.google.j2cl.samples.helloworldlib;

public enum Unit{
    px(value -> value + "px"),
    em(value -> value + "em");

    private final UnitFormatter unitFormatter;

    Unit(UnitFormatter unitFormatter) {
        this.unitFormatter = unitFormatter;
    }

    public String of(Number value) {
        return unitFormatter.format(value);
    }

    @FunctionalInterface
    public interface UnitFormatter{
        String format(Number value);
    }
}
  • try to transpile the Hello world sample

this will produce an exception with the following stack trace

ures.wrapAndThrowUnchecked(Futures.java:1546)
        at com.google.common.util.concurrent.Futures.getUnchecked(Futures.java:1532)
        at com.google.j2cl.transpiler.J2clTranspiler.transpile(J2clTranspiler.java:111)
        at com.google.j2cl.transpiler.BazelJ2clBuilder.run(BazelJ2clBuilder.java:74)
        at com.google.j2cl.bazel.BazelWorker.processRequest(BazelWorker.java:62)
        at com.google.j2cl.bazel.BazelWorker.execute(BazelWorker.java:116)
        at com.google.j2cl.bazel.BazelWorker.runPersistentWorker(BazelWorker.java:98)
        at com.google.j2cl.bazel.BazelWorker.start(BazelWorker.java:71)
        at com.google.j2cl.transpiler.BazelJ2clBuilder.main(BazelJ2clBuilder.java:158)
Caused by: java.lang.NullPointerException
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:1617)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:647)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:1384)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:627)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convertLambdaBody(CompilationUnitBuilder.java:1037)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:1023)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:631)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
        at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convertArguments(CompilationUnitBuilder.java:1501)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:299)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:208)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:190)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.convert(CompilationUnitBuilder.java:177)
        at com.google.j2cl.frontend.CompilationUnitBuilder$ASTConverter.access$100(CompilationUnitBuilder.java:133)
        at com.google.j2cl.frontend.CompilationUnitBuilder.buildCompilationUnit(CompilationUnitBuilder.java:1914)
        at com.google.j2cl.frontend.CompilationUnitBuilder.lambda$build$0(CompilationUnitBuilder.java:1936)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
        at com.google.j2cl.frontend.CompilationUnitBuilder.build(CompilationUnitBuilder.java:1938)
        at com.google.j2cl.transpiler.J2clTranspiler.convertUnits(J2clTranspiler.java:141)
        at com.google.j2cl.transpiler.J2clTranspiler.transpileImpl(J2clTranspiler.java:125)
        at com.google.j2cl.transpiler.J2clTranspiler.lambda$transpile$0(J2clTranspiler.java:110)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
---8<---8<--- End of log snippet, 791 chars omitted ---8<---8<---
Target //src/main/java/com/google/j2cl/samples/helloworld:helloworld failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1.388s, Critical Path: 1.15s, Remote (0.00% of the time): [queue: 0.00%, setup: 0.00%, process: 0.00%]
INFO: 2 processes: 1 local, 1 worker.
FAILED: Build did NOT complete successfully

for some reason the CurrentType is being Null in the CompilationUnitBuilder during the process of converting the lambda expression body.

expanding the lamda to anonymous classes works.

Create an example of how to use web APIs with j2cl

Is your feature request related to a problem? Please describe.
We would love to try using j2cl in external apps, but until there's an easy way to use WebAPIs, it's hard to do so.

Describe the solution you'd like
It would be nice to have an example near helloworld, where some web API is used via elemental2 or other library. Initially it might contain a number of hacks, but this should be good enough for early adopter outside of Google

Describe alternatives you've considered
I spend some time investigating how to configure it myself, but it took too much time and I gave up.

Can't build helloworld

Hello,

My company asked me to test J2CL for future developments but it seems that i can't build the helloworld project (cmd trace in attached file)
trace.txt

I tried to use bazelisk because i first thought that it was a bazel version issue ( i'm on bazel 0.29.1)

Did i missed something?

Thomas

P.S : Sorry if my english is bad, i'm french :/

Generate closure @suppress jsdoc tag on method when @SuppressWarning present in java

I would like J2CL to generate @suppress jsdoc tags when a specially formatted @SuppressWarning() is present in java code. To start with the simplest option would be to detect the @SuppressWarning() on the java method and then translate to a @suppress on the corresponding method implementation - while detecting appropriate @SuppressWarning() in other contexts may be possible, it would also be more complex.

For now let us assume that any SuppressWarnings key that had a prefix of CL: should be translated into a closure suppression.

So we could easily imagine code such as:

  @SuppressWarnings( "CL:checkDebuggerStatement" )
  public static void pauseIfInDebugger() {
    Js.debugger();
  }

Generating the following javascript code:

  /**
   * @return {void}
   * @public
   * @suppress {checkDebuggerStatement}
   */
  static void pauseIfInDebugger() {
    debugger;
  }

A few questions:

  • Would a PR containing this be accepted?
  • Should I wait until JDT is eliminated or is it acceptable to start with what is present now?
  • Do you expect it to be possible for me to write tests in the OSS variant of the library or should I look at that first?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.