Hi - your Bookmarks portlet looks great when I run it standalone. As soon as I tried to connect it with a Postgres db it failed to load. From my tomcat log:
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'databaseInitilizer' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [CREATE TABLE IF NOT EXISTS myTable (username VARCHAR(40) PRIMARY KEY, xml CLOB);]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
Caused by: org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [CREATE TABLE IF NOT EXISTS myTable (username VARCHAR(40) PRIMARY KEY, xml CLOB);]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:337)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:329)
at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:261)
at org.springframework.jdbc.core.JdbcTemplate$1ExecuteStatementCallback.doInStatement(JdbcTemplate.java:368)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:342)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:375)
at uk.ac.bris.portlet.bookmarks.database.BookmarksDAOImpl.create(BookmarksDAOImpl.java:115)
etc....
It looks like the "create table" command in BookmarksDAOImpl.java is to blame (postgres doesn't recognize "if not exists").
I would fix this myself if I had Maven installed, but I'm not about to install yet another development platform just for one portlet. Do you happen to have a simpler method (eg an Ant script) for building and deploying? I'd really love to make use of this portlet.
Thanks!
-Robin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is good to hear from you and I am really glad that you like my portlet.
You are right that BookmarksDAOImpl calls the "CREATE TABLE" command to initialise the in-memory H2 database. However, the create call itself is invoked via the LocalH2Initializer bean (defined in the Spring configuration). LocalH2Initializer is also responsible for creating the "default" user bookmarks set.
Since you are using PostgreSQL you probably won't need to create the table and populate the default bookmarks set more than once. You can stop this happening by commenting out the databaseInitilizer bean from the Spring configuration (applicationContext.xml). In production I am running against an Oracle instance and by tweaking the "CRUD" SQL in applicationContext.xml. For instance, I additionally record the creation and last modified times.
Since you asked so nicely I have recreated an Ant based build of the bookmarks porlet. I use Maven now because it makes the distribution *MUCH* smaller and makes library upgrades easier. If you have not used Maven 2 before, I highly recommend that you give it a whirl (I'm sure you'll be impressed)! Maven itself is only 1.3Mb.
Thanks for the quick response! Your comments make perfect sense and it should be a snap to make the changes to applicationContext.xml. I should even be able to point it at our existing bookmarks table from an older app (which thankfully also used xbel).
Also thanks for providing build files for Ant ... one dumb question though ... where do I find them? I don't see them in the Subversion build anywhere. I DO see a build.properties and build.xml in the CVS source, but that build looks totally different and I'm assuming it's an older version. Can you help me out?
-Robin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have uploaded the ant build version to the downloads page (I haven't changed anything in the repository). You just need to download bmarks-portlet-0.4.antbuild.zip from the link below:
Hi Mark - I think I'm almost there with this ... it looks like it is successfully loading the 'default' bookmarks into my postgres table, but it is running into an error in the castor package when it tries to display them:
org.exolab.castor.xml.MarshalException: The class for the root element 'xbel' could not be found.{File: [not available]; line: 2; column: 21}
at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:755)
at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:721)
at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:610)
at uk.ac.bris.portlet.bookmarks.xbel.MarshallUtils.unmarshall(MarshallUtils.java:36)
at uk.ac.bris.portlet.bookmarks.database.BookmarksFacade.getBookmarksXbel(BookmarksFacade.java:39)
at uk.ac.bris.portlet.bookmarks.database.BookmarksFacade.getBookmarksXbel(BookmarksFacade.java:43)
at uk.ac.bris.portlet.bookmarks.database.BookmarksFacade.getBookmarksXbelString(BookmarksFacade.java:55)
at uk.ac.bris.portlet.bookmarks.struts.actions.main.execute(main.java:29)
etc...
With a little debugging I verified that it is successfully retrieving the XML for 'default'. Am I missing an xbel library or something?
Thanks again for your help with this.
-Robin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Whoops! Sorry Robin. In my haste to throw together a build file for you I had forgotten that the way I use Castor now has changed since I last used that build file. As a result, there are some important files that are not being copied over by the build. You need to copy the following into the bottom of the Ant "compile" target.
Works perfectly now. Thanks! What would you suggest is the best way to do single sign-on when I put this portlet into uPortal? We use LDAP for portal authentication...
I noticed a few issues when I got the portlet running in uPortal ... some of the buttons don't do anything (edit/move/delete) and the some of the text and fields in the Add Bookmark form are overlapping each other. Looks okay when I run it standalone though, so it might be the portlet adapter in uPortal causing problems.
-Robin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The portlet authetication currently relies on request.getRemoteUser() to acquire the user id. I mostly use CAS Filter and this can store the user identity in the request. If you are using LDAP authentication directly you could probably create a servlet filter and use HttpServletRequestWrapper to pass the user id into the request. It is easier than it sounds! I have done something similar in my test authentication filter:
I am aware that there are some problems when the portlet is used with too narrow a screen, I have not found a way around this as yet. I tend to run the portlet in a full tab width. If you find a solution I’d be very interested as I have a love/hate relationship with CSS!
Links not working
For me the fact that edit/delete/move are not working is more of a concern. Do you get any kind of URL being generated?
It could be to do with the ServletContextProvider implementation. I tend to use Satish Sekharan's (Memorial University) ServletContextProvider implementation (PortalServletContextProvider) which is necessary to get a Struts bridge portlet to work with uPortal. Incidentally, PortalServletContextProvider is also used inside Bedework. PortalServletContextProvider is referenced inside /WEB-INF/portlet.xml. However, I have encountered two different versions of this; maybe you could try the other version as this could possibly be affecting the edit/delete/move links.
Hi Mark - the URLs for edit/move/delete look okay, but when I click them the page just refreshes. This is the URL on the edit button when it is displayed in uPortal:
Hi Mark - think I found the problem! In WEB-INF/stylesheets/main.xsl I needed to change "_spage" to "_spageview" (4 places). I was comparing the URLs for the buttons across the top of the portlet (which work fine) and noticed that they had an "_spageview" parameter whereas the links for each bookmark on the right had "_spage".
-Robin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi - your Bookmarks portlet looks great when I run it standalone. As soon as I tried to connect it with a Postgres db it failed to load. From my tomcat log:
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'databaseInitilizer' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [CREATE TABLE IF NOT EXISTS myTable (username VARCHAR(40) PRIMARY KEY, xml CLOB);]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
Caused by: org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [CREATE TABLE IF NOT EXISTS myTable (username VARCHAR(40) PRIMARY KEY, xml CLOB);]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:337)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:329)
at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:261)
at org.springframework.jdbc.core.JdbcTemplate$1ExecuteStatementCallback.doInStatement(JdbcTemplate.java:368)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:342)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:375)
at uk.ac.bris.portlet.bookmarks.database.BookmarksDAOImpl.create(BookmarksDAOImpl.java:115)
etc....
It looks like the "create table" command in BookmarksDAOImpl.java is to blame (postgres doesn't recognize "if not exists").
I would fix this myself if I had Maven installed, but I'm not about to install yet another development platform just for one portlet. Do you happen to have a simpler method (eg an Ant script) for building and deploying? I'd really love to make use of this portlet.
Thanks!
-Robin
Hi Robin,
It is good to hear from you and I am really glad that you like my portlet.
You are right that BookmarksDAOImpl calls the "CREATE TABLE" command to initialise the in-memory H2 database. However, the create call itself is invoked via the LocalH2Initializer bean (defined in the Spring configuration). LocalH2Initializer is also responsible for creating the "default" user bookmarks set.
Since you are using PostgreSQL you probably won't need to create the table and populate the default bookmarks set more than once. You can stop this happening by commenting out the databaseInitilizer bean from the Spring configuration (applicationContext.xml). In production I am running against an Oracle instance and by tweaking the "CRUD" SQL in applicationContext.xml. For instance, I additionally record the creation and last modified times.
Since you asked so nicely I have recreated an Ant based build of the bookmarks porlet. I use Maven now because it makes the distribution *MUCH* smaller and makes library upgrades easier. If you have not used Maven 2 before, I highly recommend that you give it a whirl (I'm sure you'll be impressed)! Maven itself is only 1.3Mb.
Best wishes,
Mark
For reference;
BookmarksDAOImpl:
<http://bmarks-portlet.svn.sourceforge.net/viewvc/bmarks-portlet/bmarks-portlet/trunk/src/main/java/uk/ac/bris/portlet/bookmarks/database/BookmarksDAOImpl.java?view=markup>
LocalH2Initializer:
<http://bmarks-portlet.svn.sourceforge.net/viewvc/bmarks-portlet/bmarks-portlet/trunk/src/main/java/uk/ac/bris/portlet/bookmarks/database/LocalH2Initializer.java?revision=6&view=markup>
applicationContext.xml:
<http://bmarks-portlet.svn.sourceforge.net/viewvc/bmarks-portlet/bmarks-portlet/trunk/src/main/webapp/WEB-INF/applicationContext.xml?view=markup>
Thanks for the quick response! Your comments make perfect sense and it should be a snap to make the changes to applicationContext.xml. I should even be able to point it at our existing bookmarks table from an older app (which thankfully also used xbel).
Also thanks for providing build files for Ant ... one dumb question though ... where do I find them? I don't see them in the Subversion build anywhere. I DO see a build.properties and build.xml in the CVS source, but that build looks totally different and I'm assuming it's an older version. Can you help me out?
-Robin
I have uploaded the ant build version to the downloads page (I haven't changed anything in the repository). You just need to download bmarks-portlet-0.4.antbuild.zip from the link below:
<https://sourceforge.net/project/showfiles.php?group_id=154104>
HTH
Mark
Hi Mark - I think I'm almost there with this ... it looks like it is successfully loading the 'default' bookmarks into my postgres table, but it is running into an error in the castor package when it tries to display them:
org.exolab.castor.xml.MarshalException: The class for the root element 'xbel' could not be found.{File: [not available]; line: 2; column: 21}
at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:755)
at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:721)
at org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:610)
at uk.ac.bris.portlet.bookmarks.xbel.MarshallUtils.unmarshall(MarshallUtils.java:36)
at uk.ac.bris.portlet.bookmarks.database.BookmarksFacade.getBookmarksXbel(BookmarksFacade.java:39)
at uk.ac.bris.portlet.bookmarks.database.BookmarksFacade.getBookmarksXbel(BookmarksFacade.java:43)
at uk.ac.bris.portlet.bookmarks.database.BookmarksFacade.getBookmarksXbelString(BookmarksFacade.java:55)
at uk.ac.bris.portlet.bookmarks.struts.actions.main.execute(main.java:29)
etc...
With a little debugging I verified that it is successfully retrieving the XML for 'default'. Am I missing an xbel library or something?
Thanks again for your help with this.
-Robin
Whoops! Sorry Robin. In my haste to throw together a build file for you I had forgotten that the way I use Castor now has changed since I last used that build file. As a result, there are some important files that are not being copied over by the build. You need to copy the following into the bottom of the Ant "compile" target.
<copy todir="${build.home}/WEB-INF/classes/">
<fileset dir="src" includes="**/*.cdr"/>
</copy>
Cheers,
Mark
For futher info see:
<http://www.castor.org/xml-best-practice.html>
Works perfectly now. Thanks! What would you suggest is the best way to do single sign-on when I put this portlet into uPortal? We use LDAP for portal authentication...
I noticed a few issues when I got the portlet running in uPortal ... some of the buttons don't do anything (edit/move/delete) and the some of the text and fields in the Add Bookmark form are overlapping each other. Looks okay when I run it standalone though, so it might be the portlet adapter in uPortal causing problems.
-Robin
Hi Robin,
Authentication
The portlet authetication currently relies on request.getRemoteUser() to acquire the user id. I mostly use CAS Filter and this can store the user identity in the request. If you are using LDAP authentication directly you could probably create a servlet filter and use HttpServletRequestWrapper to pass the user id into the request. It is easier than it sounds! I have done something similar in my test authentication filter:
<http://bmarks-portlet.svn.sourceforge.net/viewvc/bmarks-portlet/bmarks-portlet/trunk/src/main/java/uk/ac/bris/portlet/bookmarks/web/SimpleAuthFilter.java?view=markup>
CSS
I am aware that there are some problems when the portlet is used with too narrow a screen, I have not found a way around this as yet. I tend to run the portlet in a full tab width. If you find a solution I’d be very interested as I have a love/hate relationship with CSS!
Links not working
For me the fact that edit/delete/move are not working is more of a concern. Do you get any kind of URL being generated?
It could be to do with the ServletContextProvider implementation. I tend to use Satish Sekharan's (Memorial University) ServletContextProvider implementation (PortalServletContextProvider) which is necessary to get a Struts bridge portlet to work with uPortal. Incidentally, PortalServletContextProvider is also used inside Bedework. PortalServletContextProvider is referenced inside /WEB-INF/portlet.xml. However, I have encountered two different versions of this; maybe you could try the other version as this could possibly be affecting the edit/delete/move links.
Bookmarks portlet default:
<http://bmarks-portlet.svn.sourceforge.net/viewvc/bmarks-portlet/bmarks-portlet/trunk/src/main/java/ca/mun/portal/bridges/>
Alternative implementation:
<http://loka.it.su.se/source/xref/su-bedework/projects/webapps/uportal/src/ca/mun/portal/strutsbridge/>
See also:
<http://bmarks-portlet.svn.sourceforge.net/viewvc/bmarks-portlet/bmarks-portlet/trunk/src/main/webapp/WEB-INF/portlet.xml?revision=3&view=markup>
<http://www.ja-sig.org/wiki/display/PLT/Struts+Bridge>
Cheers,
Mark
Hi Mark - the URLs for edit/move/delete look okay, but when I click them the page just refreshes. This is the URL on the edit button when it is displayed in uPortal:
http://localhost:8080/uPortal/tag.4a0db80b001a54a4.render.userLayoutRootNode.target.366.uP?uP_portlet_action=false&_spage=%2FPopulateEdit.do%3Fpathid%3D%2F1%26type%3DBookmark#366
And in standalone mode, which works fine:
http://localhost:8080/bmarks-portlet-0-4/PopulateEdit.do?pathid=/1&type=Bookmark
I'll try your suggestions and see what happens. Thanks.
-Robin
Something else I forgot to say! You will need to set:
org.jasig.portal.ChannelManager.use_anchors=false
in portal.properties. I think this could fix it!
If you are still having difficulty after that you should try the alternative ServletContextProvider implementation.
Cheers,
Mark
Hi Mark - think I found the problem! In WEB-INF/stylesheets/main.xsl I needed to change "_spage" to "_spageview" (4 places). I was comparing the URLs for the buttons across the top of the portlet (which work fine) and noticed that they had an "_spageview" parameter whereas the links for each bookmark on the right had "_spage".
-Robin