A common problem that comes up is the need to change how documents are stored in the Document Library.
For example, you may start out storing documents using Jackrabbit hooked to a database. However, as time goes on and you find yourself using more Liferay deployments, the number of database connections reserved for Jackrabbit alone gets dangerously close to the maximum number of database connections supported by your database vender.
So, you want to switch from using
JCRHook over to using the
FileSystemHook to store documents on a SAN.
If your migration uses two different hooks and you have access to the portal class loader (for example, you're running in the EXT environment, or you have the ability to update the context class loader for your web application like in Tomcat 5.5), the solution is straightforward.
InputStream exportStream = sourceHook.getFileAsStream( companyId, folderId, fileName, versionNumber); targetHook.updateFile( companyId, portletId, groupId, folderId, fileName, versionNumber, fileName, fileEntryId, properties, modifiedDate, tagsCategories, tagsEntries, exportStream);
In summary, you instantiate the hook objects, pull data from your source hook and push it to your target hook. Then, update your configurations and restart your server to use the new document library hook. (In case you're not sure how to change document library hooks, see the comments for the
dl.hook.impl property in
If you'd like to see how this is accomplished via code samples rather than via textual explanations, these document links might help (just to note, the sample plugins SDK portlets leverage the portal class loader in order to access the classes found in
portal-impl.jar, and so you must use Tomcat 5.5 or another servlet container that supports a similar mechanism in order to use them):
- sample 5.2.x migration code
- sample 5.1.x migration portlet (requires Tomcat 5.5)
- sample 5.2.x migration portlet (requires Tomcat 5.5)
However, it's not always so easy. Another common problem is where you start out using Jackrabbit hooked up to a file system (perhaps in the earlier iterations of Liferay where
JCRHook was the default), but you want to move to a clustered environment and you do not have access to a SAN.
Therefore, you want to migrate over to using Jackrabbit hooked to a database.
This is different from the previous problem in that you're using the same exact hook in both cases, and the way Liferay handles Jackrabbit inside of this hook makes it so that you can only have one active Jackrabbit workspace configuration (specified in your
portal.properties file), and so simply instantiating two different hooks is not possible.
The solution here is to run the migration twice.
First, with the original
JCRHook configuration, export the data to an intermediate hook (for example, the Liferay
FileSystemHook) and shut down your Liferay instance. Then, you update
repository.xml to reflect the desired
JCRHook configuration, and import from your intermediate hook back to
If you do not have access to the portal class loader, the migration is less straightforward, because you won't have access to the hook classes themselves.
InputStream exportStream = DLLocalServiceUtil.getFileAsStream( companyId, folderId, fileName, versionNumber); FileUtil.write(intermediateFileLocation, exportStream); InputStream importStream = new FileInputStream(intermediateFileLocation); DLLocalServiceUtil.updateFile( companyId, portletId, groupId, folderId, fileName, versionNumber, fileName, fileEntryId, properties, modifiedDate, tagsCategories, tagsEntries, importStream);
In summary, you'll have to read the documents using
DLLocalServiceUtil with the original configuration and save them to disk in a way where you can parse all the data needed to call
updateFile (perhaps in the same way that mirrors the way
FileSystemHook works). Then, you re-import those exported documents using
DLLocalServiceUtil after updating your configuration and restarting the server.