http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/licenses/apache-2.0.txt ---------------------------------------------------------------------- diff --git a/modules/osgi/licenses/apache-2.0.txt b/modules/osgi/licenses/apache-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/modules/osgi/licenses/apache-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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.
http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/pom.xml ---------------------------------------------------------------------- diff --git a/modules/osgi/pom.xml b/modules/osgi/pom.xml new file mode 100644 index 0000000..d6d46bf --- /dev/null +++ b/modules/osgi/pom.xml @@ -0,0 +1,171 @@ +<?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. +--> + +<!-- + POM file. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-parent</artifactId> + <version>1</version> + <relativePath>../../parent</relativePath> + </parent> + + <artifactId>ignite-osgi</artifactId> + <version>1.5.0-SNAPSHOT</version> + <url>http://ignite.apache.org</url> + + <dependencies> + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-core</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <version>${osgi.core.version}</version> + </dependency> + + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam</artifactId> + <version>4.6.0</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-junit4</artifactId> + <version>4.6.0</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.ops4j.pax.exam</groupId> + <artifactId>pax-exam-container-karaf</artifactId> + <version>4.6.0</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.karaf</groupId> + <artifactId>apache-karaf</artifactId> + <version>${karaf.version}</version> + <type>tar.gz</type> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + <version>1</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.ops4j.pax.url</groupId> + <artifactId>pax-url-aether</artifactId> + <version>2.4.3</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- Generate the OSGi MANIFEST.MF for this bundle. + This bundle is a fragment attached to the ignite-core bundle, as it contains and exports classes in + the org.apache.ignite.internal.processors.query.h2.opt in the same manner as ignite-geospatial, thus + leading to a split package situation in OSGi. It also contains an internal processor. + --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Fragment-Host>org.apache.ignite.ignite-core</Fragment-Host> + </instructions> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.servicemix.tooling</groupId> + <artifactId>depends-maven-plugin</artifactId> + <version>1.3.1</version> + <executions> + <execution> + <id>generate-depends-file</id> + <goals> + <goal>generate-depends-file</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <forkCount>1</forkCount> + <systemProperties> + <property> + <name>karafVersion</name> + <value>${karaf.version}</value> + </property> + <property> + <name>projectVersion</name> + <value>${project.version}</value> + </property> + <property> + <name>camelVersion</name> + <value>${camel.version}</value> + </property> + </systemProperties> + </configuration> + </plugin> + + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteAbstractOsgiContextActivator.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteAbstractOsgiContextActivator.java b/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteAbstractOsgiContextActivator.java new file mode 100644 index 0000000..ac76f6e --- /dev/null +++ b/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteAbstractOsgiContextActivator.java @@ -0,0 +1,238 @@ +/* + * 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.ignite.osgi; + +import java.util.Dictionary; +import java.util.Hashtable; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteException; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.Ignition; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.util.typedef.internal.A; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.osgi.classloaders.BundleDelegatingClassLoader; +import org.apache.ignite.osgi.classloaders.ContainerSweepClassLoader; +import org.apache.ignite.osgi.classloaders.OsgiClassLoadingStrategyType; +import org.jetbrains.annotations.Nullable; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * This {@link BundleActivator} starts Apache Ignite inside the OSGi container when the bundle is started. + * <p> + * Create an implementation of this class and set the {@code Bundle-Activator} OSGi Manifest header to the FQN of + * your class. + * <p> + * You must provide the {@link IgniteConfiguration} to start by implementing the {@link #igniteConfiguration()} + * abstract method. The return value of this method cannot be {@code null}. For example, if your implementation is + * called {@code org.myorg.osgi.IgniteActivator}, your bundle must provide the following header: + * <pre> + * Bundle-Activator: org.myorg.osgi.IgniteActivator + * </pre> + * You may use the + * <a href="https://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html">Maven + * Bundle Plugin</a> to generate your bundle (or bundle manifest), including the required header. + * <p> + * This activator also exports the Ignite instance as an OSGi service, with the property {@code ignite.name} set + * to the value of {@link Ignite#name()}, if and only if the name is not null. + * <p> + * Currently, Ignite only allows a single instance per container. We may remove this limitation if enough demand + * builds up in the community. + * + * @see <a href="http://wiki.osgi.org/wiki/Bundle-Activator">Bundle-Activator OSGi Manifest header</a> + * + */ +public abstract class IgniteAbstractOsgiContextActivator implements BundleActivator { + /** OSGI service property name. */ + public static final String OSGI_SERVICE_PROP_IGNITE_NAME = "ignite.name"; + + /** The instance of Ignite started by this Activator. */ + protected Ignite ignite; + + /** Our bundle context. */ + private BundleContext bundleCtx; + + /** Ignite logger. */ + private IgniteLogger log; + + /** + * Method invoked by OSGi to start the bundle. It starts the specified Ignite configuration. + * + * @param ctx Bundle context. + * @throws Exception + */ + @Override public final void start(BundleContext ctx) throws Exception { + // Ensure that no other instances are running. + if (IgniteOsgiUtils.gridCount() > 0) { + throw new IgniteException("Failed to start Ignite instance (another instance is already running " + + "and ignite-osgi is currently limited to a single instance per container)."); + } + + bundleCtx = ctx; + + // Start the Ignite configuration specified by the user. + IgniteConfiguration cfg = igniteConfiguration(); + + A.notNull(cfg, "Ignite configuration"); + + // Override the classloader with the classloading strategy chosen by the user. + ClassLoader clsLdr; + + if (classLoadingStrategy() == OsgiClassLoadingStrategyType.BUNDLE_DELEGATING) + clsLdr = new BundleDelegatingClassLoader(bundleCtx.getBundle(), Ignite.class.getClassLoader()); + else + clsLdr = new ContainerSweepClassLoader(bundleCtx.getBundle(), Ignite.class.getClassLoader()); + + cfg.setClassLoader(clsLdr); + + onBeforeStart(ctx); + + // Start Ignite. + try { + ignite = Ignition.start(cfg); + } + catch (Throwable t) { + U.error(log, "Failed to start Ignite via OSGi Activator [errMsg=" + t.getMessage() + ']', t); + + onAfterStart(ctx, t); + + return; + } + + log = ignite.log(); + + log.info("Started Ignite from OSGi Activator [name=" + ignite.name() + ']'); + + // Add into Ignite's OSGi registry. + IgniteOsgiUtils.classloaders().put(ignite, clsLdr); + + // Export Ignite as a service. + exportOsgiService(ignite); + + onAfterStart(ctx, null); + } + + /** + * Stops Ignite when the bundle is stopping. + * + * @param ctx Bundle context. + * @throws Exception If failed. + */ + @Override public final void stop(BundleContext ctx) throws Exception { + onBeforeStop(ctx); + + try { + ignite.close(); + } + catch (Throwable t) { + U.error(log, "Failed to stop Ignite via OSGi Activator [errMsg=" + t.getMessage() + ']', t); + + onAfterStop(ctx, t); + + return; + } + + if (log.isInfoEnabled()) + log.info("Stopped Ignite from OSGi Activator [name=" + ignite.name() + ']'); + + IgniteOsgiUtils.classloaders().remove(ignite); + + onAfterStop(ctx, null); + } + + /** + * This method is called before Ignite initialises. + * <p> + * The default implementation is empty. Override it to introduce custom logic. + * + * @param ctx The {@link BundleContext}. + */ + protected void onBeforeStart(BundleContext ctx) { + // No-op. + } + + /** + * This method is called after Ignite initialises, only if initialization succeeded. + * <p> + * The default implementation is empty. Override it to introduce custom logic. + * + * @param ctx The {@link BundleContext}. + * @param t Throwable in case an error occurred when starting. {@code null} otherwise. + */ + protected void onAfterStart(BundleContext ctx, @Nullable Throwable t) { + // No-op. + } + + /** + * This method is called before Ignite stops. + * <p> + * The default implementation is empty. Override it to introduce custom logic. + * + * @param ctx The {@link BundleContext}. + */ + protected void onBeforeStop(BundleContext ctx) { + // No-op. + } + + /** + * This method is called after Ignite stops, only if the operation succeeded. + * <p> + * The default implementation is empty. Override it to introduce custom logic. + * + * @param ctx The {@link BundleContext}. + * @param t Throwable in case an error occurred when stopping. {@code null} otherwise. + */ + protected void onAfterStop(BundleContext ctx, @Nullable Throwable t) { + // No-op. + } + + /** + * Override this method to provide the Ignite configuration this bundle will start. + * + * @return The Ignite configuration. + */ + public abstract IgniteConfiguration igniteConfiguration(); + + /** + * Override this method to indicate which classloading strategy to use. + * + * @return The strategy. + */ + public OsgiClassLoadingStrategyType classLoadingStrategy() { + return OsgiClassLoadingStrategyType.BUNDLE_DELEGATING; + } + + /** + * Exports the Ignite instance onto the OSGi Service Registry. + * + * @param ignite Ignite. + */ + private void exportOsgiService(Ignite ignite) { + Dictionary<String, String> dict = new Hashtable<>(); + + // Only add the service property if the grid name != null. + if (ignite.name() != null) + dict.put(OSGI_SERVICE_PROP_IGNITE_NAME, ignite.name()); + + bundleCtx.registerService(Ignite.class, ignite, dict); + + if (log.isInfoEnabled()) + log.info("Exported OSGi service for Ignite with properties: " + dict); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteOsgiUtils.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteOsgiUtils.java b/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteOsgiUtils.java new file mode 100644 index 0000000..deda3e8 --- /dev/null +++ b/modules/osgi/src/main/java/org/apache/ignite/osgi/IgniteOsgiUtils.java @@ -0,0 +1,69 @@ +/* + * 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.ignite.osgi; + +import java.util.Map; +import java.util.concurrent.ConcurrentMap; +import org.apache.ignite.Ignite; +import org.jsr166.ConcurrentHashMap8; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; + +/** + * Helper class for OSGi. + */ +public class IgniteOsgiUtils { + /** Whether we are running in an OSGi container. */ + private static boolean osgi = FrameworkUtil.getBundle(IgniteOsgiUtils.class) != null; + + /** Maps Ignite instances to the ClassLoaders of the bundles they were started from. */ + private static final ConcurrentMap<Ignite, ClassLoader> CLASSLOADERS = new ConcurrentHashMap8<>(); + + /** + * Private constructor. + */ + private IgniteOsgiUtils() { } + + /** + * Returns whether we are running in an OSGi environment. + * + * @return {@code true/false}. + */ + public static boolean isOsgi() { + return osgi; + } + + /** + * Returns a {@link Map} of {@link Ignite} instances and the classloaders of the {@link Bundle}s they were + * started from. + * + * @return The {@link Map}. + */ + protected static Map<Ignite, ClassLoader> classloaders() { + return CLASSLOADERS; + } + + /** + * Returns the number of grids currently running in this OSGi container. + * + * @return The grid count. + */ + public static int gridCount() { + return CLASSLOADERS.size(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/BundleDelegatingClassLoader.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/BundleDelegatingClassLoader.java b/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/BundleDelegatingClassLoader.java new file mode 100644 index 0000000..07c0682 --- /dev/null +++ b/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/BundleDelegatingClassLoader.java @@ -0,0 +1,147 @@ +/* + * 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.ignite.osgi.classloaders; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.osgi.framework.Bundle; + +/** + * A {@link ClassLoader} implementation delegating to a given OSGi bundle, and to the specified {@link ClassLoader} + * as a fallback. + */ +public class BundleDelegatingClassLoader extends ClassLoader { + /** The bundle which loaded Ignite. */ + protected final Bundle bundle; + + /** The fallback classloader, expected to be the ignite-core classloader. */ + @GridToStringExclude + protected final ClassLoader clsLdr; + + /** + * Constructor. + * + * @param bundle The bundle + */ + public BundleDelegatingClassLoader(Bundle bundle) { + this(bundle, null); + } + + /** + * Constructor. + * + * @param bundle The bundle. + * @param classLoader Fallback classloader. + */ + public BundleDelegatingClassLoader(Bundle bundle, ClassLoader classLoader) { + this.bundle = bundle; + this.clsLdr = classLoader; + } + + /** {@inheritDoc} */ + @Override protected Class<?> findClass(String name) throws ClassNotFoundException { + return bundle.loadClass(name); + } + + /** {@inheritDoc} */ + @Override protected URL findResource(String name) { + URL resource = bundle.getResource(name); + + if (resource == null && clsLdr != null) + resource = clsLdr.getResource(name); + + return resource; + } + + /** + * Finds a given resource from within the {@link #bundle}. + * + * @param name The resource name. + * @return URLs of resources. + * @throws IOException + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + protected Enumeration findResources(String name) throws IOException { + return bundle.getResources(name); + } + + /** + * Loads a class trying the {@link #bundle} first, falling back to the ClassLoader {@link #clsLdr}. + * + * @param name Class name. + * @param resolve {@code true} to resolve the class. + * @return The Class. + * @throws ClassNotFoundException + */ + @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + Class<?> cls; + + try { + cls = findClass(name); + } + catch (ClassNotFoundException e) { + if (clsLdr == null) + throw classNotFoundException(name); + + try { + cls = clsLdr.loadClass(name); + } + catch (ClassNotFoundException e2) { + throw classNotFoundException(name); + } + + } + + if (resolve) + resolveClass(cls); + + return cls; + } + + /** + * Returns the {@link Bundle} to which this ClassLoader is associated. + * + * @return The Bundle. + */ + public Bundle getBundle() { + return bundle; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(BundleDelegatingClassLoader.class, this); + } + + /** + * Builds a {@link ClassNotFoundException}. + * + * @param clsName Class name. + * @return The exception. + */ + protected ClassNotFoundException classNotFoundException(String clsName) { + String s = "Failed to resolve class [name=" + clsName + + ", bundleId=" + bundle.getBundleId() + + ", symbolicName=" + bundle.getSymbolicName() + + ", fallbackClsLdr=" + clsLdr + ']'; + + return new ClassNotFoundException(s); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/ContainerSweepClassLoader.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/ContainerSweepClassLoader.java b/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/ContainerSweepClassLoader.java new file mode 100644 index 0000000..e2e773a --- /dev/null +++ b/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/ContainerSweepClassLoader.java @@ -0,0 +1,134 @@ +/* + * 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.ignite.osgi.classloaders; + +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import org.apache.ignite.internal.util.GridConcurrentHashSet; +import org.jsr166.ConcurrentHashMap8; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; + +/** + * A {@link ClassLoader} implementation that first attempts to load the class from the associated {@link Bundle}. As + * a fallback, it sweeps the entire OSGi container to find the requested class, returning the first hit. + * <p> + * It keeps a cache of resolved classes and unresolvable classes, in order to optimize subsequent lookups. + */ +public class ContainerSweepClassLoader extends BundleDelegatingClassLoader { + /** Classes resolved previously. */ + private final ConcurrentMap<String, Bundle> resolved = new ConcurrentHashMap8<>(); + + /** Unresolvable classes. */ + private final Set<String> nonResolvable = new GridConcurrentHashSet<>(); + + /** + * Constructor with a {@link Bundle} only. + * + * @param bundle The bundle. + */ + public ContainerSweepClassLoader(Bundle bundle) { + super(bundle); + } + + /** + * Constructor with a {@link Bundle} and another {@link ClassLoader} to check. + * + * @param bundle The bundle. + * @param classLoader The other classloader to check. + */ + public ContainerSweepClassLoader(Bundle bundle, ClassLoader classLoader) { + super(bundle, classLoader); + } + + /** + * Runs the same logic to find the class as {@link BundleDelegatingClassLoader}, but if not found, sweeps the + * OSGi container to locate the first {@link Bundle} that can load the class, and uses it to do so. + * + * @param name The classname. + * @param resolve Whether to resolve the class or not. + * @return The loaded class. + * @throws ClassNotFoundException + */ + @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + // If we know it's not resolvable, throw the exception immediately. + if (nonResolvable.contains(name)) + throw classNotFoundException(name); + + Class<?> cls; + + // First, delegate to super, and return the class if found. + try { + cls = super.loadClass(name, resolve); + return cls; + } + catch (ClassNotFoundException e) { + // Continue. + } + + // Else, check the cache. + if (resolved.containsKey(name)) + return resolved.get(name).loadClass(name); + + // If still unresolved, sweep the container. + cls = sweepContainer(name); + + // If still unresolved, throw the exception. + if (cls == null) + throw classNotFoundException(name); + + return cls; + } + + /** + * Sweeps the OSGi container to find the first {@link Bundle} that can load the class. + * + * @param name The classname. + * @return The loaded class. + */ + protected Class<?> sweepContainer(String name) { + Class<?> cls = null; + + Bundle[] bundles = bundle.getBundleContext().getBundles(); + + int bundleIdx = 0; + + for (; bundleIdx < bundles.length; bundleIdx++) { + Bundle b = bundles[bundleIdx]; + + // Skip bundles that haven't reached RESOLVED state; skip fragments. + if (b.getState() <= Bundle.RESOLVED || b.getHeaders().get(Constants.FRAGMENT_HOST) != null) + continue; + + try { + cls = b.loadClass(name); + break; + } + catch (ClassNotFoundException e) { + // No-op. + } + } + + if (cls == null) + nonResolvable.add(name); + else + resolved.put(name, bundles[bundleIdx]); + + return cls; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/OsgiClassLoadingStrategyType.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/OsgiClassLoadingStrategyType.java b/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/OsgiClassLoadingStrategyType.java new file mode 100644 index 0000000..9afde42 --- /dev/null +++ b/modules/osgi/src/main/java/org/apache/ignite/osgi/classloaders/OsgiClassLoadingStrategyType.java @@ -0,0 +1,29 @@ +/* + * 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.ignite.osgi.classloaders; + +/** + * Enum for the user to indicate which type of {@link ClassLoader} Ignite should use. + */ +public enum OsgiClassLoadingStrategyType { + /** Use this value for {@link BundleDelegatingClassLoader}. */ + BUNDLE_DELEGATING, + + /** Use this value for {@link ContainerSweepClassLoader}. */ + CONTAINER_SWEEP +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/AbstractIgniteKarafTest.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/AbstractIgniteKarafTest.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/AbstractIgniteKarafTest.java new file mode 100644 index 0000000..786b543 --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/AbstractIgniteKarafTest.java @@ -0,0 +1,109 @@ +/* + * 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.ignite.osgi; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.inject.Inject; + +import org.apache.karaf.features.FeaturesService; + +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.karaf.options.LogLevelOption; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerMethod; +import org.osgi.framework.BundleContext; + +import static org.ops4j.pax.exam.CoreOptions.junitBundles; +import static org.ops4j.pax.exam.CoreOptions.maven; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.CoreOptions.options; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFileExtend; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; + +/** + * Abstract test class that sets up an Apache Karaf container with Ignite installed. + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerMethod.class) +public abstract class AbstractIgniteKarafTest { + /** Features we do not expect to be installed. */ + protected static final Set<String> IGNORED_FEATURES = new HashSet<>( + Arrays.asList("ignite-log4j", "ignite-scalar-2.10")); + + /** Regex matching ignite features. */ + protected static final String IGNITE_FEATURES_NAME_REGEX = "ignite.*"; + + /** Project version. */ + protected static final String PROJECT_VERSION = System.getProperty("projectVersion"); + + /** Pax Exam will inject the Bundle Context here. */ + @Inject + protected BundleContext bundleCtx; + + /** Pax Exam will inject the Karaf Features Service. */ + @Inject + protected FeaturesService featuresSvc; + + /** + * Base configuration for a Karaf container running the specified Ignite features. + * + * @return The configuration. + */ + public Option[] baseConfig() { + return options( + + // Specify which version of Karaf to use. + karafDistributionConfiguration() + .frameworkUrl(maven().groupId("org.apache.karaf").artifactId("apache-karaf").type("tar.gz") + .versionAsInProject()) + .karafVersion(System.getProperty("karafVersion")) + .useDeployFolder(false) + .unpackDirectory(new File("target/paxexam/unpack")), + + // Add JUnit bundles. + junitBundles(), + + // Add the additional JRE exports that Ignite requires. + editConfigurationFileExtend("etc/jre.properties", "jre-1.7", "sun.nio.ch"), + editConfigurationFileExtend("etc/jre.properties", "jre-1.8", "sun.nio.ch"), + + // Make log level INFO. + logLevel(LogLevelOption.LogLevel.INFO), + + // Add our features repository. + features(mavenBundle() + .groupId("org.apache.ignite").artifactId("ignite-osgi-karaf") + .version(System.getProperty("projectVersion")).type("xml/features"), + featuresToInstall().toArray(new String[0])), + + // Propagate the projectVersion system property. + systemProperty("projectVersion").value(System.getProperty("projectVersion")) + ); + } + + protected abstract List<String> featuresToInstall(); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteKarafFeaturesInstallationTest.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteKarafFeaturesInstallationTest.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteKarafFeaturesInstallationTest.java new file mode 100644 index 0000000..c0eb06b --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteKarafFeaturesInstallationTest.java @@ -0,0 +1,100 @@ +/* + * 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.ignite.osgi; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.apache.karaf.features.Feature; +import org.junit.Test; +import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.CoreOptions; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.karaf.options.KarafDistributionOption; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Pax Exam test class to check if all features could be resolved and installed. + */ +public class IgniteKarafFeaturesInstallationTest extends AbstractIgniteKarafTest { + /** Number of features expected to exist. */ + private static final int EXPECTED_FEATURES = 25; + + private static final String CAMEL_REPO_URI = "mvn:org.apache.camel.karaf/apache-camel/" + + System.getProperty("camelVersion") + "/xml/features"; + + /** + * Container configuration. + * + * @return The configuration. + */ + @Configuration + public Option[] config() { + List<Option> options = new ArrayList<>(Arrays.asList(baseConfig())); + + options.add(KarafDistributionOption.features(CAMEL_REPO_URI)); + + return CoreOptions.options(options.toArray(new Option[0])); + } + + /** + * @throws Exception + */ + @Test + public void testAllBundlesActiveAndFeaturesInstalled() throws Exception { + // Asssert all bundles except fragments are ACTIVE. + for (Bundle b : bundleCtx.getBundles()) { + System.out.println(String.format("Checking state of bundle [symbolicName=%s, state=%s]", + b.getSymbolicName(), b.getState())); + + if (b.getHeaders().get(Constants.FRAGMENT_HOST) == null) + assertTrue(b.getState() == Bundle.ACTIVE); + } + + // Check that according to the FeaturesService, all Ignite features except ignite-log4j are installed. + Feature[] features = featuresSvc.getFeatures(IGNITE_FEATURES_NAME_REGEX); + + assertNotNull(features); + assertEquals(EXPECTED_FEATURES, features.length); + + for (Feature f : features) { + if (IGNORED_FEATURES.contains(f.getName())) + continue; + + boolean installed = featuresSvc.isInstalled(f); + + System.out.println(String.format("Checking if feature is installed [featureName=%s, installed=%s]", + f.getName(), installed)); + + assertTrue(installed); + assertEquals(PROJECT_VERSION.replaceAll("-", "."), f.getVersion()); + } + } + + /** + * @return Features list. + */ + @Override protected List<String> featuresToInstall() { + return Arrays.asList("ignite-all"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiServiceTest.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiServiceTest.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiServiceTest.java new file mode 100644 index 0000000..9a2e92d --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiServiceTest.java @@ -0,0 +1,131 @@ +/* + * 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.ignite.osgi; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.inject.Inject; +import org.apache.ignite.Ignite; +import org.apache.ignite.osgi.activators.BasicIgniteTestActivator; +import org.apache.ignite.osgi.activators.TestOsgiFlags; +import org.apache.ignite.osgi.activators.TestOsgiFlagsImpl; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.CoreOptions; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.ProbeBuilder; +import org.ops4j.pax.exam.TestProbeBuilder; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerMethod; +import org.ops4j.pax.exam.util.Filter; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.ops4j.pax.exam.CoreOptions.streamBundle; +import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle; +import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd; + +/** + * Pax Exam test class to check whether the Ignite service is exposed properly and whether lifecycle callbacks + * are invoked. + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerMethod.class) +public class IgniteOsgiServiceTest extends AbstractIgniteKarafTest { + /** Injects the Ignite OSGi service. */ + @Inject @Filter("(ignite.name=testGrid)") + private Ignite ignite; + + @Inject + private BundleContext bundleCtx; + + /** + * @return Config. + */ + @Configuration + public Option[] bundleDelegatingConfig() { + List<Option> options = new ArrayList<>(Arrays.asList(baseConfig())); + + // Add bundles we require. + options.add( + streamBundle(bundle() + .add(BasicIgniteTestActivator.class) + .add(TestOsgiFlags.class) + .add(TestOsgiFlagsImpl.class) + .set(Constants.BUNDLE_SYMBOLICNAME, BasicIgniteTestActivator.class.getSimpleName()) + .set(Constants.BUNDLE_ACTIVATOR, BasicIgniteTestActivator.class.getName()) + .set(Constants.EXPORT_PACKAGE, "org.apache.ignite.osgi.activators") + .set(Constants.DYNAMICIMPORT_PACKAGE, "*") + .build(withBnd()))); + + // Uncomment this if you'd like to debug inside the container. + // options.add(KarafDistributionOption.debugConfiguration()); + + return CoreOptions.options(options.toArray(new Option[0])); + } + + /** + * Builds the probe. + * + * @param probe The probe builder. + * @return The probe builder. + */ + @ProbeBuilder + public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) { + probe.setHeader(Constants.IMPORT_PACKAGE, "*,org.apache.ignite.osgi.activators"); + + return probe; + } + + /** + * @throws Exception If failed. + */ + @Test + public void testServiceExposedAndCallbacksInvoked() throws Exception { + assertNotNull(ignite); + assertEquals("testGrid", ignite.name()); + + TestOsgiFlags flags = (TestOsgiFlags) bundleCtx.getService( + bundleCtx.getAllServiceReferences(TestOsgiFlags.class.getName(), null)[0]); + + assertNotNull(flags); + assertEquals(Boolean.TRUE, flags.getOnBeforeStartInvoked()); + assertEquals(Boolean.TRUE, flags.getOnAfterStartInvoked()); + + // The bundle is still not stopped, therefore these callbacks cannot be tested. + assertNull(flags.getOnBeforeStopInvoked()); + assertNull(flags.getOnAfterStopInvoked()); + + // No exceptions. + assertNull(flags.getOnAfterStartThrowable()); + assertNull(flags.getOnAfterStopThrowable()); + } + + /** + * @return Features. + */ + @Override protected List<String> featuresToInstall() { + return Arrays.asList("ignite-core"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiTestSuite.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiTestSuite.java new file mode 100644 index 0000000..0a3d69c --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/IgniteOsgiTestSuite.java @@ -0,0 +1,32 @@ +/* + * 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.ignite.osgi; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** + * Test suite for OSGi-related test cases. + * <p> + * NOTE: Have to use JUnit 4 annotations because Pax Exam is built on JUnit 4. + */ +@RunWith(Suite.class) +@Suite.SuiteClasses({IgniteOsgiServiceTest.class, IgniteKarafFeaturesInstallationTest.class}) +public class IgniteOsgiTestSuite { + // No-op. +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/BasicIgniteTestActivator.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/BasicIgniteTestActivator.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/BasicIgniteTestActivator.java new file mode 100644 index 0000000..c414092 --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/BasicIgniteTestActivator.java @@ -0,0 +1,76 @@ +/* + * 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.ignite.osgi.activators; + +import java.util.Hashtable; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.osgi.IgniteAbstractOsgiContextActivator; +import org.apache.ignite.osgi.classloaders.OsgiClassLoadingStrategyType; +import org.jetbrains.annotations.Nullable; +import org.osgi.framework.BundleContext; + +/** + * Basic Ignite Activator for testing. + */ +public class BasicIgniteTestActivator extends IgniteAbstractOsgiContextActivator { + /** Flags to report our state to a watcher. */ + private TestOsgiFlagsImpl flags = new TestOsgiFlagsImpl(); + + /** + * @return Ignite config. + */ + @Override public IgniteConfiguration igniteConfiguration() { + IgniteConfiguration config = new IgniteConfiguration(); + + config.setGridName("testGrid"); + + return config; + } + + /** + * @return Strategy. + */ + @Override public OsgiClassLoadingStrategyType classLoadingStrategy() { + return OsgiClassLoadingStrategyType.BUNDLE_DELEGATING; + } + + /** {@inheritDoc} */ + @Override protected void onBeforeStart(BundleContext ctx) { + flags.onBeforeStartInvoked = Boolean.TRUE; + + // Export the flags as an OSGi service. + ctx.registerService(TestOsgiFlags.class, flags, new Hashtable<String, Object>()); + } + + /** {@inheritDoc} */ + @Override protected void onAfterStart(BundleContext ctx, @Nullable Throwable t) { + flags.onAfterStartInvoked = Boolean.TRUE; + flags.onAfterStartThrowable = t; + } + + /** {@inheritDoc} */ + @Override protected void onBeforeStop(BundleContext ctx) { + flags.onBeforeStopInvoked = Boolean.TRUE; + } + + /** {@inheritDoc} */ + @Override protected void onAfterStop(BundleContext ctx, @Nullable Throwable t) { + flags.onAfterStopInvoked = Boolean.TRUE; + flags.onAfterStopThrowable = t; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlags.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlags.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlags.java new file mode 100644 index 0000000..09a2d29 --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlags.java @@ -0,0 +1,53 @@ +/* + * 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.ignite.osgi.activators; + +/** + * Interface to export the flags in OSGi. + */ +public interface TestOsgiFlags { + /** + * @return The flag. + */ + Boolean getOnBeforeStartInvoked(); + + /** + * @return The flag. + */ + Boolean getOnAfterStartInvoked(); + + /** + * @return The flag. + */ + Throwable getOnAfterStartThrowable(); + + /** + * @return The flag. + */ + Boolean getOnBeforeStopInvoked(); + + /** + * @return The flag. + */ + Boolean getOnAfterStopInvoked(); + + /** + * @return The flag. + */ + Throwable getOnAfterStopThrowable(); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlagsImpl.java ---------------------------------------------------------------------- diff --git a/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlagsImpl.java b/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlagsImpl.java new file mode 100644 index 0000000..ccec2df --- /dev/null +++ b/modules/osgi/src/test/java/org/apache/ignite/osgi/activators/TestOsgiFlagsImpl.java @@ -0,0 +1,83 @@ +/* + * 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.ignite.osgi.activators; + +/** + * Data transfer object representing flags we want to watch from the OSGi tests. + */ +public class TestOsgiFlagsImpl implements TestOsgiFlags { + /** onBeforeStartInvoked flag. */ + public Boolean onBeforeStartInvoked; + + /** onAfterStartInvoked flag. */ + public Boolean onAfterStartInvoked; + + /** onAfterStartThrowable flag. */ + public Throwable onAfterStartThrowable; + + /** onBeforeStartInvoked flag. */ + public Boolean onBeforeStopInvoked; + + /** onAfterStopInvoked flag. */ + public Boolean onAfterStopInvoked; + + /** onAfterStopThrowable flag. */ + public Throwable onAfterStopThrowable; + + /** + * @return The flag. + */ + @Override public Boolean getOnBeforeStartInvoked() { + return onBeforeStartInvoked; + } + + /** + * @return The flag. + */ + @Override public Boolean getOnAfterStartInvoked() { + return onAfterStartInvoked; + } + + /** + * @return The flag. + */ + @Override public Throwable getOnAfterStartThrowable() { + return onAfterStartThrowable; + } + + /** + * @return The flag. + */ + @Override public Boolean getOnBeforeStopInvoked() { + return onBeforeStopInvoked; + } + + /** + * @return The flag. + */ + @Override public Boolean getOnAfterStopInvoked() { + return onAfterStopInvoked; + } + + /** + * @return The flag. + */ + @Override public Throwable getOnAfterStopThrowable() { + return onAfterStopThrowable; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/rest-http/pom.xml ---------------------------------------------------------------------- diff --git a/modules/rest-http/pom.xml b/modules/rest-http/pom.xml index 3dc18d3..0780144 100644 --- a/modules/rest-http/pom.xml +++ b/modules/rest-http/pom.xml @@ -34,6 +34,13 @@ <version>1.5.0-b1-SNAPSHOT</version> <url>http://ignite.apache.org</url> + <properties> + <osgi.export.package> + org.apache.ignite.internal.processors.rest.protocols.http.jetty, + {local-packages} + </osgi.export.package> + </properties> + <dependencies> <dependency> <groupId>org.apache.ignite</groupId> @@ -44,13 +51,13 @@ <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> - <version>8.0.23</version> + <version>${tomcat.version}</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> - <version>2.6</version> + <version>${commons.lang.version}</version> </dependency> <dependency> @@ -92,38 +99,38 @@ <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> - <version>2.4</version> + <version>${jsonlib.version}</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>net.sf.ezmorph</groupId> <artifactId>ezmorph</artifactId> - <version>1.0.6</version> + <version>${ezmorph.version}</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> - <version>3.2.1</version> + <version>${commons.collections.version}</version> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> - <version>1.8.3</version> + <version>${commons.beanutils.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>1.7.7</version> + <version>${slf4j.version}</version> </dependency> <dependency> @@ -131,4 +138,15 @@ <artifactId>log4j</artifactId> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> + </build> + </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/scalar-2.10/pom.xml ---------------------------------------------------------------------- diff --git a/modules/scalar-2.10/pom.xml b/modules/scalar-2.10/pom.xml index 83e515b..9a958eb 100644 --- a/modules/scalar-2.10/pom.xml +++ b/modules/scalar-2.10/pom.xml @@ -44,7 +44,7 @@ <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> - <version>2.10.4</version> + <version>${scala210.library.version}</version> </dependency> <dependency> @@ -109,6 +109,12 @@ <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> </plugin> + + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> </plugins> <!-- TODO IGNITE-956 FIX scaladocs plugins--> @@ -194,5 +200,6 @@ <!--</executions>--> <!--</plugin>--> <!--</plugins>--> + </build> </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/scalar/pom.xml ---------------------------------------------------------------------- diff --git a/modules/scalar/pom.xml b/modules/scalar/pom.xml index e78ce73..301a103 100644 --- a/modules/scalar/pom.xml +++ b/modules/scalar/pom.xml @@ -44,7 +44,7 @@ <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> - <version>2.11.7</version> + <version>${scala211.library.version}</version> </dependency> <dependency> @@ -184,6 +184,13 @@ </execution> </executions> </plugin> + + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> </build> </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/schedule/pom.xml ---------------------------------------------------------------------- diff --git a/modules/schedule/pom.xml b/modules/schedule/pom.xml index 6e687a6..cb53713 100644 --- a/modules/schedule/pom.xml +++ b/modules/schedule/pom.xml @@ -34,6 +34,13 @@ <version>1.5.0-b1-SNAPSHOT</version> <url>http://ignite.apache.org</url> + <properties> + <osgi.export.package> + org.apache.ignite.internal.processors.schedule, + {local-packages} + </osgi.export.package> + </properties> + <dependencies> <dependency> <groupId>org.apache.ignite</groupId> @@ -44,7 +51,7 @@ <dependency> <groupId>it.sauronsoftware.cron4j</groupId> <artifactId>cron4j</artifactId> - <version>2.2.5</version> + <version>${cron4j.version}</version> </dependency> <dependency> @@ -75,4 +82,20 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this fragment. It is a fragment because it contains internal processors + that would be looked up by ignite-core. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Fragment-Host>org.apache.ignite.ignite-core</Fragment-Host> + </instructions> + </configuration> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/schema-import/pom.xml ---------------------------------------------------------------------- diff --git a/modules/schema-import/pom.xml b/modules/schema-import/pom.xml index 2fae337..36f6b13 100644 --- a/modules/schema-import/pom.xml +++ b/modules/schema-import/pom.xml @@ -44,7 +44,7 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>1.3.175</version> + <version>${h2.version}</version> <scope>test</scope> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/slf4j/pom.xml ---------------------------------------------------------------------- diff --git a/modules/slf4j/pom.xml b/modules/slf4j/pom.xml index 130ea19..1449549 100644 --- a/modules/slf4j/pom.xml +++ b/modules/slf4j/pom.xml @@ -44,7 +44,17 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.6.4</version> + <version>${slf4j.version}</version> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/spark-2.10/pom.xml ---------------------------------------------------------------------- diff --git a/modules/spark-2.10/pom.xml b/modules/spark-2.10/pom.xml index 627cc49..0b24898 100644 --- a/modules/spark-2.10/pom.xml +++ b/modules/spark-2.10/pom.xml @@ -52,7 +52,7 @@ <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> - <version>2.10.4</version> + <version>${scala210.library.version}</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/spring/pom.xml ---------------------------------------------------------------------- diff --git a/modules/spring/pom.xml b/modules/spring/pom.xml index 2e90632..1808a0a 100644 --- a/modules/spring/pom.xml +++ b/modules/spring/pom.xml @@ -106,7 +106,7 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>1.3.175</version> + <version>${h2.version}</version> <scope>test</scope> </dependency> @@ -118,11 +118,10 @@ <scope>test</scope> </dependency> - <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>1.3.175</version> + <version>${h2.version}</version> <scope>test</scope> </dependency> </dependencies> @@ -136,5 +135,30 @@ </excludes> </testResource> </testResources> + + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. + This bundle is a fragment attached to the ignite-core bundle, as it contains and exports classes in the org.apache.ignite + leading to a split package situation in OSGi. + --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Fragment-Host>org.apache.ignite.ignite-core</Fragment-Host> + <Require-Bundle> + org.apache.servicemix.bundles.spring-beans, + org.apache.servicemix.bundles.spring-context, + org.apache.servicemix.bundles.spring-context-support, + org.apache.servicemix.bundles.spring-core, + org.apache.servicemix.bundles.spring-expression, + org.apache.servicemix.bundles.spring-jdbc, + org.apache.servicemix.bundles.spring-tx + </Require-Bundle> + </instructions> + </configuration> + </plugin> + </plugins> </build> </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/ssh/pom.xml ---------------------------------------------------------------------- diff --git a/modules/ssh/pom.xml b/modules/ssh/pom.xml index 1079c00..e1b0fe5 100644 --- a/modules/ssh/pom.xml +++ b/modules/ssh/pom.xml @@ -44,7 +44,7 @@ <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> - <version>0.1.53</version> + <version>${jsch.version}</version> </dependency> <dependency> @@ -69,4 +69,21 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <!-- This is a fragment because it's an internal processor module. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Fragment-Host>org.apache.ignite.ignite-core</Fragment-Host> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/twitter/pom.xml ---------------------------------------------------------------------- diff --git a/modules/twitter/pom.xml b/modules/twitter/pom.xml index fc924f6..1649043 100644 --- a/modules/twitter/pom.xml +++ b/modules/twitter/pom.xml @@ -65,7 +65,7 @@ <dependency> <groupId>com.twitter</groupId> <artifactId>hbc-twitter4j</artifactId> - <version>2.2.0</version> + <version>${twitter.hbc.version}</version> </dependency> <dependency> @@ -118,4 +118,14 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> + </build> </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/urideploy/pom.xml ---------------------------------------------------------------------- diff --git a/modules/urideploy/pom.xml b/modules/urideploy/pom.xml index 5f2436e..37c77ba 100644 --- a/modules/urideploy/pom.xml +++ b/modules/urideploy/pom.xml @@ -80,19 +80,19 @@ <dependency> <groupId>net.sf.jtidy</groupId> <artifactId>jtidy</artifactId> - <version>r938</version> + <version>${jtidy.version}</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.6</version> + <version>${commons.codec.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> - <version>8.0.23</version> + <version>${tomcat.version}</version> <scope>test</scope> </dependency> @@ -145,4 +145,15 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> + </build> + </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/visor-console-2.10/pom.xml ---------------------------------------------------------------------- diff --git a/modules/visor-console-2.10/pom.xml b/modules/visor-console-2.10/pom.xml index 8d1bd74..87ce699 100644 --- a/modules/visor-console-2.10/pom.xml +++ b/modules/visor-console-2.10/pom.xml @@ -80,13 +80,13 @@ <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> - <version>2.10.4</version> + <version>${scala210.library.version}</version> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>jline</artifactId> - <version>2.10.4</version> + <version>${scala210.jline.version}</version> </dependency> <!-- Third party dependencies --> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/visor-console/pom.xml ---------------------------------------------------------------------- diff --git a/modules/visor-console/pom.xml b/modules/visor-console/pom.xml index 1ed21ae..d4fc6cf 100644 --- a/modules/visor-console/pom.xml +++ b/modules/visor-console/pom.xml @@ -80,7 +80,7 @@ <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> - <version>2.11.7</version> + <version>${scala211.library.version}</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/visor-plugins/pom.xml ---------------------------------------------------------------------- diff --git a/modules/visor-plugins/pom.xml b/modules/visor-plugins/pom.xml index 5cdda0c..7754a4b 100644 --- a/modules/visor-plugins/pom.xml +++ b/modules/visor-plugins/pom.xml @@ -53,13 +53,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>1.7.7</version> + <version>${slf4j.version}</version> </dependency> <!-- Third party dependencies --> </dependencies> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/web/pom.xml ---------------------------------------------------------------------- diff --git a/modules/web/pom.xml b/modules/web/pom.xml index c97e77b..d25ce61 100644 --- a/modules/web/pom.xml +++ b/modules/web/pom.xml @@ -44,7 +44,7 @@ <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> - <version>8.0.23</version> + <version>${tomcat.version}</version> </dependency> <dependency> @@ -89,4 +89,15 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> + </build> + </project> http://git-wip-us.apache.org/repos/asf/ignite/blob/96e08027/modules/zookeeper/pom.xml ---------------------------------------------------------------------- diff --git a/modules/zookeeper/pom.xml b/modules/zookeeper/pom.xml index 8aa5730..8ade247 100644 --- a/modules/zookeeper/pom.xml +++ b/modules/zookeeper/pom.xml @@ -34,10 +34,6 @@ <version>1.5.0-b1-SNAPSHOT</version> <url>http://ignite.apache.org</url> - <properties> - <curator.version>2.9.1</curator.version> - </properties> - <dependencies> <dependency> <groupId>org.apache.ignite</groupId> @@ -87,4 +83,14 @@ </dependency> </dependencies> + <build> + <plugins> + <!-- Generate the OSGi MANIFEST.MF for this bundle. --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + </plugins> + </build> + </project>