Skip to content
Permalink
Browse files

Implemented: Show dependency resolution algorithm problem

(OFBIZ-11275)

This adds a test demonstrating a bug in the dependency resolution
algorithm done in ‘ComponentContainer’.

When relying on <depends-on> declaration in “ofbiz-component.xml”
files we should expect to retrieve components (and their associated
containers) in a topological ordering meaning a linear ordering where
each component configuration element is placed after its dependencies
configuration elements.  Currently this is not the case and the
dependency declarations only impact the construction of the dynamic
classpath.
  • Loading branch information
Samuel Trégouët authored and mthl committed Oct 20, 2019
1 parent 8aea160 commit 1317703c9ab6370d1eb52f5f44e7ec9d50edd18e
@@ -68,6 +68,17 @@

@Override
public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
init(name, Start.getInstance().getConfig().ofbizHome);
}

/**
* Loads components found in a directory.
*
* @param name the name of this container
* @param ofbizHome the directory where to search for components
* @throws ContainerException when components are already loaded or when failing to load them.
*/
void init(String name, Path ofbizHome) throws ContainerException {
if (!loaded.compareAndSet(false, true)) {
throw new ContainerException("Components already loaded, cannot start");
}
@@ -76,7 +87,7 @@ public void init(List<StartupCommand> ofbizCommands, String name, String configF
// load the components from framework/base/config/component-load.xml (root components)
try {
for (ComponentDef def: ComponentLoaderConfig.getRootComponents()) {
loadComponent(Start.getInstance().getConfig().ofbizHome, def);
loadComponent(ofbizHome, def);
}
} catch (IOException | ComponentException e) {
throw new ContainerException(e);
@@ -0,0 +1,84 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ofbiz.base.container;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.ofbiz.base.component.ComponentConfig;
import org.apache.ofbiz.base.start.StartupException;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;


public class ComponentContainerTest {
private static final Path ORDER_CONFIG = Paths.get("applications", "order", "config");
private static final Path ACCOUNTING_CONFIG = Paths.get("applications", "accounting", "config");
private static final Path[] CONFIGS = {ORDER_CONFIG, ACCOUNTING_CONFIG};

private Path ofbizHome = Paths.get("testsdata", "ComponentContainerTest").toAbsolutePath().normalize();

@Before
public void setUp() throws IOException {
cleanUp();
for (Path cfg : CONFIGS) {
Files.createDirectory(ofbizHome.resolve(cfg));
}
}

@After
public void cleanUp() throws IOException {
for (Path cfg : CONFIGS) {
Files.deleteIfExists(ofbizHome.resolve(cfg));
}
}

@Ignore("Dependency declarations do not impact the components order")
@Test
public void testCheckDependencyForComponent() throws ContainerException, StartupException, MalformedURLException {
ComponentContainer containerObj = new ComponentContainer();
containerObj.init("component-container", ofbizHome);

List<String> loadedComponents = ComponentConfig.components()
.map(c -> c.getGlobalName())
.collect(Collectors.toList());
// we can cast ContextClassLoader since ComponentContainer.loadClassPathForAllComponents has called
// setContextClassLoader with an URLClassLoader instance
URL[] classpath = ((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs();
List<URL> actualClasspath = Arrays.asList(classpath);
List<URL> expectedClasspath = Arrays.asList(
ofbizHome.resolve(ORDER_CONFIG).toUri().toURL(),
ofbizHome.resolve(ACCOUNTING_CONFIG).toUri().toURL());

assertEquals(expectedClasspath, actualClasspath);
assertEquals(Arrays.asList("order", "accounting"), loadedComponents);
}
}
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

<ofbiz-component name="accounting"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd">
<depends-on component-name="order" />
<resource-loader name="main" type="component"/>
<classpath type="dir" location="config"/>
<webapp name="accounting"
title="Accounting"
server="default-server"
location="webapp/accounting"
base-permission="OFBTOOLS,ACCOUNTING"
mount-point="/accounting"/>
</ofbiz-component>
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

<ofbiz-component name="order"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd">
<resource-loader name="main" type="component"/>
<classpath type="dir" location="config"/>
<webapp name="order"
title="Order"
description="OrderComponentDescription"
server="default-server"
location="webapp/ordermgr"
base-permission="OFBTOOLS,ORDERMGR"
mount-point="/ordermgr"/>
</ofbiz-component>

0 comments on commit 1317703

Please sign in to comment.
You can’t perform that action at this time.