Search code examples
google-closure-compilerikvm

Closure Templates through IKVM?


Google Closure works GREAT without the Java Runtime Environment by using IKVM

In case that ever goes away, the simplified steps to convert it to an exe are:

  1. Download and extract (but nothing to install) Closure Compiler and IKVM
  2. Move compiler.jar to the IKVM bin folder
  3. ikvmc -target:exe -fileversion:2012.09.17 .\compiler.jar (with the jar's release date). Note: I get a few warnings about ANT libraries.
  4. Copy these dependencies from the ikvm bin directory to the closure directory:
    • IKVM.OpenJDK.Core.dll
    • IKVM.OpenJDK.Jdbc.dll
    • IKVM.OpenJDK.Misc.dll
    • IKVM.OpenJDK.SwingAWT.dll
    • IKVM.OpenJDK.Text.dll
    • IKVM.OpenJDK.Util.dll
    • XML.API.dll
    • IKVM.Runtime.dll

Then you can move the compiler.jar and new compiler.exe back to your closure directory. Fredrik recommends this powershell version of execution because of the ability to specify ascii encoding overriding unicode (half the bytes):

.\compiler.exe --js .\jquery-1.4.2.js --warning_level QUIET | out-file -encoding ascii .\jquery.min.js

==============================

However, I do not have the same luck with the Closure Templates's SoyToJsSrcCompiler.jar. I get warnings from ikvmc -target:exe -fileversion:2011.12.22 .\SoyToJsSrcCompiler.jar as with compiler.jar.

warning IKVMC0105: Unable to compile class "com.google.template.soy.jssrc.internal.GenerateSoyUtilsEscapingDirectiveCode"
    (missing class "org.apache.tools.ant.Task")
warning IKVMC0100: Class "com.google.inject.internal.asm.util.$TraceClassVisitor" not found
warning IKVMC0111: Emitted java.lang.NoClassDefFoundError in "com.google.inject.internal.cglib.core.$DebuggingClassWriter$1.run()Ljava.lang.Object;"
    ("com.google.inject.internal.asm.util.$TraceClassVisitor")
warning IKVMC0100: Class "com.google.template.soy.jssrc.internal.GenerateSoyUtilsEscapingDirectiveCode" not found

The resulting SoyToJsSrcCompiler.exe with no command-line arguments works to show the help page, but supplying a .soy file gives:

Exception in thread "main" cli.System.MethodAccessException: 
com.google.inject.assistedinject.FactoryProvider2.getBindingFromNewInjector(java.lang.reflect.Method, System.Object[], AssistData) at 
com.google.inject.assistedinject.FactoryProvider2$$FastClassByGuice$$9dcdf6d7.invoke() at 
com.google.inject.internal.cglib.reflect.$FastMethod.invoke(FastMethod.java:53) at 
com.google.inject.internal.SingleMethodInjector$1.invoke(SingleMethodInjector.java:56) at 
com.google.inject.internal.SingleMethodInjector.inject(SingleMethodInjector.java:90) at 
com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:107) at 
com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:76) at 
com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:73) at 
com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031) at 
com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:88) at
com.google.inject.internal.Initializer$InjectableReference.get(Initializer.java:150) at 
com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40) at 
com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53) at 
com.google.inject.internal.InjectionRequestProcessor$StaticInjection$1.call(InjectionRequestProcessor.java:11 6) at 
com.google.inject.internal.InjectionRequestProcessor$StaticInjection$1.call(InjectionRequestProcessor.java:11 0) at 
com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024) at 
com.google.inject.internal.InjectionRequestProcessor$StaticInjection.injectMembers(InjectionRequestProcessor. java:110) at 
com.google.inject.internal.InjectionRequestProcessor.injectMembers(InjectionRequestProcessor.java:78) at 
com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:171) at 
com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:111) at 
com.google.inject.Guice.createInjector(Guice.java:95) at 
com.google.inject.Guice.createInjector(Guice.java:72) at 
com.google.template.soy.MainClassUtils.createInjector(MainClassUtils.java:212) at 
com.google.template.soy.SoyToJsSrcCompiler.execMain(SoyToJsSrcCompiler.java:223) at 
com.google.template.soy.SoyToJsSrcCompiler.main(SoyToJsSrcCompiler.java:205)

Anyone know how to get this to work?


Solution

  • The exception can be an bug in IKVM. Which version do you use? Test the latest version.

    warning IKVMC0100: Class "com.google.template.soy.jssrc.internal.GenerateSoyUtilsEscapingDirectiveCode" not found

    Another problem can be that you have not compile all needed jar files for SoyToJsSrcCompiler.jar. In which jar file is this missing class file? Take a look in the wiki to see how you compile multiple jar files.

    The next problem can be that there is the same package in different jar files. It there are only package visible for some mthods this will not work for .NET. You can test a sharedclassloader. See the wiki for details.