Tapestry 5
  1. Tapestry 5
  2. TAP5-927

Cannot use Scala for Tapestry IOC Modules

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 5.1.0.5
    • Fix Version/s: 5.2.0
    • Component/s: tapestry-ioc
    • Labels:
      None

      Description

      Scala (as of 2.7.7) adds a public method $tag() to classes. It's not particularly pretty (and $tag() is apparently deprecated) but it's there. (See http://programming-scala.labs.oreilly.com/ch14.html#CommandLineToolDecompilers)

      The (new, in 5.1.0.x) checks in org.apache.tapestry5.ioc.internal.DefaultModuleDefImp mean that a module implemented in Scala throws an exception on load:

      java.lang.RuntimeException: Module class <MODULE_NAME> contains unrecognized public methods: public static final int <MODULE_NAME>.$tag() throws java.rmi.RemoteException.

      It would be nice to have a way to work around this so that Scala could be used with Tapestry IOC 5.1.0.x (including Modules). One generic approach may be to have an @IgnoredPublicMethods annotation applicable to Module classes that took an array of Strings that named methods that should also be removed from the "methods" set before checking whether there are superfluous public methods. Of course, there's always the hard-code exception too (ugly but a lot less "investment" for this pesky incompatibility).

      As an example, the following article describes Scala and Tapestry: http://fanf42.blogspot.com/2009/02/tapestry-5-scala-view-article-in-html.html. If you checkout the git project and update the Tapestry release version to 5.1.0.5, you'll see it fail, where in 5.0.x it worked.

      The relevant code is:

      109 // Want to verify that every public method is meaningful to Tapestry IoC. Remaining methods might
      110 // have typos, i.e., "createFoo" that should be "buildFoo".
      111
      112 Set<Method> methods = CollectionFactory.newSet(moduleClass.getMethods());
      113
      114 methods.removeAll(OBJECT_METHODS);
      115
      116 boolean modulePreventsServiceDecoration = moduleClass.getAnnotation(PreventServiceDecoration.class) != null;
      117
      118 grind(methods, modulePreventsServiceDecoration);
      119 bind(methods, modulePreventsServiceDecoration);
      120
      121 if (methods.isEmpty()) return;
      122
      123 throw new RuntimeException(String.format("Module class %s contains unrecognized public methods: %s.",
      124 moduleClass.getName(),
      125 InternalUtils.joinSorted(methods)));

        Activity

        Hide
        Howard M. Lewis Ship added a comment -

        Any method who names starts with '$' is now ignored.

        Show
        Howard M. Lewis Ship added a comment - Any method who names starts with '$' is now ignored.
        Hide
        Martin Kneissl added a comment -

        Unfortunately the $tag() method seems not to be marked as synthetic by the Scala compiler. The removal of synthetic methods from module definitions will not remove the $tag() method. Explicit code is required.

        Show
        Martin Kneissl added a comment - Unfortunately the $tag() method seems not to be marked as synthetic by the Scala compiler. The removal of synthetic methods from module definitions will not remove the $tag() method. Explicit code is required.
        Hide
        Peter Niederwieser added a comment -

        Probably this could be solved just like http://issues.apache.org/jira/browse/TAP5-839 by ignoring public synthetic methods in module classes.

        Show
        Peter Niederwieser added a comment - Probably this could be solved just like http://issues.apache.org/jira/browse/TAP5-839 by ignoring public synthetic methods in module classes.
        Hide
        Philip Lopez added a comment -

        changed priority to minor: workaround is to use Tapestry 5.0.x or to avoid Scala for modules.

        Show
        Philip Lopez added a comment - changed priority to minor: workaround is to use Tapestry 5.0.x or to avoid Scala for modules.

          People

          • Assignee:
            Howard M. Lewis Ship
            Reporter:
            Philip Lopez
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development