question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is it possible to emit generated code that is not obfuscated and reproduces the API of a Java class?

See original GitHub issue

Hi TeamVM folks 😃

could I write a library in Java, like a simple class like:

namespace com.acme;

class FooBar {
    public String whatEver() {
       return "FooBar";
    }
}

…then compile it into Java bytecode and use TeaVM to generate the JS impl. and put it in some output directory (constructing the inner directory tree just by following the namespace) like: $output/com/acme/FooBar.js. The file FooBar.js would come with a module.exports = Foobar; call at last line so that I could import this original Java impl. in any JavaScript project and just do:

import { FooBar} from '$output/com/acme/FooBar';

new FooBar().whatever(); // "FooBar"

@konsoletyper If this is not possible yet, how hard would it be to implement? And could you please help me to find the right places in the TeaVM code so that I would have a chance to implement it and PR it for you?

Would be awesome!

Thanks and best, Aron

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
konsoletypercommented, Aug 24, 2018

This is nearly impossible to implement. Java was not designed to be compiled to JavaScript, so any attempt to do it in a straight and simple way would end up with large mess of slow JavaScript code. Thus tools like GWT or TeaVM perform a lot of whole program optimizations. This approach requires compilation of a whole application, not module-to-module or class-to-class. The only option provided by TeaVM is to compile bunch of jar files into single highly optimized JavaScript.

To disable obfuscation, say, for debugging reasons, you may play with Maven options (set minifying to false). However, the generated code would not be intended for calling directly from JavaScript.

If you want to interoperate between Java and JavaScript, you can use JSO library. In this case TeaVM will generate unobfuscated methods where you ask to. However, this library was not designed to write Java code invokable from JavaScript. Indeed, it can be extended to support this use case. As for now, you can use following workaround. Say, you want Foo namespace to provide bar method. Here’s the code:

public static void main(String[] args) {
    exportFoo(new Foo() {
        @Override
        public void bar() {
            System.out.println("Bar method works");
        }
    });
}

@JSBody(params = "foo", script = "Foo = foo;")
static native void exportFoo(Foo foo);

interface Foo extends JSObject {
    void bar();
}

Anyway, this approach is still incomplete due to following reasons:

  1. TeaVM can’t generate code in wrapper functions, so you end up with polluted global object. This can be easily improved.
  2. This approach requires your JavaScript code to call main() function before using Foo.bar().
  3. It can’t be integrated in CommonJS module system.

The whole JSO implementation is available here. This library uses compiler magic to generate interop code.

Please, do not to write any PR before you discuss things with me. There’s a great chance that I deny the whole PR, since I already have some thoughts about implementing this part of interop, and know lot of corner cases and pitfalls. The best thing you can start with is to describe your use case.

0reactions
rufenerccommented, Oct 10, 2018

@comick Hello You suggested: (function() { // runtime // you compiled code // make main function available in global scope main() })()

I tried to follow your procedure but I failed to do it right. Must be something about namespace. Would you mind to show me your working solution. Thanks

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Can I always use the Reflection API if the code is going ...
Those solutions work only for calls within the same project - client code (in another project) may not use the reflection API to...
Read more >
Java Source Code obfuscator ( not bytecode obfuscator )
Hello, I'm looking for an obfuscation tool that doesn't work on bytecode file but directly on the source code.
Read more >
An Obfuscating Compiler
This compiler emits code that generates runtime values that are arbitrarily different in each register and memory location for each unique compilation, yet...
Read more >
What's new in Eazfuscator.NET? - Gapotchenko
NET Native tool-chain to fail on obfuscated assemblies; Fixed issue with closure conditional obfuscation variable not working for generic closures ...
Read more >
[GWT] Documentation - Debug & Compile
gwt.rpc file generated by the GWT compiler. The .gwt.rpc file serves as a serialization policy to indicate which types implementing java.io.Serializable ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found