Developing for Sakai Time - Presented by Zach Thomas 00:00:15 - Lead Developer at Texas State University - Full-time Sakai developer for 18 months - What does a Sakai developer do? 00:00:38 - Install Sakai for demoing purposes - Update skin to match local institution - Install third-party tools - Write code (such as a provider) to integrate Sakai with local institution - Write tools from scratch - What skills do you need? 00:01:22 - Steep learning curve - Java - Need knowledge beyond knowing Java syntax - Know about Java beans, how to create them - Know object orientation - Know difference between a Java class and a Java interface and how they are used - Web application development - Java servlets - How a web app is laid out - Setting up a web.xml file - Sakai is built on a large stack of open source libraries and tools - Finding websites - Reading documentation - Reading source code - Searching mailing lists - Learning to ask good questions - Tools 00:03:25 - Subversion - Sakai's source control system - Moved to Subversion from CVS with Sakai 2.0 - Keep all code and documents in one place - All developers use same code base - THE essential tool for an open source project - svn --version - Shows Subversion is installed properly - Use svn to get source code from Sakai - Create three directories - trunk - Main development work - branches - Work that may interfere with main work - tags - Used for releases - svn export [Sakai source] [local directory] - Create local Subversion repository to hold your code - svn import [local directory] [local repository] - svn checkout - Provides developer with working copy - Tomcat 00:10:22 - A servlet container - A reference implementation for the Java servlet specification - Use version 5.5.12 - Also get the JDK 1.4 Compatibility patch - Allows Tomcat to run in an older version of Java - Keep Tomcat .zip files locally - Easy to create a fresh Tomcat installation if need to - Just unzip and put folder wherever - Apache Maven 00:12:37 - Tool for automating the build process - Cleaning out build directory - Compiling - Running unit tests - Creating jar and war files (called "artifacts") - Copying artifacts over to Tomcat - For every project you want Maven to build, you tell it which third-party libraries your code depends on - Maven keeps a copy in local directory and uses it to manage dependencies - During compile, then, Maven knows to add it to your classpath - If Maven can't find it, it will go out onto the network and download third-party libraries from repositories you specify - Sakai uses 1.0.2 - A new version (2.0) exists, but it is built on an entirely different architecture - Just unzip and put folder wherever - To run Maven, add it to execute path - export MAVEN_HOME=[path to installation] - export PATH=$PATH:$MAVEN_HOME/bin - maven --version - First give Maven two commands - maven sakai:build sakai:deploy - Next, tell it which directory you want it to run in This would be the local copy of the Subversion code - -d [local Sakai code] - Next, give Maven two properties - -Dmaven.repo.remote=http://www.ibilblio.org/maven/;http://cvs.sakaiproject.org/maven/ This is the repository for any missing third-party libraries on the network - -Dmaven.tomcat.home=[local Tomcat directory] Tells Maven the location of the local Tomcat installation so Maven knows where to move .jar and .war files - Whole Maven command is - maven sakai:build sakai:deploy -d [local Sakai code] -Dmaven.repo.remote -Dmaven.tomcat.home - Compiles all code, then runs deploy step to copy files to Tomcat - Starting Sakai 00:18:35 - Run Tomcat startup script - ./apache-tomcat-5.5.12/bin/startup.sh - Once it is started, monitor log file - tail -f ./apache-tomcat-5.5.12/logs/catlina.out - This logs shows you everything happening in server - Components and tools being registered - When developing, you'll always have this log file running in an open window - Some housekeeping details regarding Maven - The environment variables passed to Maven only exist while that Terminal session is open - Add properties to file .bash_profile in home directory - export MAVEN_HOME=[path to installation] - export PATH=$PATH:$MAVEN_HOME/bin - Create file build.properties in home directory - Commands normally entered in command line can be stored here - -Dmaven.repo.remote=http://www.ibilblio.org/maven/;http://cvs.sakaiproject.org/maven/ - -Dmaven.tomcat.home=[local Tomcat directory] - Download Sakai plugin for Maven - Allows developers to use shorthand for certain Sakai-related tasks - Maven keeps local repository in ~/.maven/repository - All of these folders are independent projects that Maven added to directory during build process - Illustrates how Sakai is build on a large stack of open-source libraries and tools - Maven also puts .jar and .war files it creates during the build process - These files are called "artifacts" - It can use these artifacts as dependencies in any other code - Sakai Architecture 00:24:15 - 2005-12_Developing_For_Sakai - Constellation of tools: this is what you see and touch in Sakai - Tools make calls to service APIs for things they need to do - e.g., A service for sending email is called "EmailService" - When a tool needs to send an email, it makes a call to the EmailService API - The actual implementation of the APIs are independent of the API definition, which means the API can be swapped out at any time - For example, the EmailService is implemented by a service called BasicEmailService - It works fine for most purposes, but if you wanted to use an encrypted email, you could write a new implementation that fulfills the EmailService API - E.g., Create a new implementation called SecureEmailService and plug that in and the tools that use the service would not know there had been a change. - The tool has no knowledge of the implementation of the API which means you can change all sorts of functionality out without breaking the tools that depend on that functionality. - The Sakai framework is also a set of implementations and services at a lower level - Its functionality is that used by any of the services - e.g., the framework can generate unique IDS, provide facilities for logging, can register tools and components, control session lifecycles, controls rendering UI widgets - = Common functionality in one place shared by many tool - Organization of Sakai: Where is all above in the file system? 00:27:35 Two places: In the Tomcat deployment environment and in the source code - Tomcat - [tomcat]/webapps = Sakai tools - Maven builds all the .war files - When Sakai starts up, it extracts all the .war files into a directory of the same name - Some tools are grouped together - e.g., Sakai legacy tool came from Chef, and are all grouped together in a directory within webapps called "sakai-legacy-tools" - The services APIs are in "[tomcat]/shared/lib directory" - You will find a bunch of .jar files here that contain the API definitions for all the Sakai services - These are not the implementations of the services, just the API definitions - The implementations of the APIs are in the "components" directory - Components is a Sakai convention; there is not normally a components directory within a Tomcat installation. - Each of the folders under components is a special kind of web app in that there is no user interface -- only a "lib" directory with all the .jar files belonging to the web app - Each directory in the components directory is called a component package - These files contain the actual implementations of the Sakai services - Source Code - The modules can contain many sub directories called "projects" - Some modules are easier to figure out than others - e.g., the Syllabus module contains the Syllabus tool - The tool has its own API, service implementation, and web app (the actual user interface) - Every Sakai tool has a common way of organizing it. - "src" directory - Inside of which is a "java" directory and a "webapp" directory - These are the most common directories - Under "legacy" is where you find all the legacy tools - Announcement, assignment, calendar, etc. - These tools all rely on a service called "legacy-service" - "Legacy-service" directory - Inside is "src" directory is "java" directory where you'll find all the java packages for the legacy services - Includes site service, user service - Here are the actual source files for the API definitions, not the implementations - Includes framework services - Cache, logging service, etc. - To see how these services are implemented, go back to "legacy" module - Under "component" directory are another set of Java packages corresponding to all of the legacy services, but this time, these are the actual implementations of the legacy services - In each of the project directories is a file called "project.xml" - This is how we configure Maven to build a given artifact - Each project.xml is responsible for building one artifact, either a .jar file or a .war file - project_xml - Maven uses the groupId to determine which directory to copy artifact in local Maven repository - Uses artifactId and currentVersion to create file name - e.g., Maven will create file called "foo-hello-1.0.jar" - Property "deploy.type" tells Maven where to copy artifact during deploy stage of the build - If deploy.type is "jar" Maven does not move it into Tomcat; it just moves it into the local repository, then the component packages can bundle these all up together - If deploy.type is "war" then Maven copies this artifact into the webapps directory within Tomcat; you use this for a tool. - If deploy.type is "shared" then Maven copies this artifact into the Tomcat/shared/lib directory; this is for service APIs. - If deploy.type is "component" then Maven creates a war file and copies this artifact into the components directory in Tomcat. - "dependencies" is where you tell Maven what libraries your code depends on - e.g., my code depends on log4j, and I give it what version of log4j my code uses - Each project can depend on only that version it needs - "build" tag tells Maven where source files are kept - You can also specifiy unit tests, application.properties files, etc. - Eclipse IDE 00:38:48 De facto IDE for Sakai project - Not necessary to use Eclipse, but easy to get started because Sakai source tree includes config files for Eclipse. - Download from eclipse.org - Eclipse is a complete development environment - Browse source files - Run debugger - Run unit tests - Infinitely expandable via plugins - Setting up Eclipse for Sakai - Add classpath variable called "MAVEN_REPO" - Point it to local Maven repository in home directory - Install Subclipse plugin - Allows interaction with Subversion repository from within Eclipse - Import all Sakai code into Eclipse - Import project using "Existing Projects into Workspace" - Point it to Sakai source folder - Eclipse finds config files within modules - Services and Components 00:44:18 - Recall that all the Sakai services have implementation that can be swapped out and changed at any time - The combination of an API and its implimentation is called a "component" - Sakai uses Spring framework to determine which class you want to use to implement a given service. - With Spring, you configure all your componenets using a special XML file called "components.xml" - components_xml - Each component is defined in a "bean" tag - Each bean has an ID which is the fully qualified name of the interface that the component is meant to fulfill - Followed by the class which actually implements this service - There are a few other attributes for controlling the lifecycle of the bean and we can just leave those as defauls - In the second bean, in addition to naming the implementing class, you can also set properties on that component. - In this case, it is BasicEmailService and it has properties of smtp, smtpPort,smtpFrom, and a logger - The logger is actually a dependency on another Sakai service, so we use the "ref" tag to reference the other bean we have defined above. - We give it the ID of the component we want to use in this component - In Sakai, services can depend on one another and Spring is responsible for connecting them up with each other. - Putting it Together: A New Provider 00:46:56 - A provider is a service for integrating Sakai with your institution's infrastructure, such as register DB or user directory - A provider has an API just like any other service, and you write an implementation that interacts with your institution's systems - Sakai comes with some providers already installed - A user directory provider for integration with LDAP - A user directory provider for use with Kerberos - By default all the providers for use with Sakai are in the "samples" directory - The sample providers are demos of how they might actually be implemented - Creating a new provider in Eclipse - Create a new folder in providers directory - Create inside that a new "src" folder and inside that, a new "java" folder - Create a new package - The fastest way is to copy the sample user provider and pasting it in the new package - Eclipse is smart enough to change the name, but you need to refactor the class to the new name. - Changes all references to this class in the source code; matches text in code comments - New provider directory needs a "project.xml" file so that Maven will know how to build it - Will copy form sample and paste it here for example - Only need to change name to the new name - Change GroupId to new ID - Change ArtifactId to new ID - Change tags under "Organization" -- purely cosmetic - Adding new code to Subversion repository - Use Subclipse plugin - Click on new provider directory, then select Team/Add to Version Control on pop-up menu - Enter commit comment -- sets up Subversion metadata - All the new code gets transfered up to Subversion server - Next, we need to tell Sakai to use this new provider - Go to providers/component/src/webapps/WEB-INF/ - Edit "components.xml" file - Change the bean tag that defines the UserDirectoryProvider to the new provider - Edit "project.xml" file for the components package and add the new provider as a dependency on that package - Just copy an existing dependency and change the groupId and artifactId to the new provider - This ensures the .jar file for the new provider will be bundled into the components package - Return to Terminal and rerun Maven - If you change to a subdirectory of the sakai source tree, Maven will only build the projects in that subdirectory - In this case, we're only building the artifacts for the providers module - If you look in the new provider directory, you will see a new directory called "target" which Maven created, including the .jar artifact - You can use the jar command to view the contents of the .jar file - jar -tf [new providers]/target/new-provider-1.0.jar - You'll find the package and classes we created - You can also use the jar command on the .war file in the component directory to see Maven created a .war file that includes the component.xml file and the new-provider-1.0.jar file - jar -tf component/target/sakai-legacy-providers.war - You can commit the changes to the Subversion repository - Add a new message for the log - Writing Sakai Tools 00:58:12 - Beyond the scope of this presentation - In a nutshell, though, a Sakai tool is just a conventional Java servlet web app - To make it work in Sakai, you add a special XML tool registration file in /src/webapps/tools - review other tools for examples - Add a Sakai RequestFilter to web.xml - this gives your tool capabilities like Sakai sessions and authentication - More information 00:59:12 - Read the source code -- it is the ultimate authorioty on how it works - sakaiproject.org - collab.sakai.project.org - Follow-up Notes (as of January 11, 2006) Questions and answers from the sakai-dev mailing list - Q: When I type maven sakai:build... it said, "Goal "sakai:build" does not exist in this project." I checked maven.xml, there are no such goal in it. - A: This is something that's not really explained in the presentation: The maven goals used by Sakai are only available if the maven sakai plugin is available. The plugin is available in two ways: 1) if you run maven against a project.xml file that has the sakai plugin as a dependency. See the project.xml file in the top-level Sakai source directory for an example of this. 2) if you install the Sakai plugin permanently into your maven installation. This is performed with the command maven plugin:download -DartifactId=sakai -DgroupId=sakaiproject -Dversion=2.1 -Dmaven.repo.remote=http://cvs.sakaiproject.org/maven/ In practical terms, this means that if you run maven in the same directory as the top level of the Sakai source code, you won't get the 'Goal "sakai:build" does not exist in this project.' error. On the other hand, if you just install the Sakai plugin for maven, you can run maven in any directory and it will know about all the maven sakai goals. For your reference, here is a list of all the goals in the Sakai plugin for maven: sakai ............................................ clean then build then deploy sakai:build ................................. compile and package the build sakai:clean ................................. cleanup from prior builds sakai:clean_build ..................... clean and then build sakai:clean_build_deploy ...... clean then build then deploy sakai:deploy ............................. deploy to the local tomcat sakai:deploy-report ................. Report on what jars Sakai deploys - which projects deploy what to where sakai:deploy-zip ...................... deploy to the maven.deploy.home and zip a tomcat overlay structure sakai:undeploy ....................... remove from the local tomcat - Q: I got to the part where I import all the source files into Eclipse. I set the MAVEN_REPO classpath variable to: C:/Documents and Settings/gpp8p/.maven/repository Note - I am running Eclipse 3.1.1 with the MyEclipse plugin - the milestone 2 release (that's a beta release of MyEclipse). I do the import, and everything comes in fine. However, there are a slew of errors [snip] - A: Getting Eclipse to build everything perfectly is more of an art than a science. Or not even art; you pretty much have to hit it over the head repeatedly until everything works properly. I neatly sidestepped this whole problem in my demo. If you'll notice, right before I import all the Sakai modules into Eclipse, I go to the Project menu and uncheck "Build Automatically." This prevents Eclipse from even *attempting* to build everything itself. All those errors about missing dependencies are the result of maven having not yet built up your local repository. You have to run a full maven build of Sakai at least once for all the necessary dependencies to be in the .maven/repository directory. And as far as all the errors about projects not building because projects that depend on them haven't been built, you should try building the modules one at a time by using the "Clean" command under the Project menu. Do the util module first, then kernel, then try the others in no particular order. But bear in mind that getting Eclipse to behave is not strictly necessary. That's why I could switch off automatic builds in Eclipse with no consequences. All the building and deploying ultimately happens at the command line with maven.