Discussions

News: Tapestry 2.1: Java Web Components Released

  1. Release 2.1 of Tapestry: Java Web Components is now available from SourceForge. Tapestry is an open-source web component object model/framework for building web applications in Java. It reconceptualizes web application development in terms of objects, methods and properties instead of URLs and query parameters.

    More information about Tapestry is available at the Tapestry Home Page. Tapestry is licensed under the Lesser GNU Public License.

    More info
    -------------------
    Release 2.1 of the Tapestry: Java Web Components web application framework has been released and is available at SourceForge.

    Tapestry is a component object model for building dynamic, robust, scalable web applications in Java. It reconceptualizes web application development in terms of objects, methods and properties instead of URLs and query parameters ... in other words, more like building a Swing GUI than assembling a mass of servlets and JSPs.

    Tapestry allows developers to concentrate on interesting, application-specific code, rather than the low-level grunge work of building and interpreting URLs and query parameters. It allows a proper separation of HTML and Java code, and closely follows the standard Model-View-Controller patttern.

    Tapestry allows for high levels of reuse, both horizontal (same application) and vertical (different applications). Creating reusable components in Tapestry is easy and natural.

    Tapestry has been greatly enhanced since its 2.0 release in April, 2002.

    Localization support has been extended; each page or component may have its own set of localized strings, with easy access to those strings from both the component specification and within the HTML template.

    Component parameters can now be connected directly to the JavaBeans properties of a component, simplifying component creation.

    Tapestry now configures and deploys itself into JBoss 3.0.0.

    Packages have been renamed from com.primix.tapestry.* to net.sf.tapestry.*

    A sophisticated Tapestry plugin for the open-source Eclipse IDE is also available as a separate project: Spindle.

    More information about Tapestry is available at the Tapestry Home Page. Tapestry is licensed under the Lesser GNU Public License.

    Threaded Messages (57)

  2. The tapestry home page does not seem to be working.
  3. That's SourceForge for you ... its free and you get what you pay for. Just checked, and its back up.

    The stuff housed on SourceForge is completely static, except for the Wiki. The live Tapestry demos actually run on other machines provided by various cool folks in the Tapestry community.
  4. Downloaded from the Sourceforge site, unpacked, configured the demo using the instructions in the Readme.html file and....it works flawlessly! Very impressive framework and equally impressive documentation and packaging. Thanks!
  5. We have been using Tapestry since 2.0.0 and have nothing but praise for it. It has worked as expected each and every time (except for a minor issue with statefulness, which was fixed with one line of code).

    Like they say, "Objects, methods, and properties". It is so easy. It's like Visual BASIC for the web. I took Torque from the Apache Turbine project and added it to Tapestry and was able to display the data from the database in a nice formatted table in less than 10 lines of actual JAVA code (thanks to Spindle, the IDE plugin for Eclipse for creating Tapestry Applications.) It was amazing. It's form support is great (if the user inputs a date, they are required to enter it in the correct syntax and the result is stored as a Date object, not as a String that you then need to turn into a Date object yourself). I highly recommend it (especially because it has an IDE).
  6. I just want to second the positive comments about Tapestry. We have evaluated a lot of frameworks in the past couple of years, and in our opinion Tapestry is the only open source Java framework at the moment that provides everything necessary for Web-centric component oriented development.

    The most important feature of Tapestry is indisputably the ability to package common Web functionality into components that can then be effortlessly reused again and again. Building a Tapestry application is pretty much like playing with Lego bricks -- all you have to do is just fit the different pieces together and not worry about how each brick would work internally or how the different pieces would interract with one another (an OO approach at its best). As a result, after gaining some experience and accumulating a set of components, one can build incredibly complex Web applications quickly and easily, and yet be assured that those applications are of a very high quality.

    Tapestry has another major advantage as well -- it provides very clean separation between presentation and logic (cleaner than that of the most commonly used frameworks). The design of its templates is also very mindful of the actual web development process, accomodates very nicely the work of the web designers from the start, and allows them to play along even in later stages of the application development. This, again, is something rarely found in the other frameworks.

    I will mention just one more superb feature -- the Tapestry design and APIs provide a huge number of extension points that allow you to customize the behaviour of the framework almost to no end. In order to achieve a specific goal for one customer we twisted the behaviour of the system so much, that Howard would faint if he sees it. In any case, being able to easily modify and extend specific elements of the framework is a major advantage.

    This may sound a bit like an advertisement, but it is not -- we are just very satisfied users. We've got a significant increase in productivity, we've got increased quality, we've got happy web designers, and we've put an end to the repetitive operations -- it would be hard to think of a better scenario.

    If you are experienced in OO and/or components and care about Web development, I would suggest that you have a look at tapestry. I would be very surprised if you do not find it a far more viable solution for your needs than JSP or Struts, for example.

    -mb
  7. Effortlessly reused? Ha!
    To embed the component (f.e. link to home) I have to make 3 entries:
    - java method in respective class
    - tag entry in HTML template
    - entry in xml descriptor (jwc)
    Any inconsistence between entries will come clear only after deployment, on first request.
    And all these is just a replacement for old plain "a" tag!
    May be IDE makes this easy...
  8. Hi Victor,

    If you use Spindle, the Tapestry plugin for Eclipse, creating a new component/page involves several clicks with the mouse -- there is a simple wizard that does all the work for you. Inserting an existing component into the new one and setting up the parameter exchange between the two (the bindings) also involves only a few clicks. The potential for making mistakes is minimal and the speed of the operation is very high.

    In addition, a static validator for Tapestry is available (developed by us, incidentally) that checks the correctness of your code at build time, and discovers mistakes that might have occurred (although with Spindle the potential for that has dropped significantly). The validator integrates with Ant, and can work either as an Ant task, or standalone if necessary. It is possible that Howard would integrate this tool into Tapestry distribution -- then such questions would not arise :-).

    As I said earlier, this is not propaganda -- we and a lot of other people are using the framework for real, and are reaping significant benefits from it. Look at it this way -- from our view point the difference between it and the other options in the field (esp. JSP/Struts) is so significant, that we feel that we must must come to these forums and let other people know about it. This is something that I do not normally do, and feel a bit like a clown while doing it, but feel that it must be done simply because it would be an incredible shame for a gem like Tapestry to go unnoticed and for some much less inspired technologies to win the developers' mindshare purely due to lack of information.

    I hope this helps,
    -mb
  9. Complexity ....[ Go to top ]

    Effortlessly reused? Ha!

    > To embed the component (f.e. link to home) I have to make > 3 entries:
    > - java method in respective class
    > - tag entry in HTML template
    > - entry in xml descriptor (jwc)
    > Any inconsistence between entries will come clear only
    > after deployment, on first request.
    > And all these is just a replacement for old plain
    > "a" tag!

    First off, for simple links to new pages, you don't need to create any Java code ... but that's besides the point.

    For simple, demo-ware use cases like this, of course the weeker technology is simple. Let's try adding a few things ...

    We start with the following:

    <aa jwcid="homeLink">Home</aa>

    (Had to use "aa" instead of "a" here because of ServerSide's forums. Interestingly, Tapestry doesn't really care and this would work in production as is!).

    ....

    <component id="homeLink" type="Page">
      <static-binding name="page">Home</static-binding>
    </component>

    ....

    Ok, what if we're already on the Home page, so we don't want the link to be a link (but we still want to render the text, "Home"). We add a new parameter binding:

      <binding name="disabled" property-path="disableHomeLink"/>

    And we add a new property accessor method:

      public boolean getDisableHomeLink()
      {
        return getPage().getName().equals("Home");
      }

    ....

    Wait, my mistake, that shouldn't be the text "Home", it should be a graphic image for Home, with a mouse-over ... oh, and another image for when we are on the Home page (to visually show to the user that they are on the Home page).

      <aa jwcid="homeLink"><img jwcid="rollover"/></aa>

      <component id="rollover" type="Rollover">
        <binding name="image" property-path="assets.home"/>
        <binding name="focus" property-path="assets.home-focus"/>
        <binding name="disabled" property-path="assets.home-disabled"/>
      </component>

      <context-asset name="assets.home" path="/images/Home.gif"/>
      <context-asset name="assets.home-focus" path="/images/HomeH.gif"/>
      <context-asset name="assets.home-disabled" path="/images/HomeD.gif"/>

    The new Rollover component works with the existing Page component to determine whether to show the normal image or the disabled image, and whether to generate JavaScript for the rollover effect. Also note that we have a programmer-friendly way of specifying assets (a generic term for images, stylesheets, etc.) regardless of what wierd names the graphic designers use.

    ....

    I won't even get into the next use cases, involving localization. Tapestry takes care of this as well, managing localized string .properties files, and providing easy access to thier contents, as well as tracking (for each user) what locale they are using.

    ....

    The point I'm making is that as your application complexity increases, Tapestry is right there with you. Incremental changes in behavior and matched by incremental changes in the application code (HTML, specification and Java code).

    Using other frameworks, this is far from the case. Once you venture forth from demo-ware land, small changes to the application behavior can trigger land-slides of work.

    Finally, Tapestry has been developed in a very focused way to support team development ... streamlining the interactions between Java developers, but also between a graphic designer team (the HTML guys) and a Java developer team. In the examples above, the Tapestry HTML template is straight HTML, with the addition of the jwcid attribute ... this means it still previews correctly in a WYSIWYG editor even *after* it has been instrumented for use with Tapestry.

    Most other frameworks are one-way; once you instrument, you've added all sorts of bizarre, non-HTML junk (or stripped out some needed HTML junk) and what's left is not going to preview.
  10. Complexity ....[ Go to top ]

    Typo ... that should be:

     <context-asset name="home" path="/images/Home.gif"/>
      <context-asset name="home-focus" path="/images/HomeH.gif"/>
      <context-asset name="home-disabled" path="/images/HomeD.gif"/>
  11. Complexity ....[ Go to top ]

    For those of us who like flexibility, is Tapestry providing a way to control session management, session failover, declarative access-control, multi-form pages etc. ?

    And without the right editor, I really don't like "programming" in XML better than Java. Hopefully the editor provides help for that part, so that people can focus on the code rather than the glue XML.
  12. Complexity ....[ Go to top ]

    "And without the right editor, I really don't like "programming" in XML better than Java. Hopefully the editor provides help for that part, so that people can focus on the code rather than the glue XML."

    You described why I started writing the Spindle plugin in the first place.

    Geoff
  13. Server-side state[ Go to top ]

    Tapestry leverages the servlet API, specifically the HttpSession, to maintain server-side state ... but your code will never see it.

    Remember the mantra: "Objects, methods and properties". Server-side state is managed by Tapestry, but is visible to your application code simply as properties that persist between request cycles; the developer is responsible for adding a single line of code to the setter method to make properties persistent.

    In addition, there's a global object, called "the visit", which persists as well; the visit can be any object, even a HashMap.

    However, if you want to access the HttpSession directly (perhaps because you are gluing together a JSP application to a Tapestry application), it is always available as well.

    About the editor ...

    Geoff has done a great job on Spindle. Yes, you are programming in XML (even using the editor), but that's ok ... its very high level declarative programming. Basically, you provide the what and the when and Tapestry provides the how.
  14. Server-side state[ Go to top ]

    <quote>
    Geoff has done a great job on Spindle. Yes, you are programming in XML (even using the editor), but that's ok ... its very high level declarative programming. Basically, you provide the what and the when and Tapestry provides the how.
    </quote>

    To be honest, I only heard good opinions about the Eclipse module. I don't want to start yet another IDE war, but since we have quite a large team using Netbeans, are you aware of any project writing a similar plug-in for Netbeans/Forte? Thanks!
  15. I can't find much in terms of comparisons with Struts. For the folks out there that have been using Tapestry actively, can you spend a little time comparing and contrasting the two frameworks?

    thanks in advance,
    Evan
  16. This came up for discussion when Tapestry 2.0 was released.
  17. Tapestry is more similar to Apple's WebObjects or .Net's WebForm than Struts or WebWork. With Struts, developer has to write more code by defining Actions, a kind of mini servlets.
    Tapestry's main strength is strong support for web components. From the Tapestry's Developer Guide:
    "A Tapestry component is defined by its specification. The specification is an XML file that defines the type of the component, it parameters, the template used by the component, any components embedded within it and how they are 'wired up', and (less often) any assets used by the component.
    At runtime, the specification is used to identify and instantiate a class for the component. When the page containing the component is rendered, the component will access its HTML template to find the static HTML and embedded components it will render."

    Unfortunately Tapestry doesn't have a widespread community support as Struts and JSPs or even WebWork do.

    I recommend: Any developer should give an opportunity to Tapestry framework. It could change his life for good.

  18. I'm interested in looking at Tapestry, but
    I'm also thinking of using Flash MX....maybe
    with Remoting (if I can get it working with JBoss)

    Can you use a non-html front end with Tapestry, such
    as FlashMX?

    Thanks,

    Dorwin
  19. Howard,

    I'm following your work since your excellent JavaReport article "Build Feature-Rich World-Class Web Applications" back in June 2000. There you described a set of MVC pattern and the ServletUtils library. Then you have created the Tapestry library, which is a radical departure from JSP and Servlets world.

    I think you are doing really excellent and quality work for the Java community. I'm just wondering: I think you initially created these libraries to have a good reason for management to switch from Microsoft (Active Server Pages) to Java, because JSP itself had no real advantage to JSP/Servlets back then.

    But now with ASP.Net, what do you think about it when comparing it to Tapestry? E.g. code-behind pages in ASP.Net require you to define controls as server side (similiar to your jwcid) and to write a C# class with the implementation of the page (can also be embedded into the page directly). What's not required in the Microsoft World is an XML file, because this information is already in the page. In general I think that ASP.Net (with Server Side Controls, events, ViewState, automatic mapping to C# code, etc.) is much more accessible and easier to use.

    A few points I do not like so much about Tapestry:

    1. Do I have to restart the server to see changes on my pages? If yes then this would be a major limitation...
    2. I do not like the Urls with all these parameters, I prefer simple URLs (like with JSP and ASPX pages).
    3. Tapestry seems to have a steep learning curve and is non-standard

    Regards
    Bernhard
  20. Tapestry vs. ASP.Net[ Go to top ]

    Someone actually read that article? :-)

    I can't really compare Tapestry to .Net as I haven't even read anything about .Net.

    1. Do I have to restart the server to see changes on my pages? If yes then this would be a major limitation...

    During development, you can disable caching of templates and specifications. This makes the pages a little more sluggish, but changes are visible immediately.

    2. I do not like the Urls with all these parameters, I prefer simple URLs (like with JSP and ASPX pages).

    An earlier version of Tapestry used simpler URLs that made use of path info instead of query parameters. I liked those more, they were prettier.

    Old/Pretty: /vlib/app/page/Login

    New/Ugly: /vlib/app?service=page&amp;context=Login

    The change was made so that the "relative" location of the servlet was fixed; which allows static portions of templates to reference assets (images, etc.) using a relative syntax (i.e., "images/logo.gif" instead of "/vlib/images/logo.gif") ... the latter requires that the application always be deployed as "/vlib" which is not good.

    I've been thinking of changing it back, and just making the standard Shell component (which provides the <html> and <head> tags) to provide a <base> tag.

    On the other hand, ugly URLs are not all that important ... its not like anyone has to type them ever.

    3. Tapestry seems to have a steep learning curve and is non-standard

    The learning curve is actually pretty shallow if you've used WebObjects :-)

    Tapestry is non-standard because the standards are lacking. JSPs especially are about getting a quick bang for the buck, but simply don't scale in complexity. Tapestry requires the developer to do a little more to get off the start line, but by the time you're actually doing real development (say, a couple of days later) you are ahead of the game because of all the stuff you don't have to think about.

    Gradually, things in Tapestry are getting simpler. Listener objects (as inner classes) have been replaced with listener methods. Parameter bindings are now pretty much invisible. The ugly old HTML template has given way to the modern template with its "magic markup". I'm thinking about simplifying how persistant page properties work to, again, let the framework do more and the developer do less.

    What's more important is that the Tapestry community is growing, and more tutorials and cookbooks are on the way. Geoff has done a stunning job with Spindle.

    What I'm looking forward to in the future are RAD tools built on Tapestry. Tapestry's construction is perfect for RAD: most of the application can be provided in XML specifications,. which are much more flexible than Java code. Helper beans exist to help with RAD, since its easier and better to provide a JavaBean to perform some functionality than to machine-generate Java code.

    I'm also waiting for new layerings; someone who builds on Tapestry the way Tapestry builds on Servlet API.
  21. Tapestry vs. ASP.Net[ Go to top ]

    RE: new vs old style URLs

    My understanding is that many search engine spiders (google's may be the exception) often stop when they find a query parameter, i.e. '?' or '&'. That means that the vast majority of pages of a site built on Tapestry may never get indexed!

    Not only is the old style much nicer but it also helps with search engine optimisation.

    Cheers, Matt
  22. Tapestry vs. ASP.Net[ Go to top ]

    Howard,

    this is quite an interesting read. I was developing with WebObjects from 3.0 thru 4.5 before I could not find anymore WO-projects :-)

    I do not know Tapestry yet, but always thought of JSP as very cumbersome when compared with WO and WO-related frameworks. As you have both WO and Tapestry experience can you give some insight on the differences/similarities (just for presentation layer)?

    Things that would interest me:
    - Is it easy to extend FormComponents similar to DateField (like SSNField, AmountField, PatternField etc.) for validation/conversion purposes?
    - How do components interact (subcomponent to parent / subcomponent to subcomponent) in a page
    - Is there any kind of request-response-loop like in WOComponents with takeValuesFromRequest/appendToResponse etc? (I've seen methods like beginResponse, renderPage)
    - When supporting different markups (HTML/WML/XML...), would you just need to dynamically set the according IResponseWriter (in WO I remember duplicating the .wod for each markup, which was not too elegant)

    Thanks
    -the.b.o.b.
  23. Tapestry vs. WebObjects[ Go to top ]

    Well, I don't know the internals of WOF at all. WOF showed that it could be done, and on I trudged.

    Tapestry has a ValidField component, into which you plug an IValidator that is responsible for converting between object values and string values and applying any arbitrary validations (of format, of range, etc.). You can easily extend or implement new validators. This plugs into the overall Tapestry form validation. Check out the Workbench tutorial for details.

    Components are in a hiearchy. Each component knows its parent, the page that contains it, and has a Map of components it embeds. During the rendering process, components can record themselves into the IRequestCycle using a well known name and components they wrap can find them, to provide services.

    For example, all the dynamically generated JavaScript on a page is accumulated into a single block by the Body component (which replaces the <body> tag) using this mechanism. Any component that renders inside the Body ("wrapped" by Body is the Tapestry phrasing) can locate the Body and get services from it.

    Likewise, a Form wraps form element components, the various link components can interact with Rollover components within them, etc. It's very powerful and flexible.

    Tapestry has a Block and InsertBlock component pair. A Block wraps around some amount of content, the InsertBlock can Insert that content. The Portal demo shows how you can use a Block to effectively pass a piece of one page into another page for renderring. Mind boggling.

    The request/response loop exists and is encapsulated in the IRequestCycle object. Tapestry is more dynamic than WOF in some ways; components have a single method, renderComponent() that is responsible for emitting HTML (or other markup) during renderring, and for pulling query parameters and stuffing the results into properties during "rewind" (a mock render used to process form submissions and the like). The most powerful, and confusing, part of Tapestry.


    Each page provides a IMarkupWriter, an object used to write its own flavor of SGML-style markup; the default is an HTMLMarkupWriter, but there's a WMLMarkupWriter in the framework and an XMLMarkupWriter is darn easy as well. To generate PDF, you'd have to create XMLMarkup and somehow translate it to PDF, I guess ... not an area that's received much attention yet.

    I try to keep the design of Tapestry flexible and agile, but I also follow the philosophy of not designing in more than I need. Tapestry has gracefully expanded over its lifetime, and shows no signs of slowing down. I just try to keep pragmatic, and keep the documentation up to date.

    My theory on different outputs (HTML, WML, XML, etc.) is that each of these use cases (a desktop, a palmtop, a cell phone) is a markedly different experience. For example, a cellphone interface should really be just a tiny handlful of most useful actions, markedly different from the whole experience possible with HTML for a desktop.

    Trying to support all of these in one go is a mess ... I call it "coding in a case statement", far too many hidden interdependencies; fix an HTML bug and cause a cell phone bug, etc. Different experiences call for different presentation layers ... a Tapestry HTML app, a Tapestry WML app, etc.

    Still plenty of room for reuse in the non-presentation layers; and even in the presentation layer, the Java classes are generally reusable (even if the templates and component specifications are not).


  24. Tapestry vs. WebObjects[ Go to top ]

    Why would you create different apps for different markups? The way you described it, it should be fairly simple to integrate some sort of ResourceManager for Tapestry, that reads what kind of device/user agent and decides what kind of markup to return for the request, usually:

    WebBrowser->HTML
    WAPBrowser->WML
    ...
    Default->XML

    Depending on this, the same java component could be reused, but with different markup templates/component specifications.

    Like this, the same app smoothly serves all markups and there is no need to code three different apps (with different presentation layer). There are no case statements/conditionals needed.

    Does something like this exist (it does in WO), and if not, would you find it useful?
    -the.b.o.b.
  25. Tapestry examples?[ Go to top ]

    Tapestry sounds interesting, however, I'm wondering if there was an example out there shows off the capabilities of the framework.

    I've seen some pretty impressive work done using Turbine (i.e. Scarab), Jive is another pretty impressive web application, although I'm not sure how it's done. Is there anything similar for tapestry?

    Also, do I get a table component with column sorting, multi page scrolling for free in tapestry?
  26. Tapestry examples?[ Go to top ]

    Please visit the home page. There are a number of tutorials, plus the Virtual Library, a small yet complete J2EE application.

    The table component you describe (I would call such a thing a "Browser") is possible; the Vlib includes a component to do such a thing, but its currently specific to the Vlib application.

    The trick is to properly abstract the data source, so that a generic component can interact with different kinds of data source (driven by SQL, by EJBs, etc.). And then to do it in such a way that you can apply whatever look-and-feel you want to it. Tricky stuff, but doable with Tapestry.

    For an example of what you can do with reusable components, check out the Palette component

    http://www.onjava.com/pub/a/onjava/2001/11/21/tapestry.html
  27. Tapestry vs. WebObjects[ Go to top ]

    Yes, people on the developer list have made noise about this kind of feature a bit, but it hasn't quite shaped up into anything yet.

    In theory, you could provide your own implementation about ITemplateSource that selected an appropriate template based the "flavor" (HTML, WML, XHTML, XML, etc.) of the application.

    The problem is that each of these presentation "flavors" would use a different subset of components. Currently, Tapestry enforces that each component specified in the (HTML) template must be defined in the component specification exactly once.

    Again, I strongly feel that there is plenty of room for reuse, even within the presentation layer, without turning each page and component into a big, awkward "case statement".

    It's hard to discuss this outside the context of a specific application ... perhaps you could describe your situation (or that previous project) and we could examine how this would fit into the Tapestry model.

    Also, much as I like to see that message count increase here, it may be more advantageous to discuss this on the Tapestry developer mailing list, or the Tapestry Wiki.
  28. Well, I was considering Tapestry as an option for my project and found out that maybe it's not the best solution in my case. I was considering different frameworks, starting from conventional Struts/JSP to template engines like Tapestry and Velocity.

    Yeah, for html presentation Tapestry is superior and the Spindle plugin is great. Probably this pair is the best on the market. But after spending one week with that stuff I decided that maybe it's not the right thing for me right now.
    I did not like the following things:
    1. There is no clean separation between layers like you have in MVC. I was not exited with the idea of implementing lots of logic in listeners.
    2. Maybe I missed something, but I have not found a way to attach objects to request and forward that stuff to another page. I was not exited with the idea that I have to pass everything via session when I need to make the object available only within a request scope.
    3. According to the documentation, currently Tapestry is tuned for HTML only and if I will need to generate some other type of content (for example, xml or other crap) then I'm trapped.
    4. It seemed to me that once you selected Tapestry as framework, you're locked in it. Integrating other stuff to it could be quite time consuming.

    From my point of view, if I could cross Model/Controller from Struts and View from Tapestry that would satisfy my needs and convince me to go with it.

    I would really appreciate if someone could explain me how to resolve these issues. In this case I could consider Tapestry as a base for future project, because I'm already sick with these JSPs :-)

    By the way, I suppose that if the component developers could get the type of the tag that was used to embed the component then they create even more flexible components.

  29. "1. There is no clean separation between layers like you have in MVC. I was not exited with the idea of implementing lots of logic in listeners."

    The way Tapestry works is that the listeners need not be in a component or even a page. I'm sure Howard will extoll the virues of using the bean aspect of the specification. It's easy to instrument a bean to handle the listener stuff. We actually have Controller beans that are attached to a visit that control page navigation, business rules, etc. The controller bean implements listener methods that are triggered and, among other things, control what pages are displayed.



    "2. Maybe I missed something, but I have not found a way to attach objects to request and forward that stuff to another page. I was not exited with the idea that I have to pass everything via session when I need to make the object available only within a request scope."

     You can easily pass objects between pages within the context of a request.

      NextPage npage = (NextPage)getPage("Next");
      npage.setData(x);

     Where you define X and the setData() method in NextPage


    "3. According to the documentation, currently Tapestry is tuned for HTML only and if I will need to generate some other type of content (for example, xml or other crap) then I'm trapped. "

    Is this true? I know people have produced WAP apps with Tapestry.


    "4. It seemed to me that once you selected Tapestry as framework, you're locked in it. Integrating other stuff to it could be quite time consuming."

    Pretty wide statement. What are you thinking of integrating? We've had no problem using Tapestry with EJB, TOPLink, etc. But I don't know what you are asking.
  30. to clarify my last about passing data between pages:

    This is in the context of a listener method

    public void myListener(IRequestCyle cycle)
      throws RequestCycleException {

      NextPage npage = (NextPage)getPage("Next");
      npage.setData(x);
      cycle.setPage(npage); // pass control to NextPage
    }

    Where you define X and the setData method in NextPage



  31. Problem at the install[ Go to top ]

    Just downloaded JBoss 3.0.0 and Tapestry 2.1. I configured ant and ran the build. The installer expects to find the ${jboss.server.default.dir}/deploy/jetty-plugin.sar file but that file does not belong to JBoss 3.0.0.

    I downloaded it from:

    http://jboss.sourceforge.net/demo/netboot/server/j2ee/deploy/

    and everything was fine.

                   Yann
  32. Problem at the install[ Go to top ]

    Others have not had this problem, any chance you downloaded the Tomcat version of JBoss?
  33. Problem at the install[ Go to top ]

    I did not have this problem either. I got JBoss source from CVS and built it. Perhaps, did you get JBoss from the JBoss website download page which has prebuilt binaries?
  34. Problem at the install[ Go to top ]

    Can't find docs on using Tapestry with other app servers. Anyone know about that?

    The readme says

    The Virtual Library can only be auto-configured using the JBoss 3.0.0 distribution.

    huh?

    -Newt
  35. Problem at the install[ Go to top ]

    It's just a matter of getting the Tapestry JARs into the classpath, and deploying the WAR. People use Tapestry quite succesfully with WebLogic, WebSphere and Resin, and probably more beyond that (those are just common observances from the Tapestry Developer mailing list).

    The Virtual Library uses some EJBs, including CMP 2.0 entity beans, that are configured for JBoss 3.0.0, including JAWS. With a modest effort (to redo the entity beans) there should not be a problem porting to different databases or vendors ... however, since JBoss is free and freely available, it made sense to deply the *demo* into JBoss (especially because its a virtually automatic process).
  36. Problem at the install[ Go to top ]

    [quote]
    It's just a matter of getting the Tapestry JARs into the classpath, and deploying the WAR.
    [/quote]

    I just try Tapestry 2.1 with latest resin and it doesn't work. The main tapestry JAR and the contrib JAR I put in resin/lib directory then I place the tutorial.war in resin/webapps directory.

    My browser show this message while loading the HelloWorld example:

    java.lang.NoClassDefFoundError: net.sf.tapestry.ApplicationServlet
    at java.lang.Class.newInstance0(Native Method)
    at java.lang.Class.newInstance(Class.java:237)
    at java.beans.Beans.instantiate(Beans.java:207)
    at java.beans.Beans.instantiate(Beans.java:51)
    at com.caucho.server.http.Application.instantiateServlet(Application.java:2922)
    at com.caucho.server.http.Application.createServlet(Application.java:2866)
    at com.caucho.server.http.Application.loadServlet(Application.java:2827)
    at com.caucho.server.http.QServletConfig.loadServlet(QServletConfig.java:428)
    at com.caucho.server.http.Application.getFilterChainServlet(Application.java:2586)
    at com.caucho.server.http.Application.buildFilterChain(Application.java:2542)
    at com.caucho.server.http.Invocation.service(Invocation.java:309)
    at com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:135)
    at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:218)
    at com.caucho.server.http.HttpRequest.handleConnection(HttpRequest.java:160)
    at com.caucho.server.TcpConnection.run(TcpConnection.java:137)
    at java.lang.Thread.run(Thread.java:484)

  37. Problem at the install[ Go to top ]

    Please use the Tapestry developer mailing list to discuss problems installing Tapestry. I know for a fact that people are using Resin and Tapestry and the community can help you determine your configuration problem.

    Tapestry-developer mailing list
    Tapestry-developer at lists dot sourceforge dot net
    https://lists.sourceforge.net/lists/listinfo/tapestry-developer
  38. Problem at the install[ Go to top ]

    I had the same problem yesterday. You need the following in your WEB-INF/lib (or the server lib directory):

    net.sf.tapestry-2.1.jar
    net.sf.tapestry.contrib-2.1.jar
    log4j-core.jar

    in addition to the JARs that are already there.
  39. Problem at the install[ Go to top ]

    Howard,

    That was indeed the case. I found out immediately after posting yesterday, dammit! Well, it still can be useful for others who thoughtlessly did the same. :)

    Cheers,

                    Yann
  40. I have spent some time looking at Tapestry, but I fail to see how it could possibly simplify what I am already doing with Struts, Tiles, JSP and tags. In fact, it appears to be even more complicated -- numerous configuration files and references to elements of those configuration files in the source code.

    For me, MVC2 is easy to understand, provides clean separation of responsibilities, and the Struts implementation is top-notch.
  41. Tapestry Vs. Struts[ Go to top ]

    <quote>
    I have spent some time looking at Tapestry, but I fail to see how it could possibly simplify what I am already doing with Struts, Tiles, JSP and tags. In fact, it appears to be even more complicated -- numerous configuration files and references to elements of those configuration files in the source code.

    For me, MVC2 is easy to understand, provides clean separation of responsibilities, and the Struts implementation is top-notch.
    </quote>

    Bzzzzt. Sorry, thanks for playing.

    I work with Struts every day (ironic, isn't it) so I know its vast limitations, and Tapestry's great strengths. Struts is confusing, under-documented, non-scalable (in terms of app complexity), doesn't support creation of reusable components, lacks flexibility, and requires far too much Java code.

    When you have 40 developers on two coasts assembling an application, separate and *independent* configuration files are the way to go.

    I'm not sure where you got the idea that the Java code references elements from the specification; this doesn't happen very often and when it does, its the equivalent of pulling a localized string from a .properties file.

    In Tapestry, the specification *is* the component, the Java class exists to fulfill the Controller role in MVC -- to help glue the model to the View (the HTML template). The component reads and writes JavaBeans properties of the class, and invokes listener methods supplied by the class.

    In your listener code, the properties you need will have already been set before the listener is invoked. That is a *very* clean seperation ... you code doesn't need to know what component put the value there, not even the name of the component; it all just happens.

    Tapestry is the best implementation of MVC2 out there. The difference is that in Sun's diagrams there's an "application specific code" bubble in the middle of the code *you* have to write but in Tapestry you *just* write that application specific code ... Tapestry takes care of all the URL building and parsing, and all the stuff involving query parameters. All that Servlet API stuff is still there, you just *don't need to use it*.

  42. Tapestry Vs. Struts[ Go to top ]

    Thanks for the detailed reply. If nothing else, I admire your enthusiasm for the framework.

    <quote>
    Struts is confusing, under-documented, non-scalable (in terms of app complexity), doesn't support creation of reusable components, lacks flexibility, and requires far too much Java code.
    </quote>

    Under-documented? Perhaps you have not seen the O'Reilly book under development and review on this site? Not to mention the numerous examples and tutorials scattered about the Web.

    Creation of "reusable components" can be (and has been) done with custom tags. I certainly don't need another framework for that. Show me a "reusable component" that can't be done with tags, but can be done with Tapestry.

    Lacks flexibility? That is pretty vague, but if flexibility means numerous interdependent configuration files, then I'll take the "lack of flexibility".

    Non-scalable? Another vague one, but I certainly have not witnessed it, and I certainly don't see how Tapestry helps out here.

    Requires too much Java code? I would rather write Java code (I am a programmer, after all) than weed my way through configuration files trying to figure out what is going on. How well do those configuration files do in a debugger?

    <quote>
    When you have 40 developers on two coasts assembling an application, separate and *independent* configuration files are the way to go.
    </quote>

    Um, Struts does support multiple configuration files. Perhaps you should read the book :).

    <quote>
    I'm not sure where you got the idea that the Java code references elements from the specification; this doesn't happen very often and when it does, its the equivalent of pulling a localized string from a .properties file.
    </quote>

    From the tutorial (details omitted):

    in the HTML:

    <p>The current date and time is: <b><span jwcid="insertDate">Current Date</span></b>

    then in the spec (.jwc):

      <component id="insertDate" type="Insert">
        <binding name="value" property-path="currentDate"/>
      </component>

    then in the .java file:

      public Date getCurrentDate()
      {
        return new Date();
      }

    Here we have three levels of indirection (insertDate -> currentDate -> getCurrentDate()) -- I don't see the benefit of this. Perhaps you can shed some light....

    <quote>
    Tapestry is the best implementation of MVC2 out there.
    </quote>

    Well, you are entitled to your opinion :).

    In general, I don't see a clean separation of responsibilities. As an example (again from the tutorial):

      <component id="group" type="RadioGroup">
        <binding name="selected" property-path="misses"/>
      </component>
      
      <component id="inputEasy" type="Radio">
        <field-binding name="value" field-name="tutorial.hangman.Home.EASY"/>
      </component>
      
      <component id="inputMedium" type="Radio">
        <field-binding name="value" field-name="tutorial.hangman.Home.MEDIUM"/>
      </component>
      
      <component id="inputHard" type="Radio">
        <field-binding name="value" field-name="tutorial.hangman.Home.HARD"/>
      </component>

    Here the component types (radio group and radio buttons) are defined outside of the HTML. How does this simplify a page designer's life? Add on the "listeners" and I'm already lost. Too many cross-file dependencies for me.

    Perhaps you could point me to a Struts implementation of "Hangman" and show that it is more complicated ....
  43. Tapestry Vs. Struts[ Go to top ]

    Where Struts fails is when attempting to create components.
    It's not so bad for output-only components, but once the component has unique behaviors of its own (i.e., contains links or a form) things get tricky ... the component has to have special knowledge of the page that contains it. If you can encode that as a named forward, it's not too terrible (just yet another parameter for the JSP tag), but if the JSP requires any special setup before renderring (i.e., storing relevant values as HttpServletRequest attributes before renderring) then you start to have a real problem.

    Struts documentation may be coming around but it generally doesn't address the more important, but less obvious, issues of dealing with ever increasing application complexity. Successful application grow every more complex and whatever ad-hoc naming and dispatch system your start with eventually becomes a limitation.

    Tapestry bypasses this by having a single naming and dispatch system that handles any level of complexity. This is a byproduct of the component object model, where each component knows its page and containing component ... its possible to build a complete "path" to the component as part of the URL. Even when components are nested a dozen levels deep, the system still works.

    If you look at the earlier examples on this page, you'll see the Rollover component. Very basic, yet it leverages the Tapestry COM to do a number of useful things:
    1) Discovers containing link component and adjusts its appearence if the link is disabled
    2) Discovers te containing Body component, and uses it to pre-load images
    3) Uses Body to insert necessary JavaScript functions to handle rollovers
    4) Has containing link render necessary JavaScript event handles into <aa> tag

    The end result is clean, flexible HTML, with all JavaScript in a single block (not scattered across the page).

    These same approaches build to allow mega components like the Palette.

    Scalability:

    Because of the way Tapestry organizes server side state, it makes it possible for an application to *discard* no longer needed state (you can "forget a page" and any server side state associated with it). This allows an application to avoid bloating out the HttpSession, which is vital in terms of maintaining scalability.

    Complexity:

    Another area where Tapestry supports complexity is by allowing components to have their own HTML template. JSP tags need to write their HTML in Java code ... a step backwards to servlets. Yes, you could hack something together where the content was assembled using Velocity or something ... but Tapestry naturally handles this kind of things, recursively, with support for components that wrap content (including other components) and naturally integrates everything together.

    Java code:

    Tapestry is about writing interesting Java code. I never want to write code to convert a query parameter into an Integer again ... with Tapestry I don't have to. Tapestry has built-in detail exception catching and reporting ... more code I don't have to write again.

    Yes Struts supports multiple specifications (I'm using the semi-official patch), but its really one big specification divided into seperate files. That means everyone has to be careful about naming, to avoid conflicts. It also means a typo introduced by lazy developer A will screw developers B through Z.

    Tapestry configurations are *independent* not *interdependent*. Changes are extremely localized. If I screw up my page's specification, only my page is affected, not a different page in the same application.

    ... First tutorial example ( currentDate ) ...

    I think you are confusing the roles of the web developer and the java developer, or requiring that they do each other's work. In this example, the initial HTML template would have a dummy value for date:

      The current date and time is:<b>Jan 1 2001 2:13 PM</b>

    The Java developer would recognize that date was dynamic and convert it into a component.

      time is:<b><span jwcid="insertDate">Jan 1 2001 2:13 PM</span></b>

    If, later, the HTML developer needs to edit the file again, s/he can just recognize the jwcid attribute as "special, don't mess with it" and work around it. The page will still preview properly in a WYSIWYG editor. Meanwhile, the Java developer will be fairly confident that changes by the HTML developer won't break things ... there's very little in the HTML template to be broken.

    Now, sure <%= new Date() %> is more succinct, but not very readable to the HTML developer.

    Now, the Tutorial example, being a tutorial, is pretty hokey. If you extrapolate to a real example, say displaying the logged-in user's last activity, it might look more like:

    <component id="insertDate" type="Insert">
        <binding name="value" property-path="user.lastActivity"/>
      </component>

    But you're equivalent JSP starts getting more complex.

    <jsp:useBean id="user" type="org.example.User" scope="session"/>

    <%= user.getLastActivity() %>

    And that's plastered all over the JSP.

    Fine, now your user is from france, and wants to see the date formatted in a french locale. For Tapestry we define a new binding, for a format, and a new accessor method to provide the correct localized DateFormat instance.

    In the JSP world, we'd have to probably create a whole new JSP tag for this purpose, and figure out a way to identify the user's (not the server's) locale and find the right DateFormat. Possibly this would require changing the action to do this lookup before rendering, and store the result into the request (this is the kind of setup that makes creating components tougher).

    Debugging:

    Debugging Tapestry applications is easy, because all the interesting stuff occurs inside listener methods and accessor methods.

    You don't need a debugger for the specifications per-se. You can use the Inspector to dynamically investigate the cosntruction of your application at runtime, which is essentially what you are asking for (check it out, it's pretty impressive).

    In addition, Tapestry has best-of-breed exception reporting; when an unexpected exception occurs you get a very, very complex exception report. It unwinds nested exceptions, shows you the name, message and *properties* of each exception in the nested exception stack, the stack trace at the deepest level, and tons of other information about the Servlet API objects ... even a dump of the JVM system properties.

    I've had developers say that they would switch to Tapestry just for the exception handling/reporting.


    ... Hangman example ...

    I think that's an excellent division of responsibilities, and agile to boot.

    The Controller (the Java class) provides the three possible values, and tells the View (the component) what values to use (as public static fields) and the property to assign.

    The HTML template contains none of this, just ordinary <input type=radio> tags, with the jwcid attribute.

    If we change our minds about how many guesses are in an EASY game, we change it *once* in the Java class; no change to the specification or template necessary.

    That's seperation.

    The dependencies are not very complex, and the naming is consistent. Listeners are methods invoked when triggered (by a link click or form submit).

    Yes, you could write a simpler Hangman in JSPs or even as simple servlets (how many enterprise-wide HTML Hangman applications does the world need?). Unlike most frameworks, Tapestry's "sweet spot" isn't in the demo domain, its inside real, active applications.

    I'm running out of steam here!

    The point is, you can do simple things simpler in JSPs. Like any comparison of differnt level languages, the more primitive language looks easier Compare assembly code for incrementing by one with what it takes to do the same thing in Java. Why does it take a 9 MB runtime and dozens of bytecodes to increment a value in Java? I'm a real coder, who know what that Java is doing. Maybe it just says its incrementing, but its really subtracting. Can't risk that ... I'll be coding all my incrementing of integers in assembly, thank you. And coding that payroll application in assembly too, by extension.

    Tapestry addresses real application and devloper concerns, head-on, in a way that Struts and JSPs can't compare to.


  44. Tapestry Vs. Struts[ Go to top ]

    After messing around with it now for a while, I'm seeing some value to Tapestry. I think that Howard, you are mistaken in a couple of issues with Struts, specificall performance and complexity. On my first project, there was a lot of missing docs, and some things I missed until too late in the game (most seriously DispatchAction). However, with the docs getting better, I've found struts to be an excellent system.

    As for performance, I've found struts to be pretty good here. Again, as with most development environments, performace is a developer issue. Bad knowledge of struts, bad knowledge of J2EE etc will make for badly performing apps.

    One of my biggest problems, that Tapestry seems to deal with is the Struts tag libraries. Some of them can be a real pain, and the functionality seems to be inconsistent sometime. It can be very frustrating.

    One thing that Struts seems to have (although I haven't made it through all that much of the docs for Tapestry yet) is a better model for security.

    I have a pet project that I'm working that is a a sort of research tool for remote/distributed databases. It has a management interface and a research interface. I have already implemented the management interface using Struts.

    I'm gonna try doing the initial run of the research interface with Tapestry. That sounds like maybe making complexity where we don't need it, but I want to see other developers reactions to both. The back-end developers seem to like the Struts methodology better, and the Graphics people and front-enders seem to prefer the Tapestry approach better. So I'm gonna build some simple interfaces with both, and see what comes out of it.

    -Newt
  45. Tapestry Vs. Struts[ Go to top ]

    Hello Mr. Ship,

    I'm back :). Actually, you have convinced me to try something more complicated with Tapestry, so your effort is not totally in vein. I do have comments as usual, though.

    <quote>
    Where Struts fails is when attempting to create components.
    It's not so bad for output-only components, but once the component has unique behaviors of its own (i.e., contains links or a form) things get tricky ... the component has to have special knowledge of the page that contains it. If you can encode that as a named forward, it's not too terrible (just yet another parameter for the JSP tag), but if the JSP requires any special setup before renderring (i.e., storing relevant values as HttpServletRequest attributes before renderring) then you start to have a real problem.
    </qoute>

    I don't really follow the logic here. My JSPs are incredibly simple and have no relevant code whatsoever -- all they do is present information that is stored in the request area. The request is initially intercepted by a Struts action that simply places the required information into the request area and forwards to the JSP (actually to a tile def, but let's keep it simple). So not only is the page void of code, but the "view" actions that forward to the pages are very simple as well. I don't see a problem with storing data in the request area for the page to use. It is clean and easy to understand.

    <quote>
    Struts documentation may be coming around but it generally doesn't address the more important, but less obvious, issues of dealing with ever increasing application complexity. Successful application grow every more complex and whatever ad-hoc naming and dispatch system your start with eventually becomes a limitation.
    </quote>

    I agree, but point me to documentation that can replace real-world experience for any technology....

    <quote>
    Tapestry bypasses this by having a single naming and dispatch system that handles any level of complexity. This is a byproduct of the component object model, where each component knows its page and containing component ... its possible to build a complete "path" to the component as part of the URL. Even when components are nested a dozen levels deep, the system still works.
    </quote>

    I guess I'll have to take your word, 'cause I don't really know what you're trying to tell me here.

    <quote>
    If you look at the earlier examples on this page, you'll see the Rollover component. Very basic, yet it leverages the Tapestry COM to do a number of useful things:
    1) Discovers containing link component and adjusts its appearence if the link is disabled
    2) Discovers te containing Body component, and uses it to pre-load images
    3) Uses Body to insert necessary JavaScript functions to handle rollovers
    4) Has containing link render necessary JavaScript event handles into <aa> tag

    The end result is clean, flexible HTML, with all JavaScript in a single block (not scattered across the page).

    These same approaches build to allow mega components like the Palette.
    </quote>

    Okay, all stuff I can achieve with tags.

    <quote>
    Because of the way Tapestry organizes server side state, it makes it possible for an application to *discard* no longer needed state (you can "forget a page" and any server side state associated with it). This allows an application to avoid bloating out the HttpSession, which is vital in terms of maintaining scalability.
    </quote>

    I understand the implications of storing big sessions, however, I also don't understand why I need a big framework to handle this for me. My sessions are very small.

    <quote>
    Another area where Tapestry supports complexity is by allowing components to have their own HTML template. JSP tags need to write their HTML in Java code ... a step backwards to servlets. Yes, you could hack something together where the content was assembled using Velocity or something ... but Tapestry naturally handles this kind of things, recursively, with support for components that wrap content (including other components) and naturally integrates everything together.
    </quote>

    Okay, tags do generate HTML from Java code. But so does Tapestry -- Here is the "template" from the OnJava article describing Mega-Components:

    <table jwcid="table">
      <tr>
        <th>Available</th>
        <td class="controls" rowspan=2>
          <aa jwcid="selectButton"><img jwcid="selectImage" alt="[Select]"/></aa>
          <br>
          <aa jwcid="deselectButton"><img jwcid="deselectImage" alt="[Deselect]"/></aa>
        </td>
        <th>Selected</th>
      </tr>
      <tr>
        <td><select jwcid="availableSelect"/></td>
        <td><select jwcid="selectedSelect"/></td>
      </tr>
    </table>

    Note that this looks nothing like the finished product. Why? Because Tapestry is generating replacement HTML code from Java, just like you do from a tag.

    <quote>
    Tapestry is about writing interesting Java code. I never want to write code to convert a query parameter into an Integer again ... with Tapestry I don't have to. Tapestry has built-in detail exception catching and reporting ... more code I don't have to write again.
    </quote>

    Okay, so the exception reporting is very detailed and nicely formatted (suspiciously similar to that of ASP.NET). But this is not a compelling reason for me to switch. I find all Java code interesting :).

    <quote>
    The Java developer would recognize that date was dynamic and convert it into a component.

      time is:<b><span jwcid="insertDate">Jan 1 2001 2:13 PM</span></b>

    If, later, the HTML developer needs to edit the file again, s/he can just recognize the jwcid attribute as "special, don't mess with it" and work around it. The page will still preview properly in a WYSIWYG editor. Meanwhile, the Java developer will be fairly confident that changes by the HTML developer won't break things ... there's very little in the HTML template to be broken.
    </quote>

    Yes, and my point is that the HTML designer also has no control over what (HTML) is actually generated into the "insertDate" area, so there is not a clean separation of responsibilities (the developer decides what is generated into the template). Since tags present the same problem, the two approaches are equivalent (no advantage on the part of Tapestry).

    <quote>
    Now, sure <%= new Date() %> is more succinct, but not very readable to the HTML developer.
    </quote>

    If you know what you're doing, you don't have this crap in your JSPs. Tags only.

    <quote>
    But you're equivalent JSP starts getting more complex.

    <jsp:useBean id="user" type="org.example.User" scope="session"/>

    <%= user.getLastActivity() %>

    And that's plastered all over the JSP.
    </quote>

    Once again, tags vs. code. Try this:

    <bean:write name="user" property="lastActivity"/>

    My JSPs contain no code.

    <quote>
    Fine, now your user is from france, and wants to see the date formatted in a french locale. For Tapestry we define a new binding, for a format, and a new accessor method to provide the correct localized DateFormat instance.

    In the JSP world, we'd have to probably create a whole new JSP tag for this purpose, and figure out a way to identify the user's (not the server's) locale and find the right DateFormat. Possibly this would require changing the action to do this lookup before rendering, and store the result into the request (this is the kind of setup that makes creating components tougher).
    </quote>

    Yes, if I were stuck in a JSP world. I also am using Struts, and the framework takes care of this seamlessly. All I have to do is externalize all of the locale-sensitive data into a message resource bundle. And yes, it works with both browser and server locale. I am already developing a locale-sensitive application and am well aware of these issues. Struts support for this is seamless.

    <quote>
    In addition, Tapestry has best-of-breed exception reporting; when an unexpected exception occurs you get a very, very complex exception report. It unwinds nested exceptions, shows you the name, message and *properties* of each exception in the nested exception stack, the stack trace at the deepest level, and tons of other information about the Servlet API objects ... even a dump of the JVM system properties.
    </quote>

    Yes, I agree. This is nice work.

    <quote>
    The point is, you can do simple things simpler in JSPs. Like any comparison of differnt level languages, the more primitive language looks easier Compare assembly code for incrementing by one with what it takes to do the same thing in Java. Why does it take a 9 MB runtime and dozens of bytecodes to increment a value in Java? I'm a real coder, who know what that Java is doing. Maybe it just says its incrementing, but its really subtracting. Can't risk that ... I'll be coding all my incrementing of integers in assembly, thank you. And coding that payroll application in assembly too, by extension.
    </quote>

    Again, I am not using JSPs alone. I am using JSPs + Struts/Tiles + tags. Works great for me.
  46. Tapestry Vs. Struts[ Go to top ]

    <quote from Howard>
    The Java developer would recognize that date was dynamic and convert it into a component.

      time is:<b><span jwcid="insertDate">Jan 1 2001 2:13 PM</span></b>

    If, later, the HTML developer needs to edit the file again, s/he can just recognize the jwcid attribute as "special, don't mess with it" and work around it. The page will still preview properly in a WYSIWYG editor. Meanwhile, the Java developer will be fairly confident that changes by the HTML developer won't break things ... there's very little in the HTML template to be broken.
    </quote>

    <quote from Phillip>
    Yes, and my point is that the HTML designer also has no control over what (HTML) is actually generated into the "insertDate" area, so there is not a clean separation of responsibilities (the developer decides what is generated into the template). Since tags present the same problem, the two approaches are equivalent (no advantage on the part of Tapestry).
    </quote>

    Not quite true. Dummy values, which are later removed when Tapestry is run, can be inserted that will show up in the HTML designer's editor, such as Dreamweaver. This allows quite sophisticated "mocks" to be created, used for use case analysis, marketing, etc., that can be viewed statically w/o running Tapestry at all. HTML designers and java developers can continue to work without stepping on each other's toes. This is a major advantage to Tapestry.

  47. Tapestry Vs. Struts[ Go to top ]

    <quote>
    Not quite true. Dummy values, which are later removed when Tapestry is run, can be inserted that will show up in the HTML designer's editor, such as Dreamweaver. This allows quite sophisticated "mocks" to be created, used for use case analysis, marketing, etc., that can be viewed statically w/o running Tapestry at all. HTML designers and java developers can continue to work without stepping on each other's toes. This is a major advantage to Tapestry.
    </quote>

    Ultimately, however, the generated HTML may look significantly different than what is viewed in the designer. As an example, again I point you to the "Mega Components" example published at OnJava.com -- code snippet in my previous post. Load this HTML into your favorite editing tool, or even a browser. It looks nothing like the finished product. Sure, I can style all of the elements around it, but I can already do that without Tapestry. I also have not (yet) found a way to specify, for example, CSS attributes for the components generated from the Tapestry framework. It is possible that I have simply missed it, but if not, this is a pretty big disadvantage for me, and something that is easily done with tags.
  48. Tapestry Vs. Struts[ Go to top ]

    <quote>
    Ultimately, however, the generated HTML may look significantly different than what is viewed in the designer. As an example, again I point you to the "Mega Components" example published at OnJava.com -- code snippet in my previous post. Load this HTML into your favorite editing tool, or even a browser. It looks nothing like the finished product. Sure, I can style all of the elements around it, but I can already do that without Tapestry. I also have not (yet) found a way to specify, for example, CSS attributes for the components generated from the Tapestry framework. It is possible that I have simply missed it, but if not, this is a pretty big disadvantage for me, and something that is easily done with tags.
    </quote>

    The operative word is may as in the generated HTML may look different in viewd in the designer or browser. Not necessarily, however, in Tapestry. For example, in my last project we had a talented graphics/html designer who was a wiz in Dreamweaver. She made numerous "mocks", some of over 100 pages. Developers could use those mocks as a starting template, but as soon as you started doing jsp, struts or what have you, it diverged from the original. My point is that with Tapestry we could have continued to use these mock html pages as templates and she could continue to use them for demo, use case analysis, marketing, etc.

    There is a workbench.css file in /lib/tutorial.war
  49. Tapestry Vs. Struts[ Go to top ]

    From the FAQ (inside the Developer's Guide):

    Q: How do I specify the CSS class used for a Tapestry component?
     
    A: Most Tapestry components support informal parameters. These are used to specify additional HTML attributes for the tag generated by the component.

    You can set the value for such informal parameters in the component specification, or in the HTML template.
     
    .....

    About complex Mockups:

    I just create an <img> tag, stretched to approximate size and shape of the component, to hold space for it visually.

    I.e.,

      <img jwcid="palette" src="images/mockup.gif" width=200 height=150/>

  50. Tapestry Vs. Struts[ Go to top ]

    Okay, I think you guys are getting tired of me, so I am going away :). I will have a closer look at Tapestry and see if it buys me anything versus Struts. At least I know I can count on a response if I have questions or issues.

    Thanks for all of your input, and thanks for contributing to the open-source community. It is great to have options like Tapestry from which to choose and I know how much work an open-source project can take (I host my own on sf.net -- JNI++ -- http://jnipp.sf.net). My goal is not to belittle the work you've done; rather it is to evaluate its suitability for my particular needs. I just have one more question for Howard -- you mentioned in an earlier post that you use Struts on a daily basis. Why aren't you using Tapestry on those projects?
  51. Tapestry Vs. Struts[ Go to top ]

    Last October, I switched jobs, leaving my consulting position at Primix (which soon went on to consulting-company heaven) to join WebCT, a software product company. When I joined, WebCT was already well into rewriting their existing Perl/C++ application into a J2EE application.

    It didn't make sense for them to switch midstream; schedules were too aggresive and too much code in Struts already. Well, I think it would have been worth switching then but the agreement I made when hired was to work hard and discuss switching to Tapestry after the 1.0 release.

    The 1.0 release just occured and we are in discussions to see how best to leverage Tapestry.

    Along the way, I become much more knowledgable about Struts, answering my own question "Is Tapestry worth it?".
    A big "Yes", BTW.

    Going forward, the most likely path will be to (re-)code portions of the application using Tapestry. A key focus in the 2.3 release will probably be JSP interoperation; I may include JSP taglib for allowing JSPs to reference Tapestry pages in some way.
  52. Tapestry Vs. Struts[ Go to top ]

    I have been following this debate with great interest, and I must say that it is refreshing to see such courteous conversation from the author. Thank you Mr. Ship, for not losing it and getting all defensive and aggresive, and for taking the time to explain the rationale behind Tapestry.

    Sat Nashikkar,
    JP Mobile
  53. Tapestry Vs. Struts[ Go to top ]


    For what it's worth - I've used it all for web development: servlets, asp, jsp, struts, model 1, model 2, freemarker, webmacro, xslt and tag libraries. whew....

    Tapestry was the last thing i tried - to my own regret. Before tapestry - web development was nothing short of agonizing - you threw all of that object oriented skill you've been honing for 10 years out of the window. which is not so bad for developers who use procedural languages (they don't know what they're missing anyway), but it's hell for oo programmers.

    with tapestry - everything's an object again - you can easily create complex reusable components (and by that i mean a component that accepts user interaction, and you can put one or ten on a page, or one in another, or several on multiple pages, without changing any code) - something i have not been able to do with any other framework. the page component itself has plenty of hooks to which you can add extra base functionality like security by subclassing. for the person who was asking about security - i have several pages subclassed - a base page, a user base page, and an administrator base page. they all handle security checks transparently. write it once and use it again by subclassing from the appropriate class when you create a new page. and here's another thing - objects retain their own state for each user - there's no need to store state in a session anymore unless it's system wide. page or component specific data stays with the the object - like it's supposed to. whe you create a calendar object for a user, it's their calendar, nobody else's.

    i really believe i'm doing things with tapestry that would be almost impossible (or at the very least multiple times harder) using any of the mainstream frameworks.

    when jsf comes out, i'll take a look at it. but as for now, i'll use tapestry because it's the only thing that's remotely acceptable to do what i want. i still absolutely hate web development with a passion, but tapestry makes it almost bearable.

    and if something comes out to supercede it in the future (as i'm sure it will), so what? that vast mangled mess of asp/jsp spagetti out there is the greatest number of man-years of unrefactorable junk ever amassed in the history of software. you'll never reuse that again in any case. at the most, you'll reuse your business logic, which should be locked up in tidy class files somewhere - regardless of which framework you use.
  54. Tapestry Vs. Struts[ Go to top ]

    <qoute>Yes, if I were stuck in a JSP world. I also am using Struts, and the framework takes care of this seamlessly. All I have to do is externalize all of the locale-sensitive data into a message resource bundle. And yes, it works with both browser and server locale. I am already developing a locale-sensitive application and am well aware of these issues. Struts support for this is seamless.</quote>

    With Struts, how do you allow the user to enter 1,000,00.99 for US and 1.000.000,99 for Germany and correctly parse this information into a float in the ActionForm?
  55. Tapestry vs. JSP[ Go to top ]

    IMO, Tapestry is a nice framework, with a sound design and good documentation.

    However, I have a hard time choosing it to develop Java-based web applications, and the reason for that is that Tapestry is not built on top of JSP. Yes, I know how horrible using plain JSP is (I have been there), and I could never recommend it.

    I would prefer a web app framework built on top of JSP, rather than just on top of servlets, or worse, not even making use of servlets. Some of my reasons for that:
    1) JSP is an industry standard.
    2) JSP is evolving (just look at JSP 1.2, JSTL, and the upcoming JSP 2.0 and JavaServer Faces specs).
    3) There are tons of books and articles on JSP.
    4) All major IDEs support JSP (have a look at the early access version of IntelliJ IDEA 3.0).

    The real problem with JSP today, as I see it, is that there is no popular web app framework that takes full advantage of its potential (I don't think Struts does that, IMHO).
    If such frameworks do show up in the next two years, I wonder what is going to happen to frameworks such as Tapestry. Will it really be cost effective to continue using them? Will there be wide support for them, in the form of books, best practices, IDE plug-ins, mind share, etc.?

    Just my $0.02 ;-)
  56. Ok, so you are using Sun's MVC2 model to develop JSPs.

    Then you get disciplined and remove Java from your JSPs, just using JSP tags and directives.

    Now you are at the center of a debate that has run for over two years: what is the usefulness of Java ServerPages if you don't embed Java in them? We know that the more Java we put in, the hard to use and extend the page will be, but do we really need JSPs (what with all the source code generation and compiling) if we don't put Java in the page?

    That is the premise of WebMacro and Velocity, that a simpler syntax makes sense.

    See http://www.servlets.com/soapbox/problems-jsp.html

    Tapestry takes this a lot further.

    When you are writing using JSPs or even Velocity you have one file with two different languages in it. One language is HTML, the other is the directives for the scripting language. In fact, for JSPs, there are *two* directives with different syntax, the <% ... %> directives, and JSP tags from tag libraries (which have a more XML style to them). Get a fourth language, Java, if you write any Java scriptlets.

    Tapestry is just *one* language per file. The HTML template contains *just* HTML. The instrumentation doesn't take the form of scripting, but merely the addition of marker attributes to some tags.

    The specifiation file is pure, validated XML.

    The Java code is pure Java.



    Now, point by point:

    > 1) JSP is an industry standard.

    Sun is a single company, not an industry; it has forced upon us a standard that is, in fact, merely a clone (now patched and extended) of Microsoft technology.


    > 2) JSP is evolving (just look at JSP 1.2, JSTL, and the upcoming JSP 2.0 and JavaServer Faces specs).

    I'm quite eager to see the JSF spec, if it ever is made public. Just remember that Sun is a many-faced beast. Small teams of Sun engineers can create wonderful things, such as Java. But as a company, Sun frequently does a poor job on important technologies, constantly playing catch-up to Microsoft. Look how long it took them to provide a real XML toolkit, for example.


    > 3) There are tons of books and articles on JSP.

    And they pretty much say the same thing. JSPs have been around for over four years, largely unchanged for that time period and yet people are *still* struggling to figure out how to use them properly.

    > 4) All major IDEs support JSP (have a look at the early access version of IntelliJ IDEA 3.0).

    IDE support for JSP will always be awkward because of the multiple-languages issue. What's the point of supporting code completion in a JSP when code doesn't belong in the JSP? What people want is to be able to have good WYSIWYG preview of their pages, something Tapestry provides (using existing tools). People also want to be able to have thier web developers and Java developers work together ... Tapestry promotes that as well. JSPs do not support this, because the process of converting HTML pages into usable templates (as JSP files) is destructive and one-way.
  57. You make a few valid points, but most of them are simply not true. I am going to list all points you made, in the order they appeared:

    1. With JSP 1.2, you don't need to "get disciplined" in order to avoid Java code in the JSPs. Just enforce the inclusion of one taglib in each JSP; this taglib specifies a taglib validator that generates translation errors for any scriptlets in the page (JSTL 1.0 has such a validator.)

    2. The usefulness of JavaServer Pages, when properly used, is that it allows the use of a server-side declarative language (in XML syntax) in otherwise "dumb" markup pages, as a complement, not as a replacement for the original (HTML, WML, XHTML, XML, etc.) markup. We don't need, but can use JSP for that. The fact that JSPs get translated to Java code and then compiled is only an implementation choice. It could be interpreted, as MS ASP was (ASP.NET pages, however, do get translated to C# or VB.NET code, and compiled.)

    3. A consequence of itens 1 and 2 above is that there would only be TWO languages, both declarative, in any JSP page (well, perhaps more, but no scriplets). You may disagree, but I (and apparently, the W3C - see An XHTML + MathML + SVG Profile) think that using multiple declarative languages in one web page is really a great idea, and should become more common in the future.

    4. It is the JCP that now controls Java, not Sun. Sun is still the main contributor, but by no means the only one. Have a look at JSR 152 - JSP 2.0 and decide for yourself.

    5. JSF should enter public review this summer, and I am also eager to read it. I expect it to be similar to ASP.NET's WebControls, which is indeed sad, not because of "playing catch-up to MS", but because it is a poor programming model for web apps, IMO. I am not saying we should only use what comes from the JCP (or Sun), but we should build on the good pieces they put out, such as JSP 1.2, JSTL, and the future JSP 2.0 (but maybe not JSF).

    6. Yes, most, if not all, current JSP books show and sometimes even recommend, the bad aspects of JSP. But at least there are plenty of books, and new editions come out all the time. It's not their fault if current JSP frameworks are lacking in quality.

    7. The quality of IDE support for JSP depends only on the IDE itself. I have been testing the EAP version of IntelliJ IDEA 3.0 - see IntelliJ Early Access Program - and I must say, it never ceases to amaze me. With JSP taglib code completion (not only Java code completion in JSPs) and immediate highlight of wrong tag names/attributes, it is really easy to edit JSPs containing HTML and one or more taglibs. It's not awkward at all.

    8. Yes, Java developers and Web designers should be able to work together effectively. However, consider the nature of a typical web application, designed for business tasks, as opposed to a typical web site, designed for browsing. In the past, who has implemented the GUI for business apps? I mean, is it really desirable to have a web designer, who is more concerned with eye-catching pages and graphics, to be the only author of a web page? I think such designers should be trained on the server-side declarative language as well (but not on Java), or at least accept certain constraints on what they can put in a web page intended to a task-oriented audience.

    9. The conversion of an HTML page to a JSP page is not necessarily destructive (that's one reason I don't like Struts). That depends on the taglibs used on the page. Note that recent HTML tools, such as Dreamweaver MX, support the use of JSP tags mixed with HTML. Also, note that web browsers (like IE), simply ignore extraneous markup. Therefore, as long as the original markup is not removed or replaced, the page will still be viewable in the browser. The initial instrumentation of an HTML page could be easily automated by a tool, which could also easily remove all non-HTML tags, if necessary (which actually it wouldn't be).

    Ok, now I must confess that I am actually working on a JSP 1.2-based framework, that already does all of the above, plus more. It's not yet ready for SourceForge, but I hope it will be in the coming weeks or months.

    Cheers,

       Rogerio
  58. http://wwws.sun.com/software/download/developer/5102.html

    It's a freely available framework that adresses same issues as Tapestry but seems to be more standard-conformant.

    Does any have experience in JATO ?