You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by da...@apache.org on 2010/12/20 11:35:45 UTC
svn commit: r1051042 - in
/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook:
SpiFly/src/org/apache/aries/spifly/ SpiFlyTests/src/org/apache/aries/spifly/
SpiFlyTests/src/org/apache/aries/spifly/impl3/
SpiFlyTests/src/org/apache/aries/spifl...
Author: davidb
Date: Mon Dec 20 10:35:45 2010
New Revision: 1051042
URL: http://svn.apache.org/viewvc?rev=1051042&view=rev
Log:
Support for treating methods other than ServiceLoader.load()
Added:
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/WeavingData.java
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/JaxpClient.java
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/services/
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/services/javax.xml.parsers.DocumentBuilderFactory
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/MyAltDocumentBuilderFactory.java
Modified:
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/Activator.java
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/TCCLSetterVisitor.java
incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java
Modified: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/Activator.java?rev=1051042&r1=1051041&r2=1051042&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/Activator.java (original)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/Activator.java Mon Dec 20 10:35:45 2010
@@ -18,7 +18,6 @@
*/
package org.apache.aries.spifly;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -120,14 +119,16 @@ public class Activator implements Bundle
}
// TODO unRegisterProviderBundle();
-
public void registerConsumerBundle(Bundle consumer, Collection<Bundle> spiProviders) {
+ if (spiProviders == null)
+ return;
+
registeredConsumers.put(consumer, spiProviders);
}
public Collection<Bundle> findConsumerRestrictions(Bundle consumer) {
return registeredConsumers.get(consumer);
}
-
+
// TODO unRegisterConsumerBundle();
}
Modified: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java?rev=1051042&r1=1051041&r2=1051042&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java (original)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/ClientWeavingHook.java Mon Dec 20 10:35:45 2010
@@ -21,6 +21,7 @@ package org.apache.aries.spifly;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.ServiceLoader;
import org.apache.aries.spifly.HeaderParser.PathElement;
import org.apache.aries.spifly.api.SpiFlyConstants;
@@ -53,26 +54,45 @@ public class ClientWeavingHook implement
Bundle consumerBundle = wovenClass.getBundleWiring().getBundle();
String consumerHeader = consumerBundle.getHeaders().get(SpiFlyConstants.SPI_CONSUMER_HEADER);
if (consumerHeader != null) {
- Activator activator = Activator.activator;
- activator.log(LogService.LOG_DEBUG, "Weaving class " + wovenClass.getClassName());
+ Activator.activator.log(LogService.LOG_DEBUG, "Weaving class " + wovenClass.getClassName());
- if (!"true".equalsIgnoreCase(consumerHeader)) {
- activator.registerConsumerBundle(consumerBundle, parseHeader(consumerHeader));
- }
+ WeavingData wd = parseHeader(consumerBundle, consumerHeader);
ClassReader cr = new ClassReader(wovenClass.getBytes());
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
- TCCLSetterVisitor tsv = new TCCLSetterVisitor(cw, wovenClass.getClassName());
+ TCCLSetterVisitor tsv = new TCCLSetterVisitor(cw, wovenClass.getClassName(), wd);
cr.accept(tsv, 0);
wovenClass.setBytes(cw.toByteArray());
wovenClass.getDynamicImports().add(addedImport);
}
}
- private Collection<Bundle> parseHeader(String consumerHeader) {
+ private WeavingData parseHeader(Bundle consumerBundle, String consumerHeader) {
List<Bundle> selectedBundles = new ArrayList<Bundle>();
for (PathElement element : HeaderParser.parseHeader(consumerHeader)) {
+ String name = element.getName().trim();
+ String className;
+ String methodName;
+ int hashIdx = name.indexOf('#');
+ if (hashIdx > 0) {
+ className = name.substring(0, hashIdx);
+ int braceIdx = name.substring(hashIdx).indexOf('(');
+ if (braceIdx > 0) {
+ methodName = name.substring(hashIdx + 1, hashIdx + braceIdx);
+ } else {
+ methodName = name.substring(hashIdx + 1);
+ }
+ } else {
+ if ("true".equalsIgnoreCase(name)) {
+ className = ServiceLoader.class.getName();
+ methodName = "load";
+ } else {
+ className = name;
+ methodName = null;
+ }
+ }
+
String bsn = element.getAttribute("bundle");
if (bsn != null) {
for (Bundle b : bundleContext.getBundles()) {
@@ -82,8 +102,16 @@ public class ClientWeavingHook implement
}
}
}
+
+ Activator.activator.log(LogService.LOG_INFO, "Weaving " + className + "#" + methodName + " from bundle " +
+ consumerBundle.getSymbolicName() + " to " + (selectedBundles.size() == 0 ? " any provider" : selectedBundles));
+
+ if (selectedBundles.size() > 0)
+ Activator.activator.registerConsumerBundle(consumerBundle, selectedBundles);
+
+ // TODO support more than one definition
+ return new WeavingData(className, methodName, 1);
}
-
- return selectedBundles;
+ return null;
}
}
Modified: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/TCCLSetterVisitor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/TCCLSetterVisitor.java?rev=1051042&r1=1051041&r2=1051042&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/TCCLSetterVisitor.java (original)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/TCCLSetterVisitor.java Mon Dec 20 10:35:45 2010
@@ -19,6 +19,7 @@
package org.apache.aries.spifly;
import java.util.Arrays;
+import java.util.ServiceLoader;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
@@ -38,10 +39,12 @@ public class TCCLSetterVisitor extends C
private static final String VOID_RETURN_TYPE = "()V";
private final String targetClass;
+ private final WeavingData weavingData;
- public TCCLSetterVisitor(ClassVisitor cv, String className) {
+ public TCCLSetterVisitor(ClassVisitor cv, String className, WeavingData weavingData) {
super(cv);
this.targetClass = className.replace('.', '/');
+ this.weavingData = weavingData;
}
@Override
@@ -58,15 +61,15 @@ public class TCCLSetterVisitor extends C
// Add generated static method
/* Equivalent to:
- * private static void SomeMethodName(Class<?> cls) {
+ * private static void $$FCCL$$(Class<?> cls) {
* Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader());
* }
*/
MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_STATIC, GENERATED_METHOD_NAME,
"(Ljava/lang/Class;)V", "(Ljava/lang/Class<*>;)V", null);
mv.visitCode();
- mv.visitLdcInsn("java.util.ServiceLoader");
- mv.visitLdcInsn("load");
+ mv.visitLdcInsn(weavingData.getClassName());
+ mv.visitLdcInsn(weavingData.getMethodName());
mv.visitVarInsn(ALOAD, 0);
String typeIdentifier = "L" + targetClass + ";";
mv.visitLdcInsn(Type.getType(typeIdentifier));
@@ -91,7 +94,6 @@ public class TCCLSetterVisitor extends C
public TCCLSetterMethodVisitor(MethodVisitor mv) {
super(mv);
}
-
/**
* Store the last LDC call. When ServiceLoader.load(Class cls) is called
@@ -118,16 +120,23 @@ public class TCCLSetterVisitor extends C
System.out.println("### " + opcode + ": " + owner + "#" + name + "#" + desc);
if (opcode == INVOKESTATIC &&
- "java/util/ServiceLoader".equals(owner) &&
- "load".equals(name)) {
+ weavingData.getClassName().replace('.', '/').equals(owner) &&
+ weavingData.getMethodName().equals(name)) {
System.out.println("+++ Gotcha!");
// Add: Util.storeContextClassloader();
mv.visitMethodInsn(INVOKESTATIC, UTIL_CLASS,
"storeContextClassloader", VOID_RETURN_TYPE);
// Add: MyClass.$$FCCL$$(<class>);
+
// The class is the same class as the one passed into the ServiceLoader.load() api.
- mv.visitLdcInsn(lastLDCType);
+ if (ServiceLoader.class.getName().equals(weavingData.getClassName()) &&
+ "load".equals(weavingData.getMethodName())) {
+ mv.visitLdcInsn(lastLDCType);
+ } else {
+ Type type = Type.getType("L" + owner + ";");
+ mv.visitLdcInsn(type);
+ }
mv.visitMethodInsn(INVOKESTATIC, targetClass,
GENERATED_METHOD_NAME, "(Ljava/lang/Class;)V");
Added: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/WeavingData.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/WeavingData.java?rev=1051042&view=auto
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/WeavingData.java (added)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFly/src/org/apache/aries/spifly/WeavingData.java Mon Dec 20 10:35:45 2010
@@ -0,0 +1,29 @@
+package org.apache.aries.spifly;
+
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+
+public class WeavingData {
+ private final String className;
+ private final String methodName;
+ private final int argCount;
+
+ public WeavingData(String className, String methodName, int argCount) {
+ this.className = className;
+ this.methodName = methodName;
+ this.argCount = argCount;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public int getArgCount() {
+ return argCount;
+ }
+}
Modified: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java?rev=1051042&r1=1051041&r2=1051042&view=diff
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java (original)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/ClientWeavingHookTest.java Mon Dec 20 10:35:45 2010
@@ -119,6 +119,50 @@ public class ClientWeavingHookTest {
Assert.assertEquals("Only the services from bundle impl2 should be selected", "HELLO5", result);
}
+ @Test
+ public void testServiceProviderOverloadUnprocessed() {
+ Assert.fail("Test that ServiceLoader.load(2) doesn't get affected");
+ }
+
+ @Test
+ public void testJAXPClientWantsJREImplementation() throws Exception {
+ Dictionary<String, String> headers = new Hashtable<String, String>();
+ headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "todo");
+ Bundle consumerBundle = mockConsumerBundle(headers);
+
+ WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle));
+
+ URL clsUrl = getClass().getResource("JaxpClient.class");
+ WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.JaxpClient", consumerBundle);
+ wh.weave(wc);
+
+ Class<?> cls = wc.getDefinedClass();
+ Method method = cls.getMethod("test", new Class [] {});
+ Class<?> result = (Class<?>) method.invoke(cls.newInstance());
+ Assert.assertEquals("JAXP implementation from JRE", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", result.getName());
+ }
+
+ @Test
+ public void testJAXPClientWantsAltImplementation() throws Exception {
+ Dictionary<String, String> headers = new Hashtable<String, String>();
+ headers.put(SpiFlyConstants.SPI_CONSUMER_HEADER, "javax.xml.parsers.DocumentBuilderFactory#newInstance();bundle=impl3");
+ Bundle consumerBundle = mockConsumerBundle(headers);
+
+ Bundle providerBundle = mockProviderBundle("impl3", 1, "META-INF/services/javax.xml.parsers.DocumentBuilderFactory");
+ Activator.activator.registerProviderBundle("javax.xml.parsers.DocumentBuilderFactory", providerBundle);
+
+ WeavingHook wh = new ClientWeavingHook(mockSpiFlyBundle(consumerBundle));
+
+ URL clsUrl = getClass().getResource("JaxpClient.class");
+ WovenClass wc = new MyWovenClass(clsUrl, "org.apache.aries.spifly.JaxpClient", consumerBundle);
+ wh.weave(wc);
+
+ Class<?> cls = wc.getDefinedClass();
+ Method method = cls.getMethod("test", new Class [] {});
+ Class<?> result = (Class<?>) method.invoke(cls.newInstance());
+ Assert.assertEquals("JAXP implementation from alternative bundle", "org.apache.aries.spifly.impl3.MyAltDocumentBuilderFactory", result.getName());
+ }
+
private BundleContext mockSpiFlyBundle(Bundle ... bundles) {
return mockSpiFlyBundle("spifly", new Version(1, 0, 0), bundles);
}
Added: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/JaxpClient.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/JaxpClient.java?rev=1051042&view=auto
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/JaxpClient.java (added)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/JaxpClient.java Mon Dec 20 10:35:45 2010
@@ -0,0 +1,9 @@
+package org.apache.aries.spifly;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+public class JaxpClient {
+ public Class<?> test() {
+ return DocumentBuilderFactory.newInstance().getClass();
+ }
+}
Added: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/services/javax.xml.parsers.DocumentBuilderFactory
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/services/javax.xml.parsers.DocumentBuilderFactory?rev=1051042&view=auto
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/services/javax.xml.parsers.DocumentBuilderFactory (added)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/META-INF/services/javax.xml.parsers.DocumentBuilderFactory Mon Dec 20 10:35:45 2010
@@ -0,0 +1 @@
+org.apache.aries.spifly.impl3.MyAltDocumentBuilderFactory
Added: incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/MyAltDocumentBuilderFactory.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/MyAltDocumentBuilderFactory.java?rev=1051042&view=auto
==============================================================================
--- incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/MyAltDocumentBuilderFactory.java (added)
+++ incubator/aries/trunk/spi-fly/contrib/pilot_using_weavinghook/SpiFlyTests/src/org/apache/aries/spifly/impl3/MyAltDocumentBuilderFactory.java Mon Dec 20 10:35:45 2010
@@ -0,0 +1,52 @@
+/**
+ * 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.aries.spifly.impl3;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class MyAltDocumentBuilderFactory extends DocumentBuilderFactory {
+
+ @Override
+ public DocumentBuilder newDocumentBuilder()
+ throws ParserConfigurationException {
+ return null;
+ }
+
+ @Override
+ public void setAttribute(String name, Object value)
+ throws IllegalArgumentException {
+ }
+
+ @Override
+ public Object getAttribute(String name) throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public void setFeature(String name, boolean value)
+ throws ParserConfigurationException {
+ }
+
+ @Override
+ public boolean getFeature(String name) throws ParserConfigurationException {
+ return false;
+ }
+}