Uploaded image for project: 'Tapestry'
  1. Tapestry
  2. TAPESTRY-2758

For very complex forms, encoding the allocated ID string results in a java.io.UTFDataFormatException

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 4.1.6
    • None
    • Framework
    • None

    Description

      • java.io.UTFDataFormatException
        java.io.ObjectOutputStream$BlockDataOutputStream#writeUTF (ObjectOutputStream.java:2125)
        java.io.ObjectOutputStream$BlockDataOutputStream#writeUTF (ObjectOutputStream.java:1968)
        java.io.ObjectOutputStream#writeUTF (ObjectOutputStream.java:841)
        org.apache.tapestry.util.io.CompressedDataEncoder#encodeString (CompressedDataEncoder.java:55)
        org.apache.tapestry.engine.RequestCycle#encodeIdState (RequestCycle.java:678)
        org.apache.tapestry.form.FormSupportImpl#render (FormSupportImpl.java:482)
        org.apache.tapestry.form.Form#renderComponent (Form.java:217)

      A little digging found out that this can only happen for exceptionally large forms. The relevent code:

      RequestCycle.java:

      public String encodeIdState()

      { return CompressedDataEncoder.encodeString(_idAllocator.toExternalString()); }

      CompressedDataEncoder.java:

      public static String encodeString(String input)
      {
      Defense.notNull(input, "input");

      if (HiveMind.isBlank(input))
      return "";

      try

      { ByteArrayOutputStream bosPlain = new ByteArrayOutputStream(); ByteArrayOutputStream bosCompressed = new ByteArrayOutputStream(); GZIPOutputStream gos = new GZIPOutputStream(bosCompressed); TeeOutputStream tos = new TeeOutputStream(bosPlain, gos); ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(tos)); oos.writeUTF(input); oos.close(); boolean useCompressed = bosCompressed.size() < bosPlain.size(); byte[] data = useCompressed ? bosCompressed.toByteArray() : bosPlain.toByteArray(); byte[] encoded = Base64.encodeBase64(data); String prefix = useCompressed ? GZIP_BYTESTREAM_PREFIX : BYTESTREAM_PREFIX; return prefix + new String(encoded); }

      catch (Exception ex)

      { throw new ApplicationRuntimeException(IoMessages.encodeFailure(input, ex), ex); }

      }

      ObjectOutputStream.java:

      void writeUTF(String s, long utflen) throws IOException {
      if (utflen > 0xFFFFL)

      { throw new UTFDataFormatException(); }

      writeShort((int) utflen);
      if (utflen == (long) s.length())

      { writeBytes(s); }

      else

      { writeUTFBody(s); }

      }

      So for strings larger than 65K, we get the exception. Yes, that's an incredibly large form!

      Attachments

        Activity

          People

            Unassigned Unassigned
            hlship Howard Lewis Ship
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated: