Fix FELIX-2580 iPOJO failed to create proxies on service which are not interface
and add a test.
Disabling proxies when a scalar dependency target a concrete or abstract class.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@995124 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
index 159182d..98834dd 100644
--- a/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
+++ b/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -52,32 +52,32 @@
* Proxy settings property.
*/
public static final String PROXY_SETTINGS_PROPERTY = "ipojo.proxy";
-
+
/**
* Proxy type property.
*/
public static final String PROXY_TYPE_PROPERTY = "ipojo.proxy.type";
-
+
/**
* Proxy type value: smart.
*/
public static final String SMART_PROXY = "smart";
-
+
/**
* Proxy type value: dynamic-proxy.
*/
public static final String DYNAMIC_PROXY = "dynamic-proxy";
-
+
/**
* Proxy settings value: enabled.
*/
public static final String PROXY_ENABLED = "enabled";
-
+
/**
* Proxy settings value: disabled.
*/
public static final String PROXY_DISABLED = "disabled";
-
+
/**
* Dependency field type : Vector
* The dependency will be injected as a vector.
@@ -89,7 +89,7 @@
* The dependency will be injected as a list.
*/
protected static final int LIST = 1;
-
+
/**
* Dependency Field Type : Set.
* The dependency will be injected as a set.
@@ -105,7 +105,7 @@
* Is the handler started.
*/
private boolean m_started;
-
+
/**
* The handler description.
*/
@@ -204,7 +204,7 @@
* @return true if the dependency is valid
* @throws ConfigurationException : the checked dependency is not correct
*/
- private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {
+ private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {
// Check the internal type of dependency
String field = dep.getField();
DependencyCallback[] callbacks = dep.getCallbacks();
@@ -284,7 +284,16 @@
}
setSpecification(dep, type, true); // Throws an exception if the field type mismatch.
}
-
+
+ // Disable proxy on scalar dependency targeting non-interface specification
+ if (! dep.isAggregate() && dep.isProxy()) {
+ if (! dep.getSpecification().isInterface()) {
+ warn("Proxies cannot be used on service dependency targetting non interface " +
+ "service specification " + dep.getSpecification().getName());
+ dep.setProxy(false);
+ }
+ }
+
// Disables proxy on null (nullable=false)
// if (dep.isProxy() && dep.isOptional() && ! dep.supportsNullable()) {
// dep.setProxy(false);
@@ -333,7 +342,7 @@
+ "] are not the same");
}
}
-
+
try {
dep.setSpecification(getInstanceManager().getContext().getBundle().loadClass(className));
} catch (ClassNotFoundException e) {
@@ -358,15 +367,15 @@
// Create the dependency according to the component metadata
Element[] deps = componentMetadata.getElements("Requires");
-
+
// Get instance filters.
Dictionary filtersConfiguration = (Dictionary) configuration.get("requires.filters");
Dictionary fromConfiguration = (Dictionary) configuration.get("requires.from");
-
+
for (int i = 0; deps != null && i < deps.length; i++) {
// Create the dependency metadata
String field = deps[i].getAttribute("field");
-
+
String serviceSpecification = deps[i].getAttribute("interface");
// the 'interface' attribute is deprecated
if (serviceSpecification != null) {
@@ -374,7 +383,7 @@
} else {
serviceSpecification = deps[i].getAttribute("specification");
}
-
+
String filter = deps[i].getAttribute("filter");
String opt = deps[i].getAttribute("optional");
boolean optional = opt != null && opt.equalsIgnoreCase("true");
@@ -383,10 +392,10 @@
String agg = deps[i].getAttribute("aggregate");
boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
String identitity = deps[i].getAttribute("id");
-
+
String nul = deps[i].getAttribute("nullable");
boolean nullable = nul == null || nul.equalsIgnoreCase("true");
-
+
boolean isProxy = true;
// Detect proxy default value.
String setting = getInstanceManager().getContext().getProperty(PROXY_SETTINGS_PROPERTY);
@@ -395,7 +404,7 @@
} else if (setting != null && PROXY_DISABLED.equals(setting)) {
isProxy = false;
}
-
+
String proxy = deps[i].getAttribute("proxy");
// If proxy == null, use default value
if (proxy != null) {
@@ -406,9 +415,9 @@
warn("The configuration of a service dependency overrides the proxy mode");
}
isProxy = true;
- }
+ }
}
-
+
String scope = deps[i].getAttribute("scope");
BundleContext context = getInstanceManager().getContext(); // Get the default bundle context.
if (scope != null) {
@@ -449,7 +458,7 @@
filter = fromFilter;
}
}
-
+
Filter fil = null;
if (filter != null) {
try {
@@ -458,7 +467,7 @@
throw new ConfigurationException("A requirement filter is invalid : " + filter + " - " + e.getMessage());
}
}
-
+
Class spec = null;
if (serviceSpecification != null) {
@@ -468,7 +477,7 @@
int policy = DependencyModel.getPolicy(deps[i]);
Comparator cmp = DependencyModel.getComparator(deps[i], getInstanceManager().getGlobalContext());
-
+
Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, nullable, isProxy, identitity, context, policy, cmp, defaultImplem);
// Look for dependency callback :
@@ -510,7 +519,7 @@
}
}
}
-
+
m_description = new DependencyHandlerDescription(this, m_dependencies); // Initialize the description.
}
@@ -522,7 +531,7 @@
// Start the dependencies
for (int i = 0; i < m_dependencies.length; i++) {
Dependency dep = m_dependencies[i];
-
+
dep.start();
}
// Check the state
diff --git a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java
index a318fdc..0803a30 100644
--- a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java
+++ b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/DependencyTestSuite.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -62,6 +62,7 @@
ots.addTestSuite(ProxiedCollectionMultipleDependencies.class);
ots.addTestSuite(ModifyDependencies.class);
ots.addTestSuite(ProxyTest.class);
+ ots.addTestSuite(NonProxiedNotInterfaceDependencies.class);
return ots;
}
diff --git a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/NonProxiedNotInterfaceDependencies.java b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/NonProxiedNotInterfaceDependencies.java
new file mode 100644
index 0000000..b15e578
--- /dev/null
+++ b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/NonProxiedNotInterfaceDependencies.java
@@ -0,0 +1,64 @@
+/*
+ * 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.felix.ipojo.test.scenarios.service.dependency;
+
+import java.util.AbstractMap;
+import java.util.HashMap;
+
+import junit.framework.Assert;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.junit4osgi.OSGiTestCase;
+import org.apache.felix.ipojo.junit4osgi.helpers.IPOJOHelper;
+import org.apache.felix.ipojo.test.scenarios.service.dependency.service.CheckService;
+import org.osgi.framework.ServiceRegistration;
+
+public class NonProxiedNotInterfaceDependencies extends OSGiTestCase {
+
+ InstanceManager instance1;
+ ComponentInstance fooProvider;
+
+ ServiceRegistration reg, reg2;
+ IPOJOHelper helper;
+
+ public void setUp() {
+ helper = new IPOJOHelper(this);
+ reg = context.registerService(String.class.getName(), "ahahah", null);
+ reg2 = context.registerService(AbstractMap.class.getName(), new HashMap(), null);
+
+ }
+
+ public void tearDown() {
+ if (reg != null) {
+ reg.unregister();
+ }
+ if (reg2 != null) {
+ reg2.unregister();
+ }
+ }
+
+ public void testInstanceCreation() {
+ instance1 = (InstanceManager) helper
+ .createComponentInstance("org.apache.felix.ipojo.test.scenarios.service.dependency.proxy.CheckServiceUsingStringService");
+ Assert.assertTrue(instance1.getState() == ComponentInstance.VALID);
+ Assert.assertTrue(((CheckService) instance1.getPojoObject()).check());
+ }
+
+}
diff --git a/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/proxy/CheckServiceUsingStringService.java b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/proxy/CheckServiceUsingStringService.java
new file mode 100644
index 0000000..f822b95
--- /dev/null
+++ b/ipojo/tests/core/service-dependency/src/main/java/org/apache/felix/ipojo/test/scenarios/service/dependency/proxy/CheckServiceUsingStringService.java
@@ -0,0 +1,28 @@
+package org.apache.felix.ipojo.test.scenarios.service.dependency.proxy;
+
+import java.util.AbstractMap;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.test.scenarios.service.dependency.service.CheckService;
+
+public class CheckServiceUsingStringService implements CheckService {
+
+ private String string;
+ private AbstractMap map;
+
+
+ public CheckServiceUsingStringService() {
+ System.out.println("Service : " + string);
+ System.out.println("Map : " + map);
+ }
+
+ public boolean check() {
+ return string != null
+ && map != null;
+ }
+
+ public Properties getProps() {
+ return null;
+ }
+
+}
diff --git a/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml b/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml
index 83fd97b..1571e43 100644
--- a/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml
+++ b/ipojo/tests/core/service-dependency/src/main/resources/metadata.xml
@@ -1,5 +1,5 @@
<ipojo>
-<!--
+<!--
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
xmlns="org.apache.felix.ipojo"
@@ -9,7 +9,7 @@
name="FooProviderType-1" architecture="true">
<provides />
</component>
-
+
<!-- Simple Dependencies -->
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"
@@ -71,7 +71,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"
name="ProxiedSimpleCheckServiceProvider" architecture="true">
@@ -132,7 +132,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"
@@ -296,7 +296,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"
name="ProxiedSimpleOptionalCheckServiceProvider" architecture="true">
@@ -356,8 +356,8 @@
<callback type="unbind" method="propertiesDictionaryUnbind" />
</requires>
<provides />
- </component>
-
+ </component>
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"
name="BothOptionalNoNullableCheckServiceProvider" architecture="true">
@@ -582,7 +582,7 @@
<requires field="fs" />
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"
name="VoidMultipleCheckServiceProvider" architecture="true">
@@ -637,7 +637,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"
name="BothMultipleCheckServiceProvider" architecture="true">
@@ -674,7 +674,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"
name="DictMultipleCheckServiceProvider" architecture="true" >
@@ -693,7 +693,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"
name="MObjectMultipleCheckServiceProvider" architecture="true">
@@ -780,7 +780,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.MultipleCheckService"
name="ProxiedSimpleOptionalMultipleCheckServiceProvider"
@@ -818,7 +818,7 @@
</requires>
<provides />
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.MethodMultipleCheckService"
name="MObjectOptionalMultipleCheckServiceProvider"
@@ -841,7 +841,7 @@
</requires>
<provides />
</component>
-
+
<!-- Aggregate dependency as List -->
<component
classname="org.apache.felix.ipojo.test.scenarios.component.ListCheckService"
@@ -854,7 +854,7 @@
classname="org.apache.felix.ipojo.test.scenarios.component.ListCheckService"
name="OptionalListCheckServiceProvider"
architecture="true">
- <requires proxy="false"
+ <requires proxy="false"
specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />
<provides />
</component>
@@ -871,7 +871,7 @@
<requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />
<provides />
</component>
-
+
<!-- Aggregate dependency as Vector -->
<component
classname="org.apache.felix.ipojo.test.scenarios.component.VectorCheckService"
@@ -889,7 +889,7 @@
<requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />
<provides />
</component>
-
+
<!-- Aggregate dependency as Set -->
<component
classname="org.apache.felix.ipojo.test.scenarios.component.SetCheckService"
@@ -917,7 +917,7 @@
<requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true" />
<provides />
</component>
-
+
<!-- Aggregate dependency as Collection -->
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CollectionCheckService"
@@ -935,7 +935,7 @@
classname="org.apache.felix.ipojo.test.scenarios.component.CollectionCheckService"
name="OptionalCollectionCheckServiceProvider"
architecture="true">
- <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true"
+ <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true"
proxy="false"
/>
<provides />
@@ -944,22 +944,22 @@
classname="org.apache.felix.ipojo.test.scenarios.component.CollectionCheckService"
name="ProxiedOptionalCollectionCheckServiceProvider"
architecture="true">
- <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true"
+ <requires specification="org.apache.felix.ipojo.test.scenarios.service.dependency.service.FooService" field="fs" optional="true"
proxy="false"
/>
<provides />
</component>
-
-
+
+
<!-- Modify method test -->
<component
classname="org.apache.felix.ipojo.test.scenarios.component.FooProviderType2"
name="FooProviderType-Updatable" architecture="true">
<provides>
- <property name="foo" field="m_foo" value="foo"/>
+ <property name="foo" field="m_foo" value="foo"/>
</provides>
</component>
-
+
<component
classname="org.apache.felix.ipojo.test.scenarios.component.CheckServiceProvider"
name="VoidModifyCheckServiceProvider" architecture="true">
@@ -1034,7 +1034,15 @@
<provides/>
<requires field="fs" optional="true"/>
<callback transition="validate" method="start"/>
- <callback transition="invalidate" method="stop"/>
+ <callback transition="invalidate" method="stop"/>
</component>
-
+
+ <component
+ classname="org.apache.felix.ipojo.test.scenarios.service.dependency.proxy.CheckServiceUsingStringService"
+ immediate="true">
+ <provides/>
+ <requires field="string"/>
+ <requires field="map"/>
+ </component>
+
</ipojo>