The static calculator demo needs to reference just a single application .js file from its main HTML page. The rest is loaded based on classpath attribute. closure
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 27 May 2014 12:25:41 +0200
branchclosure
changeset 16047665471a56c1
parent 1603 3ee8458a6ca9
child 1605 c74047c30b8f
The static calculator demo needs to reference just a single application .js file from its main HTML page. The rest is loaded based on classpath attribute.
javaquery/demo-calculator/pom.xml
javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml
javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/package-info.java
javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml
launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java
rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java
rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java
rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java
rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java
rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java
     1.1 --- a/javaquery/demo-calculator/pom.xml	Tue May 27 09:20:06 2014 +0200
     1.2 +++ b/javaquery/demo-calculator/pom.xml	Tue May 27 12:25:41 2014 +0200
     1.3 @@ -23,7 +23,6 @@
     1.4                  <executions>
     1.5                      <execution>
     1.6                          <goals>
     1.7 -                            <goal>j2js</goal>
     1.8                              <goal>aot</goal>
     1.9                              <goal>brwsr</goal>
    1.10                          </goals>
    1.11 @@ -32,9 +31,11 @@
    1.12                  <configuration>
    1.13                      <directory>${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html/</directory>
    1.14                      <startpage>index.xhtml</startpage>
    1.15 -                    <javascript>${project.build.directory}/app.js</javascript>
    1.16 -                    <library>true</library>
    1.17 +                    <mainJavaScript>${project.build.directory}/calculator.js</mainJavaScript>
    1.18                      <obfuscation>${bck2brwsr.obfuscationlevel}</obfuscation>
    1.19 +                    <exports>
    1.20 +                        <param>org/apidesign/bck2brwsr/demo/calc/staticcompilation/</param>
    1.21 +                    </exports>
    1.22                  </configuration>
    1.23              </plugin>
    1.24           <plugin>
     2.1 --- a/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml	Tue May 27 09:20:06 2014 +0200
     2.2 +++ b/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml	Tue May 27 12:25:41 2014 +0200
     2.3 @@ -27,34 +27,19 @@
     2.4        <format>dir</format>
     2.5    </formats>
     2.6    <baseDirectory>public_html</baseDirectory>
     2.7 -  <dependencySets>
     2.8 -    <dependencySet>
     2.9 -        <useProjectArtifact>false</useProjectArtifact>
    2.10 -        <scope>runtime</scope>
    2.11 -        <outputDirectory>lib</outputDirectory>
    2.12 -        <includes>
    2.13 -            <include>*:jar</include>
    2.14 -            <include>*:rt</include>
    2.15 -        </includes>
    2.16 -    </dependencySet>
    2.17 -  </dependencySets> 
    2.18    <fileSets>
    2.19        <fileSet>
    2.20            <directory>${project.build.directory}</directory>
    2.21            <outputDirectory>/</outputDirectory>
    2.22            <includes>
    2.23                <include>bck2brwsr.js</include>
    2.24 -              <include>app.js</include>
    2.25 +              <include>calculator.js</include>
    2.26                <include>lib/*.js</include>
    2.27            </includes>
    2.28        </fileSet>
    2.29    </fileSets>
    2.30    <files>
    2.31      <file>
    2.32 -      <source>${project.build.directory}/${project.build.finalName}.jar</source>
    2.33 -      <outputDirectory>/</outputDirectory>
    2.34 -    </file>
    2.35 -    <file>
    2.36        <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml</source>
    2.37        <outputDirectory>/</outputDirectory>
    2.38        <destName>index.xhtml</destName>
     3.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/package-info.java	Tue May 27 09:20:06 2014 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,21 +0,0 @@
     3.4 -/**
     3.5 - * Back 2 Browser Bytecode Translator
     3.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.7 - *
     3.8 - * This program is free software: you can redistribute it and/or modify
     3.9 - * it under the terms of the GNU General Public License as published by
    3.10 - * the Free Software Foundation, version 2 of the License.
    3.11 - *
    3.12 - * This program is distributed in the hope that it will be useful,
    3.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.15 - * GNU General Public License for more details.
    3.16 - *
    3.17 - * You should have received a copy of the GNU General Public License
    3.18 - * along with this program. Look for COPYING file in the top folder.
    3.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
    3.20 - */
    3.21 -@Exported
    3.22 -package org.apidesign.bck2brwsr.demo.calc.staticcompilation;
    3.23 -
    3.24 -import org.apidesign.bck2brwsr.core.Exported;
     4.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml	Tue May 27 09:20:06 2014 +0200
     4.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml	Tue May 27 12:25:41 2014 +0200
     4.3 @@ -91,11 +91,7 @@
     4.4          <div data-bind="text: displayPreview"></div>
     4.5          <script src="bck2brwsr.js"></script>
     4.6          <script>
     4.7 -            var vm = bck2brwsr(
     4.8 -                'app.js',
     4.9 -                'lib/emul-0.9-SNAPSHOT-rt.js',
    4.10 -                'lib/javaquery.api-0.9-SNAPSHOT.js'
    4.11 -            );
    4.12 +            var vm = bck2brwsr('calculator.js');
    4.13              vm.loadClass('org.apidesign.bck2brwsr.demo.calc.staticcompilation.Calc');
    4.14          </script>
    4.15      </body>
     5.1 --- a/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java	Tue May 27 09:20:06 2014 +0200
     5.2 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java	Tue May 27 12:25:41 2014 +0200
     5.3 @@ -76,7 +76,7 @@
     5.4                  Bck2Brwsr.newCompiler()
     5.5                      .addRootClasses(classes.toArray(new String[0]))
     5.6                      .addResources(arr.toArray(new String[0]))
     5.7 -                    .library(true)
     5.8 +                    .library()
     5.9                      //.obfuscation(ObfuscationLevel.FULL)
    5.10                      .resources(new EmulationResources() {
    5.11                          @Override
    5.12 @@ -135,7 +135,7 @@
    5.13              throw new IOException(ex);
    5.14          }
    5.15  
    5.16 -        all.library(false)
    5.17 +        all
    5.18              //.obfuscation(ObfuscationLevel.FULL)
    5.19              .resources(new Bck2Brwsr.Resources() {
    5.20                  @Override
     6.1 --- a/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java	Tue May 27 09:20:06 2014 +0200
     6.2 +++ b/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java	Tue May 27 12:25:41 2014 +0200
     6.3 @@ -70,6 +70,9 @@
     6.4          Set<String> exported = new HashSet<>();
     6.5  
     6.6          listJAR(jf, classes, resources, exported);
     6.7 +        
     6.8 +        String cp = jf.getManifest().getMainAttributes().getValue("Class-Path"); // NOI18N
     6.9 +        String[] classpath = cp == null ? new String[0] : cp.split(" ");
    6.10  
    6.11          class JarRes extends EmulationResources implements Bck2Brwsr.Resources {
    6.12  
    6.13 @@ -80,7 +83,7 @@
    6.14              }
    6.15          }
    6.16          return Bck2Brwsr.newCompiler()
    6.17 -            .library(true)
    6.18 +            .library(classpath)
    6.19              .addClasses(classes.toArray(new String[classes.size()]))
    6.20              .addExported(exported.toArray(new String[exported.size()]))
    6.21              .addResources(resources.toArray(new String[resources.size()]))
     7.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java	Tue May 27 09:20:06 2014 +0200
     7.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java	Tue May 27 12:25:41 2014 +0200
     7.3 @@ -18,25 +18,16 @@
     7.4  
     7.5  package org.apidesign.bck2brwsr.mojo;
     7.6  
     7.7 -import java.io.BufferedReader;
     7.8  import java.io.File;
     7.9  import java.io.FileWriter;
    7.10  import java.io.IOException;
    7.11  import java.io.InputStream;
    7.12 -import java.io.InputStreamReader;
    7.13  import java.net.MalformedURLException;
    7.14  import java.net.URL;
    7.15  import java.net.URLClassLoader;
    7.16  import java.util.ArrayList;
    7.17  import java.util.Collection;
    7.18 -import java.util.Enumeration;
    7.19 -import java.util.HashSet;
    7.20  import java.util.List;
    7.21 -import java.util.Set;
    7.22 -import java.util.jar.JarEntry;
    7.23 -import java.util.jar.JarFile;
    7.24 -import java.util.logging.Level;
    7.25 -import java.util.logging.Logger;
    7.26  import org.apache.maven.artifact.Artifact;
    7.27  import org.apache.maven.plugin.AbstractMojo;
    7.28  import org.apache.maven.plugin.MojoExecutionException;
    7.29 @@ -62,13 +53,22 @@
    7.30  public class AheadOfTime extends AbstractMojo {
    7.31      @Parameter(defaultValue = "${project}")
    7.32      private MavenProject prj;
    7.33 +    
    7.34 +    @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar")
    7.35 +    private File mainJar;
    7.36  
    7.37 +    @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.js")
    7.38 +    private File mainJavaScript;
    7.39 +    
    7.40 +    @Parameter
    7.41 +    private String[] exports;
    7.42 +    
    7.43      /**
    7.44       * Directory where to generate ahead-of-time JavaScript files for
    7.45       * required libraries.
    7.46       */
    7.47 -    @Parameter(defaultValue = "${project.build.directory}/lib")
    7.48 -    private File aot;
    7.49 +    @Parameter(defaultValue = "lib")
    7.50 +    private String classPathPrefix;
    7.51  
    7.52      /** Root JavaScript file to generate */
    7.53      @Parameter(defaultValue="${project.build.directory}/bck2brwsr.js")
    7.54 @@ -86,7 +86,7 @@
    7.55      public void execute() throws MojoExecutionException, MojoFailureException {
    7.56          URLClassLoader loader;
    7.57          try {
    7.58 -            loader = buildClassLoader(null, prj.getArtifacts());
    7.59 +            loader = buildClassLoader(mainJar, prj.getArtifacts());
    7.60          } catch (MalformedURLException ex) {
    7.61              throw new MojoFailureException("Can't initialize classloader");
    7.62          }
    7.63 @@ -101,6 +101,7 @@
    7.64              if ("provided".equals(a.getScope())) {
    7.65                  continue;
    7.66              }
    7.67 +            File aot = new File(prj.getBuild().getDirectory(), classPathPrefix);
    7.68              aot.mkdirs();
    7.69              File js = new File(aot, n.substring(0, n.length() - 4) + ".js");
    7.70              try {
    7.71 @@ -109,6 +110,23 @@
    7.72                  throw new MojoFailureException("Can't compile" + a.getFile(), ex);
    7.73              }
    7.74          }
    7.75 +        
    7.76 +        try {
    7.77 +            Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar);
    7.78 +            if (exports != null) {
    7.79 +                for (String e : exports) {
    7.80 +                    c = c.addExported(e.replace('.', '/'));
    7.81 +                }
    7.82 +            }
    7.83 +            FileWriter w = new FileWriter(mainJavaScript);
    7.84 +            c.
    7.85 +                    obfuscation(obfuscation).
    7.86 +                    resources(loader).
    7.87 +                    generate(w);
    7.88 +            w.close();
    7.89 +        } catch (IOException ex) {
    7.90 +            throw new MojoFailureException("Cannot generate script for " + mainJar, ex);
    7.91 +        }
    7.92              
    7.93          try {
    7.94              FileWriter w = new FileWriter(vm);
     8.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java	Tue May 27 09:20:06 2014 +0200
     8.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java	Tue May 27 12:25:41 2014 +0200
     8.3 @@ -108,12 +108,14 @@
     8.4          try {
     8.5              URLClassLoader url = buildClassLoader(classes, prj.getArtifacts());
     8.6              FileWriter w = new FileWriter(javascript);
     8.7 -            Bck2Brwsr.newCompiler().
     8.8 +            Bck2Brwsr c = Bck2Brwsr.newCompiler().
     8.9                  obfuscation(obfuscation).
    8.10 -                library(library).
    8.11                  resources(url, ignoreBootClassPath).
    8.12 -                addRootClasses(arr.toArray(new String[0])).
    8.13 -                generate(w);
    8.14 +                addRootClasses(arr.toArray(new String[0]));
    8.15 +            if (library) {
    8.16 +                c = c.library();
    8.17 +            }
    8.18 +            c.generate(w);
    8.19              w.close();
    8.20          } catch (IOException ex) {
    8.21              throw new MojoExecutionException("Can't compile", ex);
     9.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Tue May 27 09:20:06 2014 +0200
     9.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Tue May 27 12:25:41 2014 +0200
     9.3 @@ -58,11 +58,13 @@
     9.4      private final StringArray resources;
     9.5      private final Resources res;
     9.6      private final Boolean extension;
     9.7 +    private final StringArray classpath;
     9.8  
     9.9      private Bck2Brwsr(
    9.10 -        ObfuscationLevel level, 
    9.11 -        StringArray exported, StringArray classes, StringArray resources, 
    9.12 -        Resources res, Boolean extension
    9.13 +            ObfuscationLevel level, 
    9.14 +            StringArray exported, StringArray classes, StringArray resources, 
    9.15 +            Resources res, 
    9.16 +            Boolean extension, StringArray classpath
    9.17      ) {
    9.18          this.level = level;
    9.19          this.exported = exported;
    9.20 @@ -70,6 +72,7 @@
    9.21          this.resources = resources;
    9.22          this.res = res;
    9.23          this.extension = extension;
    9.24 +        this.classpath = classpath;
    9.25      }
    9.26      
    9.27      /** Helper method to generate virtual machine from bytes served by a <code>resources</code>
    9.28 @@ -106,7 +109,11 @@
    9.29       * @since 0.5
    9.30       */
    9.31      public static Bck2Brwsr newCompiler() {
    9.32 -        return new Bck2Brwsr(ObfuscationLevel.NONE, new StringArray(), new StringArray(), new StringArray(), null, false);
    9.33 +        return new Bck2Brwsr(
    9.34 +            ObfuscationLevel.NONE, 
    9.35 +            new StringArray(), new StringArray(), new StringArray(), 
    9.36 +            null, false, null
    9.37 +        );
    9.38      }
    9.39      
    9.40      /** Adds exported classes or packages. If the string ends 
    9.41 @@ -126,7 +133,7 @@
    9.42      public Bck2Brwsr addExported(String... exported) {
    9.43          return new Bck2Brwsr(
    9.44              level, this.exported.addAndNew(exported), 
    9.45 -            classes, resources, res, extension
    9.46 +            classes, resources, res, extension, classpath
    9.47          );
    9.48      }
    9.49  
    9.50 @@ -167,7 +174,7 @@
    9.51          } else {
    9.52              return new Bck2Brwsr(level, exported, 
    9.53                  this.classes.addAndNew(classes), resources, res,
    9.54 -                extension);
    9.55 +                extension, classpath);
    9.56          }
    9.57      }
    9.58      
    9.59 @@ -187,7 +194,7 @@
    9.60              return this;
    9.61          } else {
    9.62              return new Bck2Brwsr(level, exported, this.classes, 
    9.63 -                this.resources.addAndNew(resources), res, extension
    9.64 +                this.resources.addAndNew(resources), res, extension, classpath
    9.65              );
    9.66          }
    9.67      }
    9.68 @@ -201,7 +208,7 @@
    9.69       * @since 0.5
    9.70       */
    9.71      public Bck2Brwsr obfuscation(ObfuscationLevel level) {
    9.72 -        return new Bck2Brwsr(level, exported, classes, resources, res, extension);
    9.73 +        return new Bck2Brwsr(level, exported, classes, resources, res, extension, classpath);
    9.74      }
    9.75      
    9.76      /** A way to change the provider of additional resources (classes) for the 
    9.77 @@ -213,7 +220,10 @@
    9.78       * @since 0.5
    9.79       */
    9.80      public Bck2Brwsr resources(Resources res) {
    9.81 -        return new Bck2Brwsr(level, exported, classes, resources, res, extension);
    9.82 +        return new Bck2Brwsr(
    9.83 +            level, exported, classes, resources, 
    9.84 +            res, extension, classpath
    9.85 +        );
    9.86      }
    9.87  
    9.88      /** Should one generate a library? By default the system generates
    9.89 @@ -222,13 +232,25 @@
    9.90       * By turning on the library mode, only classes explicitly listed
    9.91       * will be included in the archive. The others will be referenced
    9.92       * as external ones.
    9.93 +     * <p>
    9.94 +     * A library archive may specify its <em>classpath</em> - e.g. link to
    9.95 +     * other libraries that should also be included in the application. 
    9.96 +     * One can specify the list of libraries as vararg to this method.
    9.97 +     * These are relative URL with respect to location of this library.
    9.98 +     * The runtime system then prefers seek for ".js" suffix of the library
    9.99 +     * and only then seeks for the classical ".jar" path.
   9.100       * 
   9.101 -     * @param library turn on the library mode?
   9.102 +     * @param classpath the array of JARs that are referenced by this library -
   9.103 +     *   by default gets turned into 
   9.104       * @return new instance of the compiler with library flag changed
   9.105       * @since 0.9
   9.106       */
   9.107 -    public Bck2Brwsr library(boolean library) {
   9.108 -        return new Bck2Brwsr(level, exported, classes, resources, res, library);
   9.109 +    public Bck2Brwsr library(String... classpath) {
   9.110 +        return new Bck2Brwsr(
   9.111 +            level, exported, classes, 
   9.112 +            resources, res, true, 
   9.113 +            StringArray.asList(classpath)
   9.114 +        );
   9.115      }
   9.116      
   9.117      /** Turns on the standalone mode. E.g. acts like {@link #library(boolean) library(false)},
   9.118 @@ -241,7 +263,10 @@
   9.119       * @since 0.9
   9.120       */
   9.121      public Bck2Brwsr standalone(boolean includeVM) {
   9.122 -        return new Bck2Brwsr(level, exported, classes, resources, res, includeVM ? false : null);
   9.123 +        return new Bck2Brwsr(
   9.124 +            level, exported, classes, resources, 
   9.125 +            res, includeVM ? false : null, null
   9.126 +        );
   9.127      }
   9.128  
   9.129      /** A way to change the provider of additional resources (classes) for the 
   9.130 @@ -319,6 +344,10 @@
   9.131      boolean includeVM() {
   9.132          return extension != null;
   9.133      }
   9.134 +    
   9.135 +    StringArray classpath() {
   9.136 +        return classpath;
   9.137 +    }
   9.138  
   9.139      /** Provider of resources (classes and other files). The 
   9.140       * {@link #generate(java.lang.Appendable, org.apidesign.vm4brwsr.Bck2Brwsr.Resources, java.lang.String[]) 
    10.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java	Tue May 27 09:20:06 2014 +0200
    10.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java	Tue May 27 12:25:41 2014 +0200
    10.3 @@ -105,11 +105,16 @@
    10.4          }
    10.5          
    10.6          try (Writer w = new BufferedWriter(new FileWriter(gt))) {
    10.7 -            Bck2Brwsr.newCompiler().library(createExtension).
    10.8 +            Bck2Brwsr c = Bck2Brwsr.newCompiler().
    10.9                  obfuscation(obfLevel).
   10.10                  addRootClasses(classes.toArray()).
   10.11 -                resources(new LdrRsrcs(Main.class.getClassLoader(), true)).
   10.12 -                generate(w);
   10.13 +                resources(new LdrRsrcs(Main.class.getClassLoader(), true));
   10.14 +            
   10.15 +            if (createExtension) {
   10.16 +                c = c.library();
   10.17 +            }
   10.18 +            
   10.19 +            c.generate(w);
   10.20          }
   10.21      }
   10.22  
    11.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue May 27 09:20:06 2014 +0200
    11.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue May 27 12:25:41 2014 +0200
    11.3 @@ -77,7 +77,7 @@
    11.4              fixedNames.add(VM.class.getName().replace('.', '/'));
    11.5              vm = new Extension(out, 
    11.6                  config.getResources(), both, config.exported(),
    11.7 -                config.allResources()
    11.8 +                config.allResources(), config.classpath()
    11.9              );
   11.10          } else {
   11.11              if (config.includeVM()) {
   11.12 @@ -487,10 +487,9 @@
   11.13                  + "    name = replaceAll(name, '.', '_');\n"
   11.14                  + "    return name;\n"
   11.15                  + "  };\n"
   11.16 -                + "  global.bck2brwsr = function() {\n"
   11.17 -                + "    var args = Array.prototype.slice.apply(arguments);\n"
   11.18 -                + "    var resources = {};\n"
   11.19 -                + "    function loadExtension(url) {\n"
   11.20 +                + "  function loadExtension(url) {\n"
   11.21 +                + "      if (url.substring(url.length - 4) == '.jar')\n"
   11.22 +                + "        url = url.substring(0, url.length - 4) + '.js';\n"
   11.23                  + "      var xhr = new XMLHttpRequest();\n"
   11.24                  + "      xhr.open('GET', url, false);\n"
   11.25                  + "      xhr.send();\n"
   11.26 @@ -498,7 +497,10 @@
   11.27                  + "      script.type = 'text/javascript';\n"
   11.28                  + "      script.text = xhr.responseText;\n"
   11.29                  + "      document.getElementsByTagName('head')[0].appendChild(script);\n"
   11.30 -                + "    }\n"
   11.31 +                + "  }\n"
   11.32 +                + "  global.bck2brwsr = function() {\n"
   11.33 +                + "    var args = Array.prototype.slice.apply(arguments);\n"
   11.34 +                + "    var resources = {};\n"
   11.35                  + "    function registerResource(n, a64) {\n"
   11.36                  + "      var str = atob(a64);\n"
   11.37                  + "      var arr = [];\n"
   11.38 @@ -556,12 +558,15 @@
   11.39                  + "      var arr = resources[name];\n"
   11.40                  + "      return (arr && arr.length > arrSize) ? arr[arrSize] : null;\n"
   11.41                  + "    }\n"
   11.42 -                + "    var reload = function(name, arr, keep) {;\n"
   11.43 +                + "    var reload = function(name, arr, keep) {\n"
   11.44 +                + "      if (!arr) throw 'Cannot find ' + name;\n"
   11.45 +                + "      var lazy = vm['org_apidesign_vm4brwsr_VMLazy'];\n"
   11.46 +                + "      if (!lazy) throw 'No bck2brwsr VM module to compile ' + name;\n"
   11.47                  + "      if (!keep) {\n"
   11.48                  + "        var attr = mangleClass(name);\n"
   11.49                  + "        delete vm[attr];\n"
   11.50                  + "      }\n"
   11.51 -                + "      return vm['org_apidesign_vm4brwsr_VMLazy'](false)\n"
   11.52 +                + "      return lazy(false)\n"
   11.53                  + "        ['load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2_3B']\n"
   11.54                  + "        (vm, name, args, arr);\n"
   11.55                  + "    };\n"
   11.56 @@ -594,6 +599,10 @@
   11.57                  + "      return false;\n"
   11.58                  + "    }\n"
   11.59                  + "    extensions.push(extension);\n"
   11.60 +                + "    var cp = config['classpath'];\n"
   11.61 +                + "    if (cp) for (var i = 0; i < cp.length; i++) {\n"
   11.62 +                + "      loadExtension(cp[i]);\n"
   11.63 +                + "    }\n"
   11.64                  + "    return null;\n"
   11.65                  + "  };\n");
   11.66              append("}(this));");
   11.67 @@ -612,21 +621,39 @@
   11.68  
   11.69      private static final class Extension extends VM {
   11.70          private final StringArray extensionClasses;
   11.71 +        private final StringArray classpath;
   11.72  
   11.73          private Extension(Appendable out, Bck2Brwsr.Resources resources,
   11.74              String[] extClassesArray, StringArray explicitlyExported,
   11.75 -            StringArray asBinary
   11.76 +            StringArray asBinary, StringArray classpath
   11.77          ) {
   11.78              super(out, resources, explicitlyExported, asBinary);
   11.79              this.extensionClasses = StringArray.asList(extClassesArray);
   11.80 +            this.classpath = classpath;
   11.81          }
   11.82  
   11.83          @Override
   11.84          protected void generatePrologue() throws IOException {
   11.85 -            append("bck2brwsr.register({\n"
   11.86 -                    + "'magic' : 'kafíčko'\n"
   11.87 -                + "}, function(exports) {\n"
   11.88 -                           + "  var vm = {};\n");
   11.89 +            append(
   11.90 +                  "bck2brwsr.register({\n"
   11.91 +                + "  'magic' : 'kafíčko'"
   11.92 +            );
   11.93 +            if (classpath != null && classpath.toArray().length > 0) {
   11.94 +                append(
   11.95 +                  ",\n  'classpath' : [\n"
   11.96 +                );
   11.97 +                String sep = "    ";
   11.98 +                for (String s : classpath.toArray()) {
   11.99 +                    append(sep).append("'").append(s).append("'");
  11.100 +                    sep = ",\n    ";
  11.101 +                }
  11.102 +                append(
  11.103 +                  "\n  ]"
  11.104 +                );
  11.105 +            }
  11.106 +            append(
  11.107 +                  "\n}, function(exports) {\n"
  11.108 +                + "  var vm = {};\n");
  11.109              append("  function link(n) {\n"
  11.110                  + "    return function() {\n"
  11.111                  + "      var cls = n['replace__Ljava_lang_String_2CC']"
    12.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Tue May 27 09:20:06 2014 +0200
    12.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java	Tue May 27 12:25:41 2014 +0200
    12.3 @@ -163,7 +163,7 @@
    12.4              addRootClasses(name).
    12.5              addResources("org/apidesign/vm4brwsr/obj.js").
    12.6              obfuscation(ObfuscationLevel.FULL).
    12.7 -            library(true);
    12.8 +            library();
    12.9          if (resourceName != null) {
   12.10              b2b = b2b.addResources(resourceName);
   12.11          }
   12.12 @@ -189,8 +189,7 @@
   12.13          Bck2Brwsr b2b = Bck2Brwsr.newCompiler().
   12.14              resources(new EmulationResources()).
   12.15              addRootClasses(name).
   12.16 -            addResources(resources).
   12.17 -            library(false);
   12.18 +            addResources(resources);
   12.19          b2b.generate(sb);
   12.20          ScriptEngineManager sem = new ScriptEngineManager();
   12.21          ScriptEngine js = sem.getEngineByExtension("js");