This page is a brief(-ish!) look at the process, learning curve and problems etc I encountered whilst building a demo tool using the LAMS Tools Contract. The tool I'm building is just a basic forum, but it's not the actual tool that I'm really interested in, for me it's much more about the process of building a new tool, rather than the end result.
To give an idea of how long this is taking me, I'm only spending 2 weeks looking at creating a tool, so anything that's left unimplemented (or not working!) will have to be left.
What this page isn't!
This is not meant to be a user guide to creating a new tool, it's a description of the process I went through, and some people may encounter some of the same issues. This may not be the best way to go about building a new tool - just how I did it! So neither is it a complete step-by-step account of everything I've done, as that would take too much time to remember and write up!
Since Alex created his tool we have changed a number of the Java interfaces and have redone our stylesheets. An updated copy of Alex's source is attached to this page and it will compile and deploy. But any pages that use tabs look weird due to the stylesheet changes. I recommend reading Alex's report to give you an idea of what to do and what to look out for but should base your code on another tool, such as lams_tool_submit. We also have written a Eclipse plugin that helps you to copy an existing tool to a new name.
For info, this is my background knowledge etc in using the various technologies and frameworks used by LAMS for their system development:
Java: fairly good understanding of java (about 2 years developing java web apps).
Hibernate: no actual practical experience in using Hibernate, but I had an understanding of the basic concepts.
Struts: fairly good understanding having built a handful of fairly basic struts apps, though not really significant experience in building many Struts applications.
Spring: no actual practical experience in using Spring, but I had an understanding of the basic concepts.
So some of the issues I encountered are more to do with my understanding of these frameworks etc (and all their associated configuration files). Also, for info, I've not done any coding of LAMS, so I only know the basic architecture that's being used, rather than any real detail about it.
Initial set up
First thing was to get LAMS up and running on my laptop. So got this done by downloading the most recent copy of the source code and going through the instructions (http://wiki.lamsfoundation.org/display/lams/building+lams) I had a couple of little problems (just me forgetting to set up a couple of the configuration options properly!).
For info, I quickly found that you'll want to set up and install LAMS on a fairly decent machine, I was trying on a laptop, using Windows Tablet PC with 1Ghz processor & 512Mb RAM - this was not suitable as it took so long to compile, build and restart JBoss, which quickly got very frustrating.
Create the tool framework/skeleton
Once I'd actually got the main LAMS up and running, I took a copy of the lams-tool-example, to use as the basis for my tool. In this case I created a new project in Eclipse "lams-tool-alexforum" and began the actual development work.
I also had a browse through the source code of some of the other tools to get an idea of how the developers on the LAMS team had written their tools. The other tools are all written slightly (but not significantly!) differently - mainly due to the fact different developers have worked on each.
One little thing I needed to do was to ensure I'd got all the right libraries included in my project. Some were already set up just from copying the example tool, but I also had to set up the 3rdParty libraries in Eclipse, which I just imported using the script in lams-build/3rdParty.userlibraries.
Create database (and hibernate files)
I then created the scripts and Hibernate files for the tables needed for my tool. This was just by updating the scripts in the <tool>/db/sql directory and creating the various classes, files etc required for Hibernate (in the package uk.ac.open.lams.tool.alexforum.model). For info just run "generate-hbm-files" in the ant build to create the Hibernate XML files. At this point I've not thought about or added any of the actual data access methods I'll need later on - rather I'll tackle these once I get to needing to request data from the database, though if I was developing an actual tool, I would already have a good idea of the data access methods I'd need - so could implement some of them now!
Check the deployment
Before I actually started on creating any of the user interfaces, I wanted to check that my tool could actually be deployed ok (using the deploy-tool option in the ant build script), and it took a few iterations before everything worked ok, mainly as I kept finding files and config options that I'd missed. Most of the errors were easy enough to track down from the error messages in the log files. Though there was one that had me a little stumped for a while, the error I was receiving was:
The reason turned out to be because I'd missed adding the alexForumMetaDAO (and other DAO) variables to the AlexForumServiceImpl class, along with their associated getter and setter methods. Once this was done the tool was being deployed fine and I could then log into LAMS authoring to see my tool appearing alongside the other tools.
Developing the authoring interface
Now that the tool will deploy, I need to start creating an interface so the tool can actually be used. The order I'm planning on creating the interface is to do authoring, learner and finally monitor. I also found out exactly what the toolContentID and toolSessionIDs are and when/why they get generated. A ToolContentID is generated each time the tool is added to the authoring environment, so it is unique for the particular sequence the tool is in. The ToolSessionID gets generated when the sequence is actually instantiated and run, and is specific for the particular group of users. So for example, during a lesson, if the class is divided into 2 groups (each doing the same activity), there will only be one ToolContentID, but 2 ToolSessionIDs (one for each group). This way the tool doesn't need to worry about how the studnet may or may not be grouped.
The first thing I did for the authoring interface was just to implement the basic author url (<tool>/<authorurl> - actual urls are set in the <tool>/db/sql/tool_insert.sql file ) - and not to worry about generating any real content. I got this to work ok - after finding I'd not added the struts servlet mappings etc to the web.xml file.
Next error I started to receive was:
because I'd not added the reference to the alexForumApplicationContext.xml to the contextConfigLocation in my web.xml file.
Now looking at using the LAMS custom tags libraries to create an 'official looking' tool (i.e. using the right stylesheets/format etc). Made some good progress in getting this set up, and now have the authoring form appearing with the 3 standard tabs. Most of the code I used for creating the tab area was just copied from the Shraed Resources tool, just a couple of fiddly bits to make sure the tab area and tab content were in the correct place within the jsp script (originally the tab content was appearing outside the tabbed area). Another little error I had was "Cannot retrieve definition for form bean null" which ended up being due to the fact that I'd not defined a form bean for the form, so even though I'm not actually going to be using it, I had to create a very basic form bean.
Final step was to get the form to actually save some of the data (!), I was only really interested in getting the basic data saved, so stuck to the title and instructions. Had to fiddle a bit to get this working, especially as it was my first proper code using Hibernate. Couple of problems I came across were, firstly, in obtaining the data for an existing instance of the tool - getting it from Hiberate was fine, but I wasn't returning the data to the jsp via the form bean properly, but got this sorted out easily enough. My other error was that on a new tool instance I could save the content fine (and it was being stored to the database), but if I tried to update the content, I was getting an error about duplicate key ids. The issue turned out to be in my handling of the Hibernate update, I was testing to see if the toolContentID already existed, if not an new object was created (and stored to database), otherwise the existing object was cloned and this clone updated with the new data. The problem was (obvious now!) with the cloning, and all I needed to do was update the existing object.
Another step I needed to finish off was to ensure the page the user saw after submitting the form was the generic LAMS save page (so gives user option to either re-edit or close the editing window). I found I'd got a couple of elements wrong or missing in my code. Firstly, my struts xml had the AuthorSaveAction forwarding to another page, whereas it ought to have been setting the session authoring flag to true (using request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG,Boolean.TRUE)) and then redirecting back to the original edit page (in my case start.jsp). Secondly, I hadn't ensured that the ToolSignatureID and ToolContentID attributes on the <lams:AuthoringButton> tag were being set correctly, in my case (from looking at the generated HTML) both of these atrtibutes were blank. Getting both of these errors corrected reuslted in the user being forwarded to the generic save confirmation page.
That's going to be all now for the authoring interface, so now on to what the learner would see...
Developing the learner interface
First thing to do was ensure I've got the required methods implemented from the LAMS core ToolContentManager and ToolSessionManager classes in my service implementation class. The main ones to actually implement (rather than just leave stubs for!!) are:
createToolSession - creates the tool session - created when the first learner reaches the activity (though the tool doesn't need to keep track of who is the first user - LAMS core does this and then calls this createToolSession method)
copyToolContent - copies the content to the session
leaveToolSession - marks the activity as being completed by the user
I then copied the basic learning files from the 'shared resources' tool and updated to fit with my classes/database etc, all this worked fine first time - well, in that the learners screen appeared without any error messages - though it was still laid out and had all the text from the shared resources tool. I updated so it at least looks something different to the shared resources tool. Now going to get the finish action sorted out, as this send the user on to the next activity in the sequence.
Started off by copying the finish action from the Noticeboard tool - I though this code might be a bit easier to follow than the shared resources tool as the noticeboard doesn't 'do' as much, so less code to look through. The first error I came up against was... "[null] is not a legal modein LAMS", but that turned out to be because I'd not updated the test 'mode == ToolAccessMode.LEARNER'. So by commenting this out it worked fine. I'm not quite sure of the purpose of this test, a similar one appears in the authoring environment - so not sure if I need to leave it in or not!
Now my learning interface appears to be working fine, in that the learner can get to the screen (sees a message) and then can click on the finished button and is taken to the next activity, and the fact that you've completed an activity is retained between sessions/logins. All that would be needed to do now would be to make the tool actually do something, but all the interactions with LAMS core (on the authoring and learner side) are now complete.
Final step to look at (though not sure how far I'll get with it in the next couple of days) is the monitoring interface...
Developing the monitoring interface
Once again I started by copying the monitoring action code from the shared resources and noticeboard tools, though as I've been updating the code I noticed that my user table isn't being updated with the session ids, so I must have missed something in the learner interface to record this. I think I need this data to be able to complete the monitor interface, as I need to be able to show the teacher when/how often learners have logged in to the activity. I've now got this sorted out, I had missed out adding the session object to the user object before I saved the user.
The monitor interface seems a similar setup to the authoring one, in that there are a number of tabs that need to be set up and the interface is a little more predefined than the learner interface.
After a couple of errors appearing, I can now get the monitor interface to appear - well, sort of! - I don't get any errors, but the page displayed is blank, so I need to figure out what's going wrong there! Found out that it was because I'd not set up the struts forward correctly, once it was forwarding to the correct page I started to get the errors I was expecting!
The errors I got were all fairly obvious to solve - missing parameters or values being passed ot the jsp page. So was fairly easy to get the monitoring page appearing without any errors showing. However it doesn't yet show any actual details about the users who have logged in to the activity.
I feel like I'm starting to get somewhere with the tool development, though would have been good if I'd had chance to get the tool to actually 'do' something! For interest I've attached to this page a zip file of the tool code. I don't yet feel that I completely understand exactly what is going on all the time and why, but I think this is mainly due to my lack of experience and understanding with some of the frameworks used. All been relatively painless though, but I doubt I would have got as far as I have without having the core LAMS developers around to help me out when I've been getting stuck
Still to do
There are still some aspects of the tool ( & ignoring the fact the tool doesn't do anything) that are unimplemented, for example:
- Allowing online/offline instructions to be entered/uploaded
- Check useful error messages are shown on authoring interface if the user doesn't enter a title (or other required field), rather than the java error stack trace currently shown
- Add some sample field to the advanced tab on the authoring interface
- Implement the 'define later' link on the monitor interface
- Allow the tool to export details to the portfolio
- Add some actual content to the monitoring interface, currently each of the 4 tabs just shows a holding page.
These are just the missing bits I've noticed so far!