Uploaded image for project: 'Tapestry 5'
  1. Tapestry 5
  2. TAP5-927

Cannot use Scala for Tapestry IOC Modules

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 5.1.0.5
    • 5.2.0
    • tapestry-ioc
    • 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)));

      Attachments

        Activity

          People

            hlship Howard Lewis Ship
            philiplopez Philip Lopez
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: