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

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 4.1.6
    • Fix Version/s: None
    • Component/s: Framework
    • Labels:
      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

            • Assignee:
              Unassigned
              Reporter:
              hlship Howard M. Lewis Ship
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated: