Hybris: How to Override a Bean in backoffice-web-spring.xml

Hybris: How to Override a Bean in backoffice-web-spring.xml

While working on a recent Hybris project for a client, I came across the need to override a Backoffice web context bean found in the backoffice-web-spring.xml application context file. As Backoffice based extension projects don’t provide access to the Backoffice web application context, I needed to find a way to override the bean and make it work. This tutorial describes the steps I took, and the way in which I accomplished it.

This solution leverages the customize process. From the Build Framework article found on Hybris Help:

SAP Hybris Commerce contains a process to include custom files in the ${HYBRIS_BIN_DIR} directory. This process copies the content of the ${HYBRIS_CONFIG_DIR}/customize directory to the ${HYBRIS_BIN_DIR} directory.

For your information, here are a few important things about this tutorial:

1. This tutorial was put together using Hybris 6.2.0.

1. It is assumed that a Hybris Backoffice based extension has been already been generated and added to the list of required extensions. If you need help generating a Hybris Backoffice based extension, please refer to the Hybris Help tutorial Creating a Custom Backoffice Extension.

2. The Backoffice based extension’s project name used in this tutorial is extbackoffice.

3. I will be overriding a method within the com.hybris.backoffice.cockpitng.dataaccess.facades.type.DefaultPlatformTypeFacadeStrategy class as part of the tutorial.

Now, let’s begin!

Step 1. Create an Extension Class

Create a new class by extending the DefaultPlatformTypeFacadeStrategy within the extbackoffice project. Place this new class in the backoffice/src source path.

For this tutorial, I am going to override the public DataType convertType(TypeModel platformType, boolean lightWeight, Context context) method, placing some logging statements within and around a super call so that I can see when its being called, as well as debug the return object. Some sample code for this new class is shown below.

package com.extbackoffice.backoffice.cockpitng.dataaccess.facades.type;

import de.hybris.platform.core.model.type.TypeModel;

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

import com.hybris.backoffice.cockpitng.dataaccess.facades.type.DefaultPlatformTypeFacadeStrategy;
import com.hybris.cockpitng.dataaccess.context.Context;
import com.hybris.cockpitng.dataaccess.facades.type.DataType;


/**
 * @author daharveyjr
 */
public class ExtDefaultPlatformTypeFacadeStrategy extends DefaultPlatformTypeFacadeStrategy
{

	private static Logger LOG = LoggerFactory.getLogger(ExtDefaultPlatformTypeFacadeStrategy.class);

	@Override
	public DataType convertType(final TypeModel platformType, final boolean lightWeight, final Context context)
	{

		LOG.trace("Entry");

		final DataType returnObj = super.convertType(platformType, lightWeight, context);

		LOG.debug("return[returnObj|{}]", returnObj);
		LOG.trace("Exit");

		return returnObj;

	}

}

Step 2. Create a New Web Application Context

Out of the box, the Backoffice project loads the backoffice-web-spring.xml application context file when starting up the Backoffice application. A new web application context file needs to be created that can be loaded in combination with the backoffice-web-spring.xml application context file during application startup, allowing your new extension class, ExtDefaultPlatformTypeFacadeStrategy, to be loaded.

Create a new application context file named extbackoffice-web-spring.xml. Place the extbackoffice-web-spring.xml application context file within the backoffice/resources/web/webroot/WEB-INF folder. As this folder structure doesn’t exist, the folder structure will need to be created before creating the extbackoffice-web-spring.xml application context file.

Within the extbackoffice-web-spring.xml application context file, create an override bean definition that references back the ExtDefaultPlatformTypeFacadeStrategy class created in the previous step, when the DefaultPlatformTypeFacadeStrategy class was extended.

An example Spring bean definition can be found below.

<alias alias="platformTypeFacadeStrategy" name="extDefaultPlatformTypeFacadeStrategy" />
<bean id="extDefaultPlatformTypeFacadeStrategy" parent="defaultPlatformTypeFacadeStrategy"
    class="com.extbackoffice.backoffice.cockpitng.dataaccess.facades.type.ExtDefaultPlatformTypeFacadeStrategy">
</bean>

Step 3. Copy and Modify the Backoffice web.xml File

Now, I’ll register the newly created extbackoffice-web-spring.xml application context file with the web application so that it loads when the web application starts up.

To begin copy the web.xml file found at backoffice/web/webroot/WEB-INF/web.xml, and place it within the backoffice/resources/web/webroot/WEB-INF folder that was previously created.

At this point, I’d recommend backing up the original file, by copying the file again, and renaming it web.bak. This way if something goes wrong, there is a reliable backup that can be referenced or reverted back to.

Modify the web.xml file previously copied and modify the contextConfigLocation context-param, to include the newly created extbackoffice-web-spring.xml file as shown below.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        WEB-INF/backoffice-web-spring.xml
        WEB-INF/extbackoffice-web-spring.xml
    </param-value>
</context-param>

Step 4. Setup the buildcallbacks.xml File

Setup the buildcallbacks.xml file in the extbackoffice extension project to include some new macro definitions that will move the files previously created into place in the core Backoffice project, allowing the new logic and files created to take effect.

I’ve included below the macro definitions and the source code of a sample buildcallbacks.xml file for reference. It may be customized, and I have generalized it for this tutorial.

A few things to note about this specific buildcallbacks.xml file.

1. There are two newly defined macro defintions: extbackoffice_prepare_customize_class_files and extbackoffice_prepare_customize_static_files.

2. The extbackoffice_prepare_customize_class_files will move the compiled class files specified into the appropriate location within config folder so that they can then be moved into the Hybris core at the appropriate time.

3. The extbackoffice_prepare_customize_static_files will move the static files specified into the appropriate location within config folder so that they can then be moved into the Hybris core at the appropriate time.

4. The class.files.list property used within the extbackoffice_prepare_customize_class_files macro definition is composed of individual file names, concatenated together, to create an iterative array. The file names referenced in these properties, need to correspond to a compiled class file. For this tutorial, the class file for the ExtDefaultPlatformTypeFacadeStrategy, with its full canonical path is referred to.

5. The static.files.list property is composed of individual file names, concatenated together, to create an iterative array. The file names referenced in these properties refer to static files that don’t require compilation.

6. These two newly created macro definitions are added into the extbackoffice_after_build macro. After a build has been completed, the two newly created macro definitions are called and the assets are moved into the config folder.

<property name="class.files.0" value="com/extbackoffice/backoffice/cockpitng/dataaccess/facades/type/ExtDefaultPlatformTypeFacadeStrategy.class" />
<property name="class.files.list" value="${class.files.0}" />
	
<macrodef name="extbackoffice_prepare_customize_class_files">
	<sequential>
		<for param="file.item" list="${class.files.list}">
			<sequential>
				<if>
					<available file="${ext.extbackoffice.path}/backoffice/classes/@{file.item}" />
					<then>
						<copy file="${ext.extbackoffice.path}/backoffice/classes/@{file.item}" tofile="${HYBRIS_CONFIG_DIR}/customize/ext-backoffice/backoffice/web/webroot/WEB-INF/classes/@{file.item}" />
					</then>
				</if>
			</sequential>
		</for>
	</sequential>
</macrodef>

<property name="static.files.0" value="web/webroot/WEB-INF/web.bak" />
<property name="static.files.1" value="web/webroot/WEB-INF/web.xml" />
<property name="static.files.2" value="web/webroot/WEB-INF/extbackoffice-web-spring.xml" />
<property name="static.files.list" value="${static.files.0},${static.files.1},${static.files.2}" />

<macrodef name="extbackoffice_prepare_customize_static_files">
	<sequential>
		<for param="file.item" list="${static.files.list}">
			<sequential>
				<if>
					<available file="${ext.extbackoffice.path}/backoffice/resources/@{file.item}" />
					<then>
						<copy file="${ext.extbackoffice.path}/backoffice/resources/@{file.item}" tofile="${HYBRIS_CONFIG_DIR}/customize/ext-backoffice/backoffice/@{file.item}" />
					</then>
				</if>
			</sequential>
		</for>
	</sequential>
</macrodef>

<macrodef name="extbackoffice_after_build">
	<sequential>
		<extbackoffice_prepare_customize_class_files />
		<extbackoffice_prepare_customize_static_files />
	</sequential>
</macrodef>

Step 5. Clean, Compile, and Customize

At this point, all logic and assets will have been put into place and the new assets need to be compiled, executed, and put into place within the Hybris core. The following command, familiar to all Hybris developers, can now be used to accomplish that.

The buildcallbacks.xml file setup earlier will be triggered by the all target which will compile and move both the class and static files to the ‘/config/customize’ folder; however, to actually move those assets to the ‘/bin’ directory, the customize target must be called.

The customize target, per the target definition, “Copies all files from ‘/config/customize/’ folder to ‘/bin’ recursively. This will move the newly created class and static files into the Hybris core ‘/bin’ directory. The customize target is not triggered as part of another ant target, so it requires an explicit call.

ant clean all customize

NOTE: This solution can be adapted to override any web context bean definition found in any -web-spring.xml file within Hybris when you don’t have direct access to the web application context.

Author: daharveyjr

I’m a solution architect responsible for the design, development, implementation, testing, and maintenance of e-commerce operations and applications using the Hybris and WebSphere Commerce product suites and other web technologies such as Java, J2EE/JEE, Spring, PHP, WordPress and more. Twitter | Facebook | LinkedIn

4 thoughts on “Hybris: How to Override a Bean in backoffice-web-spring.xml

  1. Bryan Reply

    Just wanted to give you a thanks for this. Ran into an issue and this was exactly what I needed to get around the problem.

  2. Izzuddin Karim Reply

    thanks for this excellent writing. easy to understand.

    quick question, why don’t you use backoffice.additionalWebSpringConfigs=classpath:/extbackoffice/backoffice/resources/web/webroot/WEB-INF/extbackoffice-web-spring.xml

    to inject your custom bean definition to the backoffice core ?

  3. Amrut Reply

    Great information!! I had a similar requirement and had to override ProductCloneStrategy. All I did is override the productCloneStrategy alias with my new bean in -backoffice-spring.xml.

Leave a Reply

Your email address will not be published. Required fields are marked *