Revision: 7430
Author: [email protected]
Date: Tue Jan 19 11:56:46 2010
Log: Provides an alternative way to encode text strings for TextResorurces
when they
exceed a certain size. Extremely large resources (12MB in my tests) caused
the
GWT compiler to crash with an Out of Memory exception.
Review by: robertvawter
http://code.google.com/p/google-web-toolkit/source/detail?r=7430
Added:
/trunk/user/test/com/google/gwt/resources/client/bigtextresource.txt
Modified:
/trunk/user/src/com/google/gwt/resources/rg/TextResourceGenerator.java
/trunk/user/test/com/google/gwt/resources/ResourcesSuite.java
/trunk/user/test/com/google/gwt/resources/client/TextResourceTest.java
=======================================
--- /dev/null
+++ /trunk/user/test/com/google/gwt/resources/client/bigtextresource.txt
Tue Jan 19 11:56:46 2010
File is too large to display a diff.
=======================================
--- /trunk/user/src/com/google/gwt/resources/rg/TextResourceGenerator.java
Tue Aug 25 15:27:02 2009
+++ /trunk/user/src/com/google/gwt/resources/rg/TextResourceGenerator.java
Tue Jan 19 11:56:46 2010
@@ -33,6 +33,12 @@
* Provides implementations of TextResource.
*/
public final class TextResourceGenerator extends AbstractResourceGenerator
{
+ /**
+ * Java compiler has a limit of 2^16 bytes for encoding string constants
in a
+ * class file. Since the max size of a character is 4 bytes, we'll limit
the
+ * number of characters to (2^14 - 1) to fit within one record.
+ */
+ private static final int MAX_STRING_CHUNK = 16383;
@Override
public String createAssignment(TreeLogger logger, ResourceContext
context,
@@ -61,7 +67,11 @@
String toWrite = Util.readURLAsString(resource);
- sw.println("return \"" + Generator.escape(toWrite) + "\";");
+ if (toWrite.length() > MAX_STRING_CHUNK) {
+ writeLongString(sw, toWrite);
+ } else {
+ sw.println("return \"" + Generator.escape(toWrite) + "\";");
+ }
sw.outdent();
sw.println("}");
@@ -76,4 +86,23 @@
return sw.toString();
}
-}
+
+ /**
+ * A single constant that is too long will crash the compiler with an
out of
+ * memory error. Break up the constant and generate code that appends
using a
+ * buffer.
+ */
+ private void writeLongString(SourceWriter sw, String toWrite) {
+ sw.println("StringBuilder builder = new StringBuilder();");
+ int offset = 0;
+ int length = toWrite.length();
+ while (offset < length - 1) {
+ int subLength = Math.min(MAX_STRING_CHUNK, length - offset);
+ sw.print("builder.append(\"");
+ sw.print(Generator.escape(toWrite.substring(offset, offset +
subLength)));
+ sw.println("\");");
+ offset += subLength;
+ }
+ sw.println("return builder.toString();");
+ }
+}
=======================================
--- /trunk/user/test/com/google/gwt/resources/ResourcesSuite.java Tue Dec
15 16:53:51 2009
+++ /trunk/user/test/com/google/gwt/resources/ResourcesSuite.java Tue Jan
19 11:56:46 2010
@@ -46,7 +46,6 @@
suite.addTestSuite(NestedBundleTest.class);
suite.addTestSuite(ResourceGeneratorUtilTest.class);
suite.addTestSuite(TextResourceTest.class);
-
return suite;
}
}
=======================================
--- /trunk/user/test/com/google/gwt/resources/client/TextResourceTest.java
Wed Sep 30 16:46:38 2009
+++ /trunk/user/test/com/google/gwt/resources/client/TextResourceTest.java
Tue Jan 19 11:56:46 2010
@@ -24,6 +24,9 @@
public class TextResourceTest extends GWTTestCase {
static interface Resources extends ClientBundleWithLookup {
+ @Source("bigtextresource.txt")
+ TextResource bigTextResource();
+
@Source("com/google/gwt/resources/client/hello.txt")
TextResource helloWorldAbsolute();
@@ -43,6 +46,17 @@
public String getModuleName() {
return "com.google.gwt.resources.Resources";
}
+
+ /**
+ * Test fix for problem where large text files caused out of memory
errors
+ * when run in hosted mode.
+ */
+ public void testBigTextResource() {
+ final Resources r = GWT.create(Resources.class);
+ String result = r.bigTextResource().getText();
+ int length = result.length();
+ assertEquals(length, 12737792);
+ }
public void testExternal() throws ResourceException {
final Resources r = GWT.create(Resources.class);
@@ -79,7 +93,7 @@
assertEquals("helloWorldExternal", r.helloWorldExternal().getName());
ResourcePrototype[] resources = r.getResources();
- assertEquals(4, resources.length);
+ assertEquals(5, resources.length);
}
public void testOutsideResourceOracle() {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors