JPetStore: A Pet Store from the Open Source Community

Home

News: JPetStore: A Pet Store from the Open Source Community

  1. JPetStore is a completely rewritten Pet Store application based on Sun's original J2EE Pet Store. The primary difference is that JPetStore uses a design competetive and comparable to the Microsoft .Net Pet Shop --but without its shortcomings. JPetStore is vendor independent and based completely on open source freeware (Struts and others).

    Read the whole story at the iBATIS JPetStore website.

    * NO stored procedures
    * NO generated code
    * NO HTML in the database
    * Model-View-Controller based presentation layer
    * Based on open source freeware
    * Line count differentiated only by coding conventions

    What do you think?

    Threaded Messages (90)

  2. Wheres the online demo and performance benchmarks?

  3. I can prepare an online demo, that's no problem.

    As for performance benchmarks, as the white paper explains, I was unable to conduct them in a manner consistent with the .Net Pet Shop. Unfortunately I don't have 2 Compaq Proliant servers sitting around the house (1 x Dual Xeon + 1 x Quad Xeon).

    I have access to loads of gigantic Sun hardware and a number of smaller x86 boxes, but nothing that is close to what Microsoft used. I also don't have access to the load testing software (expensive).

    If you or anyone else can help, I'd be happy to benchmark it and post the results.

    Cheers,

    Clinton
  4. Unfortunately I can't help there.

    Have you tested jpetstore against sun's version? Perhaps use jMeter to test jpetstore and sun's petstore in your current environment?
  5. <snip>
    As for performance benchmarks, as the white paper explains, I was unable to conduct them in a manner consistent with the .Net Pet Shop. Unfortunately I don't have 2 Compaq Proliant servers sitting around the house (1 x Dual Xeon + 1 x Quad Xeon).
    </snip>

    Would it be possible to run the .NET petshop on your hardware configuration, instead of running your petshop on Microsofts hardware configuration?

    --
    jonmartin.solaas@mail.link.no
  6. With regard to load testing software, a free, Free alternative is "The Grinder".

    http://grinder.sf.net

    - Phil
  7. Hi,

    I'm new to J2ee arena, could you kindly provide the steps to assembling and deploying the JPetstore to run on an J2ee application server (for example: Bea, Sun, JBoss...) and using the Oracle db. I have the App Server & the Db setup.

    Thanks in Advance,
    J2ee rookie
    dc_truong@yahoo.com
  8. Hi David,

    Here are some simple deployment instructions....

    DATABASE: If you are using PostgreSQL, Oracle or PointBase, simply run the provided DDL and data load SQL against the database.

    BEA WEBLOGIC 6.1sp3 or 7.0

    1) Unzip jpetstore.war into <weblogic>/config/<mydomain>/applications/jpetstore/
    2) Configure your database in <jpetstore>/WEB-INF/classes/properties/SimpleDataSource.properties
    3) In WL Console (tree) navigate to <mydomain> | Web Applications | Deployments | Web Applications (click)
    4) Choose "Configure a New Web Application"
    5) Enter full path to the web application (where jpetstore.war was unzipped as above)
    6) Click Apply
    7) Select your deployment target(s) and apply

    TOMCAT 4.04

    1) Unzip jpetstore.war into <tomcat>/webapps/jpetstore/
    2) Configure your database in <jpetstore>/WEB-INF/classes/properties/SimpleDataSource.properties
    3) Start Tomcat

    Let me know if you have any questions.

    Cheers,

    Clinton
  9. Hi all,

    As requested, an online demo has been set up.

    http://www.ibatis.com/jpetstore/jpetstore-online.html

    Cheers,

    Clinton
  10. Great effort!

    The response is quite fast for the hardware configuration. I wonder whether .NET version of PetStore can run on the same hardware.


    Cheers
    K. Sivakumar
  11. Hm. Interesting. We've (my company) decided to develop two web applications using only java web technology and a good persistency layer and thus skipping all the EJB stuff. Our reason was that JSP offers good scalability and the persistency layer takes care of distributed caching problems and as a result I do not have to worry about the EJB hassle: just a nice MVC logic on top of a clean BM based on a good persistency layer.

    Now, this works great, but I always was asking myself "shouldn't we have used EJB"? This kinda confirms that our decision wasn't that bad.

    As I said: interesting.

    Tom
  12. Very Impressive response for the kind of hardware used.
  13. Written using Struts, no EJB. Interesting.
  14. I also noted the non use of EJB most specifically entity beans. Does it make sense to use DAO for this kind of work. I am hearing more buzz about DAO and just wondering where it fits in.
  15. Hi Jim,

    DAO is a wonderful pattern with or without EJBs. The DAO implementation used by JPetStore is little more than an Abstract Factory implementation tweaked for a persistence layer.

    The flexibility can be seen in the DaoFactory.properties file where by simply manipulating a single property, data caching can be enabled or disabled. It would be just as easy to plug in a totally different persistence mechanism (e.g. TopLink).

    Normally I separate the DAOs for different business objects, but there were so few BOs in JPetStore that it wouldn't make sense to split a couple hundred lines of code into many separate classes.

    Cheers,

    Clinton
  16. I had a quick look at the src of the app - it looks like a web centric web application.My question is can the j2ee's transaction , scalability bla bala... be guaranteed and kept without using ejbs? I am using Sun Petstore1.3.1 as guideline in my application and could not see much that can be reduced to .Net like petstore without losing the many aspects of j2ee promises.
    Faisal
  17. <quote>
    I had a quick look at the src of the app - it looks like a web centric web application.My question is can the j2ee's transaction , scalability bla bala... be guaranteed and kept without using ejbs? I am using Sun Petstore1.3.1 as guideline in my application and could not see much that can be reduced to .Net like petstore without losing the many aspects of j2ee promises.
    Faisal
    </quote>
    Sun's Petstore is a demonstration of how all possible J2EE technologies can be used in a single application. Using Petstore as a reference to find out how a particular J2EE technology can be used is good ,but as a guideline to design your app is bad.
    I would say that you need to evaluate your needs as far as transactions, scalability, failover, load balancing and all the fancy stuff that ejb's supposedly promise.
    You can also acheive load balancing with your web server or at a hardware level using routers.
    Similarly you don't need ejb's to ensure transactions. Any decent OR tool is fine, and if your database needs are fairly simple (few tables) you can stick to SQL and JDBC.


  18. If one moves business logic from Struts' Action classes in to separate Beans then adding SLSB facade can be done easy (when and if necessary).

    For persistance I would consider OJB (future apache jakarta project). Performance may suffer a bit but maintainability will be better, plus OJB will provide JDO compliant API in the future.

    The author (Clinton Begin) deserves a lot of credit for putting this stuff together and sharing it with the Java community. The source contains a PDF that describes his approach, make sure you take a look as it definitely contains more substance than an 'opinion' published by some 'senior Java architect'.

    I'd be interested to see some benchmarks with Linix/Tomcat/PostgreSQL config. I'd expect you can easily scale to 2000 users on more or less decent hardware but it'd be interesting to see specifics. Thanks

    -- Igor


  19. This is excellent!

    What I would like to see is a performance benchmark comparing JPetStore and PostgreSQL on Linux to the .net PetShop and MSSQL under XP on the same hardware.

  20. Great!!!

    you can run it by this steps:

    1. drop the war file that came with it in webapps of resin2 (free download from caucho.com)
    2. change SimpleDataSource.properties, to point it in your db
    3. run 2 ddl scripts to your target db.
    4. fire your browser, and load the application.

    and there you go!
  21. I have just checked out the site and given the ridiculously low hardware being used, I must say that this stuff is too cool.

    I really wonder where that 'senior java architect' (one silly Jonathan Gibbons) who has ordered us to move to .NET will make of all this.

    Well done Clinton !
  22. Give the guy a break, he said no such thing. He said future projects will be more likely to use .NET because of marketing and business factors. You lot jumped down his throat and assumed he was talking technical merit.
  23. Getting some errors when trying to sign in or clicking on the cart icon...

  24. And as Murphy would have it, on the first day of deployment..... :-)

    I've posted a complete description and a workaround for the bug. It was totally an error on the part of the programmer (who Me?). :-)

    Thanks Dat.

    Cheers,

    Clinton
  25. Hi all,

    The bug discovered this morning has been fixed.

    Cheers,

    Clinton
  26. Hi,

    I think someone above asked me to make a comment, so here goes. This is long, and if you didn&#8217;t like my paper then don&#8217;t bother reading it.

    The petshop is a small project. Both Java and .Net examples have been produced and compared using number of code lines and speed of operation. The current trend in software is to use application servers, code generators and standard libraries for much of a project's work. Comparisons of lines of code are pretty dubious, which is why the Java community laughed at Microsoft&#8217;s marketing attempt. This rewrite is very useful as it proves how irrelevant Microsoft&#8217;s claims are. A different thread has already mentioned at great length the ridiculous nature of Microsoft&#8217;s performance claims, and the irrelevance within the comparison.

    I think what is great is that we have a well written Java web site. The author rightly discarded much of the J2EE spec and &#8216;made up&#8217; his own solution. I mean this as a complement, replace &#8216;made up&#8217; with &#8216;carefully designed&#8217;, he selected a solution and wrote the bits that needed writing, and used open source for the rest. This is hopefully how every software project does things. I.e. appropriate tech, with reuse where possible and useful.

    I also note people are amazed by the performance of the live site used as the demo system. I had a 5 hour Java batch process running on wintel late last year. Upgrading the PC reduced this to about 42 minutes duration &#8211; and that was with about 5 meg of data being emailed and FTP&#8217;ed, i.e. there was an I/O component. I think this shows that PC platforms are able to handle many server type functions already, and that over the next few years the increase in performance will astound us all &#8211; i.e. what it actually means for our software performance.

    How to measure .NET V&#8217;s Java usefully? Some folks use lines of code but code generators mess up that metric, as do third party libraries and even in-house libraries. Some use speed on the same hardware. But that is a ridiculous comparison as new hardware costs far less than highly skilled development teams. So speed is not the measure.

    Maybe we should use scalability? What happens if you take the same system and ramp it up to 10000 concurrent users? Again, a silly comparison. Create a web farm, and use load-balancing hardware to preserve sessions to the same servers, if you want session fail-over then persist or duplicate session data. Again, hardware is relatively cheap. What about maintenance? Maintaining a large web farm is costly compared to a large server. True, but upgrading a large server is costly compared to upgrading a web farm. You can argue both ways.

    Back to scalability, we still have a bottleneck in the database box. Microsoft says use SQLServer, and we all say use Oracle if you have the money. Let&#8217;s face it, any big corporation will select Oracle over SQLServer if they have the skills and the budget. Does this effect the choice of .Net V&#8217;s Java, not at all? Does it effect the choice of .Net V&#8217;s Unix? Not at all. We are already at the web farm stage, separating the web servers from the db server, so its network based anyway. BUT, with EJB I hear you cry, we have in memory caching. Frankly I don&#8217;t care. Database caching has 20 years of evolution behind it, and I have still to hear how EJB works with a system having collaborating data center&#8217;s distributed in Hong Kong and London and New York &#8211; i.e. running the same system with database level replication. So scalability is a tricky one to measure as well. There are solutions in both .Net and Java, but basically we leave it to the database.

    [Aside: why haven&#8217;t I mentioned MySQL &#8211; it scales, it&#8217;s free, it has transactions and is proven. Because big finance corporations do not use it.]

    Cost! Who can argue with cost? I certainly can&#8217;t &#8211; well actually I can. Linux is near enough free, as are Jboss and the JDK&#8217;s and JVM and IDE&#8217;s. .Net costs you 18K per CPU per SQLServer (ish), 2K for the OS, and 1K each for dev licenses of visual studio (well 600 to 1500). But for scalability we have already said we are using Oracle on a Unix server! Crickey, that is expensive. So say this costs 100K, with another 60K for failover &#8211; h/w and s/w(I&#8217;m guessing as its about 3 years since I was involved in Oracle licenses on Solaris platforms). So the project base cost is 160K, with another 20K for web farm hardware (PC based), and then there is network bandwidth (say 20K), and we probably want to host it (can&#8217;t remember costs for that). Do we still care about how much the .Net dev licenses cost? Do we still care how much Microsoft operating systems cost?

    OK, cost is not an issue if we are worrying about scalability and can buy Oracle. If you can&#8217;t afford Oracle then I agree linux/mysql/postgres etc are a winner &#8211; but they couldn&#8217;t afford to employ many techies if they can&#8217;t afford Oracle. So lets drop scalability and move to smaller projects. Say the petstore.

    I have impoverished clients, who want a simple web server. Linux, Tomcat, MySQL &#8211; good. Or for cheaper staff, Linux, perl/php, MySQL. Yikes I&#8217;ve just scrubbed Java. Let&#8217;s say my staff know Java. OK, we have a clear case where JAVA HAS WON!

    Now let&#8217;s say I want to have clients who can pay me a living wage. Say that&#8217;s 50k per consultant per year. Say the project takes 3 staff at this level, so the client is paying 150K just on staff for a 3 man year project (and these are very cheap techies). How important is the 34K setup for Microsoft server (including hardware)? Depends on the client. It does not depend on the technology.

    So to summarize: Good job, let&#8217;s hope that Microsoft shuts up about the bleedin pet store. Does it prove Java is better? No, it proves Java is just as appropriate, especially if you ditch EJB and don&#8217;t worry about application servers.

    I have not touched on vendor lockin, because I agree 100% that it is the biggest worry for any project. But I look at Microsoft Office and I don&#8217;t see users really worrying very much. And every techie I work with wishes that Netscape would simply die off so that they can code for IE and not worry about being cross platform. It&#8217;s a strange old world.

    Jonathan
  27. Jonathan,
    Awesome.. Wow.. Perfect blend of practicality( price,development effort ) & theory ( technology etc )

    I enjoyed it..I feel the same.

    BTW
    >>Does it prove Java is better? No, it proves Java is just as appropriate, especially if you ditch EJB and don&#8217;t worry about application servers.

    I really can't agree with this.
    Yes EJB is not for every application. But that doesn't mean that we should ditch that..

    Except this rest all were.. good Keep it up.
    ~Murali Varadarajan
  28. A couple of proprietary JAR files such as IBATIS.JAR without source code make it difficult to learn from this implementation of PetStore. Why not provide us with all the source code and treat it like a true open source solution.
  29. I'd bet the jars you refer to are the common iBATIS jars listed in binary and source form on his site. Therefore, yes, it is a truely open source solution.

    An another note, I too am interested in its performance. I wonder how the use of a project like OSCache would compare to cached versions of the .NET and J2EE petstore. Using OSCache in my current project has done wonders.

    Don
  30. What´s OSCache? It´s a persistence layer? Is it comparable to Oracle´s BC4J?
  31. OSCache, found at http://www.opensymphony.com/oscache/, is, as I use it, an output caching system. It is probably most similiar to JCACHE and JCS (http://jakarta.apache.org/turbine/jcs/) in that they are allow for disk and memory caching, however, OSCache is the only cache I have found for output caching - whole and partial pages pages.

    For example, if you have a section of your page like a nav bar generated dynamically, you add <cache:cache key="navbar" /> around it and the output generated by all the content in that tag will be cached. It allows you, like ASP.NET does, the ability to cache portions of your pages that change infrequently. In addition to portions, you can use its servlet filter to cache whole pages, very useful if you have dynamically generated binary content like pictures and graphs.

    Don
  32. Andre: "What´s OSCache? It´s a persistence layer? Is it comparable to Oracle´s BC4J?"

    Yes. See http://sourceforge.net/projects/opensymphony/. For more information, look at the Oracle JCP submission (called "JCache", see http://www.jcp.org/jsr/detail/107.jsp), which is also implemented (preliminary spec) by SpiritSoft (http://www.spiritsoft.com). For caching in a cluster, see Tangosol Coherence (http://www.tangosol.com/coherence.jsp).

    Peace,

    Cameron Purdy
    Tangosol, Inc.
  33. For cache we've used also this:
    www.servletsuite.com/servlets/cacheflt.htm for page level cache and
    www.servletsuite.com/servlets/cachetag.htm for component-level

    Actually you may find DB taglib with cache support
    on www.servletsuite.com/servlets/cachetag.htm
  34. Eugene,

    DB taglib with cache (hello ColdFusion :) is here
    www.servletsuite.com/servlets/dbtag.htm
  35. I think its there.. check out the menu on the left,
    under 'Common' you can download the jar, with source.

    TK.
  36. Hi Ted,

    You can find all the source for the iBATIS common libraries at the following link. Sorry it was hard to find. Rest assured, you have access to all of the source code.

    http://www.ibatis.com/common/common.html

    Cheers, :-)

    Clinton
  37. That was fast ...impressive! All the credit man!. Sun 's Perstore team should see this and learn how to make things more practical with less complexity though their Petstore id more like a tutorial and how to .
  38. Hi Clinton,

    With regards to your iBATIS Common Library,
    is there any developer guide, example (other than JPetStore), doc, etc? To help kick start with your library.

    Gabriel
    PS: Cool work & well done!!
  39. Gabriel:

    Unfortunately I never expected to release the Common library outside of my own little community (in which the developers are already familiar with it). So I suppose I've been a little slow in writing docs for it. Luckily, all of these very flattering comments are driving me to write up better documentation for both JPetStore and the iBATIS common library.

    I'd really like to get some performance benchmarks though, so I'm kind of torn!

    Thanks for the encouragement!

    PS: For the Oracle driver issue....the way I've solved it (since Tomcat 3.x) was to do as Clifford Cheng said --rename the classesXX.zip to classesXX.jar (in WEB-INF/lib).

    Cheers!

    Clinton
  40. Hi Clinton, Gabriel, Clifford

    I could successfully run the jpetstore using tomcat 3.2.1 but failed to run it using Tomcat 4.0.1.

    I tried using a fresh installation of Tomcat 4.0.1 with JDK1.3.1_02 on Windows NT and only the jpetstore application war

    path set to %JAVA_HOME%\bin;%CATALINA_HOME%\bin
    classes12.jar (not classes.zip) in the Web-inf\lib
    SimpleDataSource.properties set to point to Oracle

    I get the following action/instance error:

    Apache Tomcat/4.0.1 - HTTP Status 500 - No action instance for path /shop/index could be created

    --------------------------------------------------------------------------------

    type Status report

    message No action instance for path /shop/index could be created

    description The server encountered an internal error (No action instance for path /shop/index could be created) that prevented it from fulfilling this request.

    --------------------------------------------------------------------------------

    PrintStackTrace looked like

    2002-07-05 17:04:41 action: Error creating Action
    > instance for path '/shop/index', class name
    >
    'com.ibatis.jpetstore.presentation.action.IndexAction'
    > java.lang.NoClassDefFoundError
    > at java.lang.Class.forName0(Native Method)
    > at java.lang.Class.forName(Class.java:120)
    > at
    >
    org.apache.struts.action.ActionServlet.processActionCreate(ActionServlet.java:1631)
    > at
    >
    org.apache.struts.action.ActionServlet.process(ActionServlet.java:1577)
    > at
    >
    org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:492)
    > at
    >
    javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
    > at
    >
    javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
    > at
    >
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
    > at
    >
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
    > at
    >
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
    > at
    >
    org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
    > at
    >
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
    > at
    >
    org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
    > at
    >
    org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2344)
    > at
    >
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
    > at
    >
    org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:170)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
    > at
    >
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:170)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
    > at
    >
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:462)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
    > at
    >
    org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
    > at
    >
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:163)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
    > at
    >
    org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
    > at
    >
    org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
    > at
    >
    org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor.java:1011)
    > at
    >
    org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.java:1106)
    > at java.lang.Thread.run(Thread.java:484)


    I have been using tomcat 4.0.1 for a struts based application I am developing using Oracle as backend. It works fine. Gabriel has been trying to help me with it.

    Well Clifford you said its a pathing issue - what did you exactly do to solve it. Do I need to set the classpath variable to point to struts.jar? Please assist me to solve this.

    Thanks and regards
    Panchalee

  41. Hi guys,

    I could run the jpetstore.war in tomcat 3.x and tomcat 4.0.4 but it fails to run in tomcat 4.0.1

    Really don't know why? Has anyone tried with tomcat 4.0.1?

    regards
    Panchalee
  42. Panchalee,

    Sorry for being unclear. I didn't actually try the jPetstore myself. Clinton's codes are so clean and well-structured that I simply browsed through them and understood how they work (without EJB it's a typical Struts application). Instead, I tried his library on another project and got that 'No action instance ... could be created' message which later on found out to be a pathing issue (I said in my case). However, when I worked further I realized that every time I got the map sql xml files wrong the same message came back. I haven't got a chance to step through Clinton's library source codes but believe that is something to do with loading the xml's through the DAOMgr in the action objects (again in my case). I would suggest to bring Clinton's library source codes into an IDE and try to step through them. By the way, I used Tomcat 4.0.3 and Oracle 8.1.7.

    Clifford
  43. Hi all,

    Under some app/web servers there may be issues resolving relative paths that are based on a classpath resource. Such a case in JPetStore exists with the SQL Maps. I know that this doesn't work on some web servers, such as iPlanet Web Server (Sun One Web Server) and also WebLogic can have problems if you don't expand the WAR file (I'm not sure about Tomcat 4.0.1).

    There is a workaround that you can try: Simply modify the PetStoreMapDao.properties (WEB-INF/classes/properties/) file to use an absolute path rather than a relative one (there is an example in the properties file that is commented out).

    In the case of JPetStore, SQL Maps are the only thing that require a file path.

    Panchalee: You might be getting a NoClassDefFound exception because the SqlMap and the PetStoreMapDao are static class members that are instantiated during the class loading. If any exception is thrown, the class can't be loaded, hence the exception. In any case, I suppose there is some room for improvement in my handling of fatal errors... :-)

    Cheers,

    --
    Clinton Begin
  44. Clinton,

    I've been trying to append an 'order by' parameter to a select statement in a SQL Map for resorting html tables. Is there a SQL Map attribute for this purpose? In the affirmative, could you give some hints or perhaps a few lines of sample code?

    Thanks.

    Clifford
  45. Hi Clifford,

    A static order by is easy, you can just set it in the mapped statement SQL in the SQL Map XML file. I assume you're looking for a dynamic order by clause though. Unfortunately at this time there is no easy/clean way to do that. However, that would be a next step for the SQL Map API is dynamic query generation (including order by).

    The only workaround I can think of for now is to have a separate mapped statement for each order by. You could reuse the parameter and result maps. This could get really ugly if you have many order by possibilities or if you have multiple order bys. If you only have a few though, it may not be an unreasonable temporary solution.

    I know this is far from elegant. There are a number of possibilities for improvement. I'll just have to decide which is the easiest/cleanest way. Suggestions welcome...

    An example XML map would look like:

        <result-map name="result" class="com.ibatis.jpetstore.domain.Category">
          <property name="categoryId" column="CATID" />
          <property name="name" column="NAME" />
          <property name="image" column="IMAGE" />
          <property name="description" column="DESCN" />
        </result-map>

        <mapped-statement name="getCategoryList" result-map="result">
          select * from CATEGORY
        </mapped-statement>

        <mapped-statement name="getCategoryListOrderByName" result-map="result">
          select * from CATEGORY order by NAME
        </mapped-statement>

        <mapped-statement name="getCategoryListOrderById" result-map="result">
          select * from CATEGORY order by CATID
        </mapped-statement>
      
  46. Clinton,

    Yes, I meant dynamic reordering. Thanks for your efforts anyway.

    Clifford
  47. Great contribution for Java and .NET community!

    Sounds like many people were wondering about No EJB arcitechture. I agree with R V, here is one of the reference about EJB decision making facotors.
    http://www.theserverside.com/resources/articles/Is-EJB-Appropriate/article.html

    Anyway, the intention of the app is the comparison between J2EE and .NET, and it's in JPetStore whitepaper's Conclusion section.

    thanks again, Clinton!
    Tak
  48. Great job Clinton !

  49. You have done a great job by simplifying the J2ee petstore example.

    I was trying to run the jpetstore.war using Tomcat 4.0.1 along with Oracle 8.1.5.

    - I loaded the war file in webapps folder of tomcat.
    - Modified the SimpleDataSource.properties file to point
      to Oracle
    #Oracle
    JDBC.Driver=oracle.jdbc.driver.OracleDriver
    JDBC.ConnectionURL=jdbc:oracle:thin:@localhost:1521:ORCL
    JDBC.Username=new
    JDBC.Password=new

    - created the tables and loaded data successfully by running the scripts available for Oracle

    When I run the application in the browser I get the following error

    Apache Tomcat/4.0.1 - HTTP Status 500 - No action instance for path /shop/index could be created

    --------------------------------------------------------------------------------

    type Status report

    message No action instance for path /shop/index could be created

    description The server encountered an internal error (No action instance for path /shop/index could be created) that prevented it from fulfilling this request.

    --------------------------------------------------------------------------------

    Did I miss out on something? Please help


  50. could be oracle driver issue.

    Try putting your classes12.zip into CATALINA_HOME/common/lib/

    It's work for me :-)


  51. Hi Gabriel,

    Since I am using Oracle as backend in my present web application I have already loaded classes12.jar in the CATALINA_HOME\commom\lib folder of tomcat. I have been able to connect to oracle otherwise.

    Anything else that I might try out.

    thanks
    Panchalee
  52. Hmm.. funny?

    Try email me your printStackTrace and do an offline discussion, before we bored "The J2EE Community" with this issue.

    gabrielchua at yahoo dot com
  53. Well a second thought !

    Have you made some additions in the server.xml in CATALINA_HOME\conf for context path or jdbc resources?

    Which version of tomcat are you using?
  54. I have to say Clinton has done a great job for the Struts community. I have done quite a number of Struts projects but his design has made Struts programming so clean and simple. I experimented his library on a different project and it worked just beautiful. For the Oracle driver, I put it in WEB-INF\lib but failed to load until I renamed the file extension from .zip to .jar. For the action instance problem, it's an action pathing issue in my case. It worked fine after I made the necessary correction.
  55. I've looked at it. good job. I've been hoping for someone to write an "appropriate" Pet Store ever since the .NET PetShop came out -- one that uses the appropriate levels of abstraction instead of the monstrously over-engineered J2EE PetStore.

    Contrary to popular belief, my opinion is that lines-of-code ARE a very important measure when dealing with implementation techniques. The less lines of code, it shows a mixture of thought on the programmer and expressive power in the language & libraries. Since the PetStore *is* so simple, it really doesn't make much sense for the J2EE solution to have so many more lines of code when we know the Java class libraries are pretty much on par to the .NET class libraries, and how C#/Java are also pretty much on par.


  56. I tried to use MySQL as a backend, and added the following lines into the file of SimpleDataSource.properties ==>

    #MySQL
    JDBC.Driver=org.gjt.mm.mysql.Driver
    JDBC.ConnectionURL=jdbc:mysql://localhost/petstore
    JDBC.Username=wang
    JDBC.Password=test

    While I try to enter the petstore, and meet:
    javax.servlet.ServletException: Servlet execution threw an exception
    ...
    root cause
    java.lang.ExceptionInInitializerError
    at com.ibatis.common.dao.jdbc.JdbcDaoTransactionPool.getTransaction(JdbcDaoTransactionPool.java:40)
    Caused by: java.lang.RuntimeException: SimpleDataSource: Error while loading properties. Cause: org.gjt.mm.mysql.Driver
    at com.ibatis.common.jdbc.SimpleDataSource.initialize(SimpleDataSource.java:135)
    at com.ibatis.common.jdbc.SimpleDataSource.(SimpleDataSource.java:91)
    at com.ibatis.common.jdbc.DbConnectionPool.(DbConnectionPool.java:21)
    at com.ibatis.common.jdbc.DbConnectionPool.(DbConnectionPool.java:17)
    ... 39 more

    I am sure the classpath to mySQL JDBC driver is correct. Any help?

    Thanks,
    James X Wang


  57. As far as I know MySQL does not support Transactions.
  58. James:

    I got this error message when the class file of my JDBC driver wasn't available to my web server (tomcat). I solved the problem by dropping the appropriate jar files in tomcat's lib directory. Maybe the same will also solve your problem.

    Good luck!

    Jonathan Rich
  59. James:

    In addition, did you "unjar" the MM.MySQL JDBC driver? It won't work in the JAR format. Also, once unjarred, where did you put the class files?

    There's really only one line of code that could cause the exception that is being reported (from SimpleDataSource):

        Class.forName (jdbcDriver).newInstance();

    Generally the exception you reported would occur when the driver cannot be found (NoClassDefFoundException). Sorry for the vague error message that was reported. I used a Exception.getMessage() instead of Exception.ToString() like I usually do for the "Cause:". I can't wait to start making use of JDK 1.4 exception chaining! :-)

    Cheers,

    Clinton
  60. Bob Farmer: MySQL does now support transactions via InnoDB, but there referential integrity aint there yet (last time I looked, blink and stuff changes).

    Clinton: for result specs and searches etc take a glance at the jasper reports stuff, long time since I looked, but they had some specs.

    Jonathan
  61. No problem with PostgreSQL, while I use mySQL as a backend DB, here is the wrong message:

    ==================
    Error!
    Unhandled Exception: com.ibatis.common.dao.DaoException: Column 'DESCN' not found.
    ===========

    Actually, the column "desc" exsits in the table of Category or Product. Any suggestion?

    Thanks,
    James


  62. Xijun:

    I have verified that JPetStore 1.0.1 (current version) only references the "DESCN" column, it never refers to "DESC". Could it be a typo during the MySQL DDL port?

    Cheers,

    Clinton
  63. James,

    Jonathan was right about InnoDB. However, if you want other features such as unicode support, stored procedures, triggers and views, they are not available with MySQL at least prior to 4.0.1 according to my knowledge. If you want a no cost but full-featured database, why not take a look into Postgresql?

    Clifford
  64. Hi Clifford,

    First of all, excellent work!

    I tried running the application in Win2k, Tomcat 4.0.3, Postgre 7.2.1. The application works but right at the startup I get the following message:

    Starting service Tomcat-Standalone
    Apache Tomcat/4.0.3
    PARSE error at line 1 column 1
    org.xml.sax.SAXParseException: The markup in the document preceding the root ele
    ment must be well-formed.
    Starting service Tomcat-Apache
    Apache Tomcat/4.0.3

    What could be causing the Parsing Error?
    Thanks! :)
  65. Hi Clinton,

    Forget this problem. It was related to Tomcat 4.0.3.
    I upgrade to Tomcat 4.0.4 and it's smooth as silk!
    Thanks for sharing your code to the community.

    More power to you!!! :)
  66. Clinton,

    First of all, thanks for the great work!

    I put the JPetStore to work on W2K with SQL Server 2000 and Tomcat 4.0.4 (because that's what I already had). I adapted the PostgreSQL scripts, and used the JDBC driver for SQL Server that comes with JRun 4, from Macromedia. It should also work with the free JDBC driver from MS. Everything worked well.

    By looking at the code, I noticed that you didn't use the standard authentication and authorization services, as described in the Servlet 2.3 spec, and available in Tomcat 4.
    Coincidentally, the most elaborate part of JPetStore is the management of user signon/signoff, with the orchestration of different Struts actions, otherwise unrelated, in order to redirect the user to the sigon form, and then back to the "new order" form.
    I believe such logic could be entirelly carried out by the web container, provided it implements the security framework specified by Servlet 2.3 spec. I realize that such support is NOT required for Servlet 2.3 web containers, only recommended. But since it IS required for web containers taking part in a J2EE 1.3 environment, I think it can be safely used.

    What do you think?
  67. Hi Rogerio,

    That is a fantastic observation! I hope I can effectively explain my reasoning.

    First and foremost is that the J2EE security services are container managed, which is inherently not portable. For example, how would a JPetStore facilitate the creation of new users in a portable way?

    Second, the JPetStore user/password is not really a security requirement as much as it is a account/profile management requirement. Therefore I place it more in my business domain than in my security domain. A small part which is related to security is ensuring that a user cannot see or use another users account/cart etc. Luckily thanks to session management provided by the Servlet API, this is pretty much free (session spoofing and plain-text passwords can be protected by using a secure protocol e.g. https/ssl).

    Does that make sense? Thoughts welcome...

    Cheers, :-)

    Clinton
  68. Hi All,

    Thanks for your kind suggestion. I will run PostgreSQL instead of mySQL.

    James
  69. Hi Clinton,

    Tomcat has a configurable "JDBCRealm" (in server.xml), which is used to look up user ids and roles in a database. You specify the table and column names for a users table ("Signon" in JPetStore) and a roles table.

    This is, of course, not portable, but it allows the use of existing database tables, is easy to configure, and similar mechanisms should exist in other app servers or web containers. Also, in J2EE 1.3, the JAAS API allows for the plugability of custom login modules. (Unfortunately, Tomcat 4 still doesn't have a "JAASRealm".)

    Apart from the above, which is really only a deployment issue, I don't see any portability problems (am I missing something here?).

    As for your second point, I also thought it wasn't a security requirement at first! But then I realized that it actually is, although in an unusual way for this type of web application. Basically, you would have to add a "UserRoles" table to the JPetStore database, define a "customer" role , and put somes JSPs (NewOrderForm.jsp, etc.) under a security constraint (in web.xml); for the Signon page, it would be necessary to create an empty, but protected, JSP, that just forwards to index.jsp; in code, use the "request.getRemoteUser()" method to obtain the user name. Well, you get the picture :-)

    Cheers,

       Rogerio
  70. How can you include the phrase "superior design" and "no stored procedures" in the same argument?!
    Stored Procedures should be a major component in achieving maximum performance, whether on MS SQL Server or Oracle. Compiled query language such as PL/SQL or T-SQL will ALWAYS yield the highest performance and security... period!
  71. <quote>
    How can you include the phrase "superior design" and "no stored procedures" in the same argument
    </quote>
    Hope you were being sarcastic with your comment.You seem to be mixing up design with performance. While good performance is a desired goal of any design it's not the only one. You also have ease of development, scalability , robustness and maintainability.
    If performance were the only measure we would still be coding in C.

  72. Terry:

    If performance was the only measure of success in software development, JPetStore would have been written to that effect. Unfortunately it is not.

    To demonstrate why the JPetStore design is superior, I would like to call your attention to this fact:

    If I wanted to use stored procedures in JPetStore I would have to write a single Java class to do so (e.g. PetStoreStoredProcDao). The class would be about 300 lines of code (being generous) and to plug it in, I would modify a single line in one properties file (DaoFactory.properties). Most importantly, understand this: I would *NOT* have to change a single line of code elsewhere in the application because JPetStore is layered properly.

    THAT is superior design!

    The same cannot be said of Microsoft's .Net Pet Shop, in which you would be required to heavily refactor at least 7 classes (scouring over 1300 lines of code), which are all mixed up with business objects and hard-coded persistence code. Sounds like a nightmare, no? Imagine the MS design in a real enterprise app.

    Now, should we talk about the HTML in the database now or later? ;-)

    Best regards,

    Clinton

  73. Terry:

    As for security (I forgot to address that), I don't think this is the best place to discuss Microsoft and their security history. However, I did find this link funny:

    http://www.theregister.co.uk/content/4/26086.html

    Point being: stored procs have nothing to do with security.

    Cheers,

    Clinton
  74. Thanks.

    Your persistent framework is simple and elegant. I'll use it my java development.

    BTW I'm looking into MS "Object spaces" persistent framework. Seems like your mechanism has much in common with that.



  75. Hi Clinton,

    I tried your application on Tomcat 4.0.4 and it works like a charm ... great work!

    I have one problem though ... I downloaded the source to your common lib and it seems that it includes a wrong version of Logger (and ProcessQueueThread) - it compiles but I get an unhandled Nullpointer error in method run() each time it tries to log something :(
    On the other hand, if I replace the Logger class with the one from the binary distribution everything works fine.

    I'd really like to see the correct version as this package makes for a great tutorial :)

    gg,
    Marino
  76. Hi Marino,

    I'll be putting up a new version of the common lib sometime in the next week or two. The new version will include an ANT build.xml so that you can easily recompile if you need to. I'll also ensure that I put the right version of the Logger in that distribution.

    Thanks for letting me know.

    Note: For anyone using SQL Maps, the new version will support inline parameter maps and dynamic SQL properties for use with dynamic "order by" clauses or anything else that needs to be dynamic in your mapped statements (group by, select columns etc.)

    Cheers,

    Clinton
  77. I'm still LMAO about this:

    "System Configuration
    Hardware: Pentium 233, 64MB RAM, 2 x 3 GB IDE (but it's energy efficient!)
    Software: Mandrake Linux 7.1, Apache Tomcat 4.0.4, PostgreSQL 7.2, JDK 1.3.1
    Total Cost: about $150 Canadian for the hardware.....so about $13.50 USD. ;-)"

    Could you provide some ECPerf bbop/$ figures for us? ;-)

    Peace,

    Cameron Purdy
    Tangosol, Inc.
  78. Hi Cameron,

    I don't think I'll do that, only because it wouldn't prove anything about JPetShop. It would be more of an exercise in benchmarking Tomcat, JBoss and Linux on a ridiculously minimal hardware configuration. That said, I'd be interested in it too! But I think it would be best tested by the teams that run those projects. Try contacting the Tomcat or JBoss teams.

    PS: I can give you the dollar figure though -- $0. So all other things being equal, the platform would effectively be infinitely valuable. The only way someone could beat that performance/price would be to pay YOU to run their app server software. (And some of them should!) ;-)

    Cheers,

    Clinton
  79. NOTE: It appears as though some messages have disappeared from this thread!!! This is a response to Arun, who posted a question/comment about using a single DAO vs using multiple DAOs.
    -----------------------------------------------------

    Hi Arun,

    Thanks for your very kind support! :-)

    You are correct, and I have always done exactly what you are suggesting in "real" projects. If you have a look at the DaoFactory.properties file, you'll notice that it is set up to allow for multiple DAO implementations. In the case of JPetStore though, it simply did not make sense to break up less than 300 lines of code into 7 (or so) classes (this would be a simple refactoring if needed later).

    Generally what I do is (like you suggest) create a "BaseXXXXDao" (e.g. BaseMapDao) which other DAO implementations can extend. Most of the time it works very well to have a separate DAO class for each business object. And sometimes it makes sense to have multiple DAOs for a BO (e.g. separate reads and writes) or to have a single DAO for multiple BOs (where it simplifies the implementation, like in JPetStore).

    Originally I did start with multiple DAOs in JPetStore. I had a BaseMapDao class, from which more specific implementations were extended. For example: AccountMapDao, CategoryMapDao, ItemMapDao, OrderMapDao etc. I refactored them into a single class because it seemed to simplify the code at the time.

    Excellent observation Arun! Thanks for raising it. I'm thinking of releasing an updated version of JPetStore that will address suggestions like yours.

    Cheers,

    Clinton
  80. Hi Clinton,

    I am looking forward to the new Common Library.
    Thanks for sharing your work to the community ;)
    More Power to IBATIS!!!

    Allan
  81. Clinton,

    Look forward to the new version. By the way, is there a way to define multiple datasources in the properties files (e.g. SimpleDataSource.properties) for connecting to e.g. different schemas on Oracle from the same application?

    Thanks
    Clifford
  82. Clifford:

    No there is not. However, you can instantiate as many SimpleDataSources as you like and pass a Map (properties) to the constructor with whatever configuration you need.

    Cheers,

    Clinton
  83. Viva Clinton!
  84. o-r mapping api[ Go to top ]

    Hi Clinton ,
    We are planning a small new project , I thought of using some kind of o-r mapping .
    Actually I liked your approach to o-r mapping.
    What other open source tools/api you feel are the best in o-r mapping space.
    How do you rate them and why.
    Thanks.
    Arun
  85. o-r mapping api[ Go to top ]


    Arun, please email me directly and I'll try to answer your question as best I can. I fear my answer may be much too long to crowd this thread with.

    Cheers,

    Clinton
  86. o-r mapping api[ Go to top ]

    Hi Clinton,

    Can you please copy me on your reply on this thread?
    My e-mail address is: allanyao at optonline dot net

    Thanks!

    Allan
  87. Clinton has done quite a great job on his conversion from Sun's version. This is a great example of when not to use EJB's if desired, and show very good performance in regards to that decision.

    It is also a great example on using other open source tools to help instruct those new to these technologies just how to create a web application with fluidity and function.

    Well Done !

    Peter
  88. I really pleased that there is starting to be some common sense in the J2EE community. I developed something very similar a year or so back but it was rejected by a Sun consultant as it wasn't the J2EE way. The whole EJB thing has been a debacle. The evolution of programming languages should be to make it easier to develop & maintain business logic. EJB seems to go the other way. I have been developing in J2EE for over a year and feel that C programming & debugging was easier than J2EE - there must be some experienced programmers who agree with me out there?

    Look at the thread on on J2EE complexity holding J2EE back http://www2.theserverside.com/discussion/thread.jsp?thread_id=15228.
  89. Hi Clinton

    Great job!

    I have a question about your DB O-R mapping layer. Is it compatible with jdk 1.4? I was trying to compile the source for that with jdk 1.4 code and got some compilation errors.

    Thanks in advance!
  90. Hi sjt,

    Yes, that is a limitation right now, but very easy to resolve. The only class that has trouble is the SimpleDataSource. JDBC 3.0 introduced some new methods that SDS doesn't implement. However, I could do this quite easily.

    As interest in JDK 1.4 grows, I'll start maintaining 2 versions at a time --the current release (1.4) and one down (1.3).

    If you send me an email, I'll send you a special JDK 1.4 version.

    Cheers,

    Clinton
  91. NOTE TO ALL: Please do not post questions here any more. I will not be monitoring this thread after today. From now on, please send me email directly.

    You can find my contact information at http://www.ibatis.com