Hi Ben, basically there are a lot of differences between a command line recommender and a web application.
First thing is the packaging. If you want your recommender to work as a web application you have to put all the necessary libs into the WEB-INF/lib directory. This has nothing todo with Mahout itself it is just how web applications work. In this email you will find the complete list of files how I package them in the facebook-recommender-demo. https://github.com/ManuelB/facebook-recommender-demo You can open the facebook-recommender-demo directly in NetBeans and should be able to inspect it. So you have to tell NetBeans that you need the mahout libs. I am using maven to find the dependencies and maven does package them automatically including all transitive dependencies. Next thing is life cycle of application. A command line recommender starts as a process does what it has to do and dies afterwards. A web application runs as part of the servlet container (tomcat, jetty, glassfish, etc.). This means that it will run for a long time. You should instantiate you recommender only once and then reuse it for all user requests. The recommender will use a lot of memory (in my tests about 0,2 kb per entry. meaning 60mb for 300.000 entries). As far as I know taste is thread safe. Therefore you need only one recommender in your whole web application server process. You do this in the init method. You can use a static variable and the singleton pattern. An alternative would be to put the recommender in the ServletContext by using set attribute function. Here are some links of how to do this: * http://javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html * http://www.codestyle.org/java/servlets/faq-Threads.shtml * http://en.wikipedia.org/wiki/Singleton_pattern * http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html * http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#setAttribute(java.lang.String, java.lang.Object) Another difference is where to get your data from. I do not know if you are using a file, a database, cassandra, mongo db or any other source. I will expect that you are using a file. In a command line environment you can just pull your data from everywhere. In a web application this is far more complicated. The web application uses it own class loader and therefore it is searching resources in different places. Again in https://github.com/ManuelB/facebook-recommender-demo/blob/master/src/main/java/de/apaxo/bedcon/FacebookRecommender.java I show how to read the values from a file which is prepacked in the web application. * http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html ... 138 // get the file which is part of the WAR as 139 URL url = getClass().getClassLoader().getResource(DATA_FILE_NAME); 140 141 // create a file out of the resource 142 File data = new File(url.toURI()); ... I hope that helps. If you need more help you can buy some professional support. For example my company (http://www.apaxo.de) is selling professional support. Feel free to concat me personally. /Manuel $ jar -tf facebook-recommender-demo.war META-INF/ META-INF/MANIFEST.MF WEB-INF/ WEB-INF/classes/ WEB-INF/classes/de/ WEB-INF/classes/de/apaxo/ WEB-INF/classes/de/apaxo/bedcon/ WEB-INF/lib/ WEB-INF/classes/de/apaxo/bedcon/FacebookRecommender.class WEB-INF/classes/de/apaxo/bedcon/FacebookRecommenderREST.class WEB-INF/classes/de/apaxo/bedcon/FacebookRecommenderSOAP.class WEB-INF/classes/DemoFriendsLikes.csv WEB-INF/lib/commons-beanutils-1.7.0.jar WEB-INF/lib/commons-beanutils-core-1.8.0.jar WEB-INF/lib/commons-cli-1.2.jar WEB-INF/lib/commons-cli-2.0-mahout.jar WEB-INF/lib/commons-codec-1.4.jar WEB-INF/lib/commons-collections-3.2.1.jar WEB-INF/lib/commons-configuration-1.6.jar WEB-INF/lib/commons-digester-1.8.jar WEB-INF/lib/commons-httpclient-3.0.1.jar WEB-INF/lib/commons-lang-2.6.jar WEB-INF/lib/commons-logging-1.0.3.jar WEB-INF/lib/commons-math-2.2.jar WEB-INF/lib/guava-r09.jar WEB-INF/lib/hadoop-core-0.20.204.0.jar WEB-INF/lib/jackson-core-asl-1.8.2.jar WEB-INF/lib/jackson-mapper-asl-1.8.2.jar WEB-INF/lib/lucene-analyzers-3.4.0.jar WEB-INF/lib/lucene-core-3.4.0.jar WEB-INF/lib/mahout-collections-1.0.jar WEB-INF/lib/mahout-core-0.6.jar WEB-INF/lib/mahout-math-0.6.jar WEB-INF/lib/slf4j-api-1.6.1.jar WEB-INF/lib/solr-commons-csv-3.1.0.jar WEB-INF/lib/uncommons-maths-1.2.2.jar WEB-INF/lib/watchmaker-framework-0.6.2.jar WEB-INF/lib/xpp3_min-1.1.4c.jar WEB-INF/lib/xstream-1.3.1.jar WEB-INF/web.xml META-INF/maven/ META-INF/maven/de.apaxo.bedcon/ META-INF/maven/de.apaxo.bedcon/facebook-recommender-demo/ META-INF/maven/de.apaxo.bedcon/facebook-recommender-demo/pom.xml META-INF/maven/de.apaxo.bedcon/facebook-recommender-demo/pom.properties On 07.03.2012, at 22:52, Ben Brodie wrote: > I have created a netbeans maven web project. How would you recommend I can > use RecommenderService class to create the service in my project? The best I > can do is to create my own servlet. > > Also, should I be learning EE and make a RESTful service like the facebook > recommender? My concern is that RecommenderService is already created so I > know it works. I would rather not create my own service, as I am not familiar > with Java EE. > > -----Original Message----- > From: Ted Dunning [mailto:[email protected]] > Sent: Wednesday, March 07, 2012 1:53 PM > To: [email protected] > Subject: Re: packaging a recommender as a war file > > A separate project like this is a better way to package this in any case. > It is bad practice to have developers modifying Mahout itself in order to > build their applications. > > Nice work, Manuel! > > On Wed, Mar 7, 2012 at 10:00 AM, Manuel Blechschmidt < > [email protected]> wrote: > >> Hi Ben, >> I have a gihub project which creates a war file in the end with a ready to >> go recommender. >> >> It is a Java EE 6 application with EJBs. Nevertheless should be easy to >> package it as a web app. >> >> https://github.com/ManuelB/facebook-recommender-demo >> >> /Manuel >> >> >> On 07.03.2012, at 17:54, Ben Brodie wrote: >> >>> Hi, >>> >>> I am not all that familiar with maven, and perhaps that is the source of >> my troubles. I can not figure out how to use the "integration" directory >> for packaging a recommender as a war file. The website only gives an >> example that is already set up, but that doesn't tell me how to package my >> own recommender. I also have Mahout In Action, but this is written for 0.5, >> which seems to use a different method of this. Furthermore, the current >> distribution of 0.5 does not have the same structure as that referred to in >> Mahout In Action. >>> >>> This should be easy --- I have my custom Recommender and would like to >> package this as a war file (preferably with 0.6). All I need is a direct >> explanation of how to accomplish this. >>> >>> Thanks, >>> Ben >> >> -- >> Manuel Blechschmidt >> Dortustr. 57 >> 14467 Potsdam >> Mobil: 0173/6322621 >> Twitter: http://twitter.com/Manuel_B >> >> -- Manuel Blechschmidt Dortustr. 57 14467 Potsdam Mobil: 0173/6322621 Twitter: http://twitter.com/Manuel_B
