MCPcopy Create free account
hub / github.com/diffplug/goomph / OsgiExecable

Interface OsgiExecable

src/main/java/com/diffplug/gradle/osgi/OsgiExecable.java:73–137  ·  view source on GitHub ↗

Runs code that lives outside an OSGi container inside of it. Works just like JavaExecable. Make sure the code you execute only uses classes which are available to the OSGi runtime you're using. If you'd like to call some code which is only available inside the OSGi container, use a {@link

Source from the content-addressed store, hash-verified

71 * ```
72 */
73public interface OsgiExecable extends Serializable, Runnable {
74 /** Executes the given {@link OsgiExecable} within an embedded OSGi runtime. */
75 public static <T extends OsgiExecable> T exec(BundleContext context, T input) throws Exception {
76 // find OsgiExecImp.execInternal within the OSGi runtime
77 Bundle bundle = OsgiExecImp.loadBundle(context);
78 bundle.start();
79 Class<?> clazz = bundle.loadClass(OsgiExecImp.class.getName());
80 Method execInternal = clazz.getMethod("execInternal", File.class);
81 // write the input to a tempfile
82 File tempFile = File.createTempFile("OsgiExec", ".temp");
83 try {
84 SerializableMisc.write(tempFile, input);
85 // call it within the OSGi runtime
86 execInternal.setAccessible(true);
87 execInternal.invoke(null, tempFile);
88 // get the result, and return it
89 return SerializableMisc.read(tempFile);
90 } finally {
91 FileMisc.forceDelete(tempFile);
92 }
93 }
94
95 /**
96 * Defines data which will be passed via reflection to code within the OSGi runtime - the reflection
97 * allows us to call code for which we don't have the necessary dependencies to resolve its imports
98 * unless it is only instantiated within the OSGi container.
99 */
100 @SuppressWarnings("serial")
101 public static abstract class ReflectionHost implements OsgiExecable {
102 private final String delegate;
103
104 protected ReflectionHost(String delegate) {
105 this.delegate = Objects.requireNonNull(delegate);
106 }
107
108 @Override
109 public void run() {
110 try {
111 Bundle bundle = FrameworkUtil.getBundle(OsgiExecable.class);
112 Class<?> clazz = bundle.loadClass(delegate);
113 Constructor<?>[] constructors = clazz.getDeclaredConstructors();
114 if (constructors.length != 1) {
115 throw new IllegalArgumentException(delegate + " must have only one constructor, this had " + constructors.length);
116 }
117 if (constructors[0].getParameterCount() != 1) {
118 throw new IllegalArgumentException(delegate + "'s constructor must take one argument, this took " + constructors[0].getParameterCount());
119 }
120 constructors[0].setAccessible(true);
121 ReflectionClient<?> client = (ReflectionClient<?>) (Object) constructors[0].newInstance(this);
122 client.run();
123 } catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
124 throw new RuntimeException(e);
125 }
126 }
127 }
128
129 /** Client code which gets called within the OSGi runtime. */
130 public static abstract class ReflectionClient<Host extends ReflectionHost> implements Runnable {

Callers 4

testExternalMethod · 0.95
runMethod · 0.95
ideMethod · 0.65

Implementers 2

Incrementersrc/test/java/com/diffplug/gradle/p2/O
ReflectionHostsrc/main/java/com/diffplug/gradle/osgi

Calls

no outgoing calls

Tested by

no test coverage detected