4

I’m having a bit of a nightmare trying to write a storage extension (for Tridion 2013). So far I have set up the following:

  • Running the deployer upload servlet in Tomcat via Eclipse.
  • Start the process, drop in a deployer zip package, and successfully deploy.

So all is good with the default set up. Now I’ve tried to extend the FSPageDAO class. I’ve updated the cd_storage_conf.xml, and the referenced DAO bundle XML:

<?xml version="1.0" encoding="UTF-8"?>
<StorageDAOBundles>
   <StorageDAOBundle type="filesystem">
          <StorageDAO typeMapping="Page"
                 class="com.tridion.storage.extensions.CustomFSPageDAO" />
   </StorageDAOBundle>
</StorageDAOBundles>

The class itself does very little at the moment:

package com.tridion.storage.extensions;

import java.io.File;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tridion.broker.StorageException;
import com.tridion.data.CharacterData;
import com.tridion.storage.filesystem.FSEntityManager;
import com.tridion.storage.filesystem.FSPageDAO;

@Component("CustomFSPageDAO")
@Scope("prototype")
public class CustomFSPageDAO extends FSPageDAO
{
    private Logger log = LoggerFactory.getLogger(CustomFSPageDAO.class);

    public CustomFSPageDAO(String storageId, String storageName, File storageLocation, FSEntityManager entityManager)
    {
        super(storageId, storageName, storageLocation, entityManager);
        this.storageId = storageId;
        log.debug("CustomFSPageDAO init. (EM)");
    }

    public CustomFSPageDAO(String storageId, String storageName, File storageLocation)
    {
        super(storageId, storageName, storageLocation);
        this.storageId = storageId;
        log.debug("CustomFSPageDAO init.");
    }

    @Override
    public void create(CharacterData page, String relativePath) throws StorageException
    {
        log.debug("Create.");
        super.create(page, relativePath);
    }

    @Override
    public void update(CharacterData page, String originalRelativePath, String newRelativePath) throws StorageException
    {
        log.debug("Update.");
        super.update(page, originalRelativePath, newRelativePath);
    }

    @Override
    public void remove(int publicationId, int pageId, String relativePath) throws StorageException
    {
        log.debug("Remove.");
        super.remove(publicationId, relativePath);
    }
}

When debugging in Eclipse the http upload servlet fails to start, the following is logged:

2016-04-17 21:45:41,264 INFO  BundleConfigurationLoader - Custom storage bindings defined, loading customDAOBundle.xml
2016-04-17 21:45:41,275 WARN  BundleConfigurationLoader - CAUTION: Replaced 'Page' for storage 'filesystem' with 'com.tridion.storage.extensions.CustomFSPageDAO'.
2016-04-17 21:45:41,278 INFO  ConfigurationStepLoader - Executing configuration step: FactoryLoader
2016-04-17 21:45:41,323 ERROR StorageManagerFactory - Fatal error, unable to load the StorageManagerFactory
java.lang.ClassCastException: The target class does not match the specified target type
    at com.tridion.util.ReflectionUtil.loadClassInstanceWithTypes(ReflectionUtil.java:83) ~[cd_core.jar:na]
    at com.tridion.util.ReflectionUtil.loadClassInstance(ReflectionUtil.java:108) ~[cd_core.jar:na]
    at com.tridion.storage.filesystem.FSDAOFactory.configureBundle(FSDAOFactory.java:74) ~[cd_datalayer.jar:na]
    at com.tridion.storage.configuration.StorageFactoryConfigurationLoader.configureStorage(StorageFactoryConfigurationLoader.java:91) ~[cd_datalayer.jar:na]
    at com.tridion.storage.configuration.StorageFactoryConfigurationLoader.configureStorage(StorageFactoryConfigurationLoader.java:65) ~[cd_datalayer.jar:na]
    at com.tridion.storage.configuration.StorageFactoryConfigurationLoader.configure(StorageFactoryConfigurationLoader.java:51) ~[cd_datalayer.jar:na]
    at com.tridion.configuration.step.ConfigurationStepLoader.configure(ConfigurationStepLoader.java:47) ~[cd_core.jar:na]
    at com.tridion.storage.StorageManagerFactory.configure(StorageManagerFactory.java:137) [cd_datalayer.jar:na]
    at com.tridion.services.BaseService.<init>(BaseService.java:113) ~[cd_core.jar:na]
    at com.tridion.storage.StorageManagerFactory.<init>(StorageManagerFactory.java:104) [cd_datalayer.jar:na]
    at com.tridion.storage.StorageManagerFactory.reloadInstance(StorageManagerFactory.java:84) [cd_datalayer.jar:na]
    at com.tridion.storage.StorageManagerFactory.<clinit>(StorageManagerFactory.java:56) [cd_datalayer.jar:na]
    at com.tridion.transport.HTTPSReceiverServlet.init(HTTPSReceiverServlet.java:86) [cd_upload.jar:na]
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1238) [catalina.jar:8.0.33]
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1151) [catalina.jar:8.0.33]
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:828) [catalina.jar:8.0.33]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135) [catalina.jar:8.0.33]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.33]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [catalina.jar:8.0.33]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [catalina.jar:8.0.33]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.33]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [catalina.jar:8.0.33]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.33]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [catalina.jar:8.0.33]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-coyote.jar:8.0.33]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-coyote.jar:8.0.33]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502) [tomcat-coyote.jar:8.0.33]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458) [tomcat-coyote.jar:8.0.33]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.7.0_60]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.7.0_60]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.33]
    at java.lang.Thread.run(Unknown Source) [na:1.7.0_60]

What is odd, is that I can export this same code from Eclipse, and drop the jar into a http upload site hosted under IIS. Using the same configuration, the class is picked up without issue, and everything logs out as expected.

This would be fine, but it's not a particularly efficient development workflow. Unfortunately Java isn't my strong spot, but I assume it's more an issue with the tooling, as the same code functions under IIS.

Any ideas?

  • Could it be that your Eclipse project has some build paths pulling from the wrong locations? E.g. The deployer starts up using a copy of cd_storage_conf.xml from another location? – Nickoli Roussakov Apr 18 '16 at 11:12
  • Hi Nickoli. Thanks for your reply, but no. I can amend my project DAO bundle XML to use the default class, for example: com.tridion.storage.filesystem.FSPageDAO. If so, everything works again. So I'm fairly certain the correct configuration is being picked up. – Andy Rowland Apr 18 '16 at 11:28
  • It might be because you're running on tomcat 8, with probably the JDK 8 under it. Try to run it locally under Tomcat 7 and the JDK 7. – Raimond Apr 18 '16 at 16:33
  • I've uninstalled Tomcat 8, and installed Tomcat 7. Same issue, all is good when I comment out the storage bindings bundle. When reintroduced, the servlet fails. All is good running the same code/configuration under IIS. – Andy Rowland Apr 18 '16 at 17:02
  • Your DAO code is missing @Component("CustomFSPageDAO") @Scope("prototype"). When you are running the code using eclipse (right click - Run as), are you seeing the "cd_datalayer.jar" in the source tab? – Shiva Apr 19 '16 at 17:49
1

It's been some time but I'll supply an answer provided to me by a chap named Rob van Oostenrijk. It avoids using the Upload and Responder servlet completely.

  1. I switched to using a file system publication target, obviously setting the location to the incoming folder configured in the cd_deployer_conf.xml file.
  2. In Eclipse, create a new run configuration. In the main tab set the Main class to com.tridion.deployer.Deployer.
  3. In the Clathpath tab, highlight User Entries. Use the Advanced button to add the config folder which contains all the Deployer configurations files. Use the Add External Jars button to include all the jars in the Deployer lib found. I removed the previous compiled storage extension code that had been published there. It should look something like this:Run configuration
  4. Press the Run button.

You should now be able to add breakpoints, and see them hit whilst publishing.

Hope this helps, and thanks Rob.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.