I'm trying to develop onto Karaf an OSGi WAB containing a REST API and a call from a custom-made service. However, for some weird reason, the OSGi framework complains about an unsatisfied capability, osgi.component.
I would like to know:
How can I solve this issue?
What is osgi.component bundle? Why is needed?
Why maven-bundle-plugin (thereby also bnd), declares it inside the entry "Require-Capability"?
If I need to install it on the OSGi framework, where may I find it?
Some additional information:
karaf version: 4.0.7;
maven bundle plugin: 3.2.0;
OS: Windows 10 64bit;
IDE: Eclipse Neon;
Some code to provide additional info:
The whole error:
Error executing command: Error executing command on bundles:
Error starting bundle 96: Unable to resolve com.massimobono.karaf.examples.user-fully-rest [96](R 96.0): missing
requirement [com.massimobono.karaf.examples.user-fully-rest [96](R
96.0)] osgi.extender; (&(osgi.extender=osgi.component)(version>=1.3.0)(!(version>=2.0.0)))
Unresolved requirements:
[[com.massimobono.karaf.examples.user-fully-rest [96](R 96.0)]
osgi.extender;
(&(osgi.extender=osgi.component)(version>=1.3.0)(!(version>=2.0.0)))]
Manifest file:
Manifest-Version: 1.0
Bundle-SymbolicName: com.massimobono.karaf.examples.user-fully-rest
Archiver-Version: Plexus Archiver
Built-By: massi
Bnd-LastModified: 1479908575162
Bundle-ActivationPolicy: lazy
Bundle-ManifestVersion: 2
Import-Package: com.massimobono.karaf.examples.user;version="[0.0,1)",
com.massimobono.karaf.examples.user.service;version="[0.0,1)",javax.w
s.rs;version="[2.0,3)",javax.ws.rs.core;version="[2.0,3)"
Require-Capability: osgi.extender;filter:="(&(osgi.extender=osgi.compo
nent)(version>=1.3.0)(!(version>=2.0.0)))",osgi.service;filter:="(obj
ectClass=com.massimobono.karaf.examples.user.service.UserService)";ef
fective:=active,osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Service-Component: OSGI-INF/com.massimobono.karaf.examples.user.ui.ful
lyrest.UserRest.xml
Tool: Bnd-3.2.0.201605172007
Originally-Created-By: Maven Integration for Eclipse
Export-Package: com.massimobono.karaf.examples.user.ui.fullyrest;uses:
="javax.ws.rs,javax.ws.rs.core";version="0.0.1"
Bundle-Name: user-fully-rest Maven Webapp
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Build-Jdk: 1.8.0_91
Rest base class:
package com.massimobono.karaf.examples.user.ui.fullyrest;
import java.time.LocalDateTime;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import com.massimobono.karaf.examples.user.User;
import com.massimobono.karaf.examples.user.service.UserService;
import com.massimobono.karaf.examples.user.service.UserServiceException;
#Path("user")
#Component(immediate=true)
public class UserRest {
#Reference
private volatile UserService userService;
#GET
#Produces(MediaType.TEXT_HTML)
public String getUserNumber() {
try {
return String.format("<h1>Total users: %d</h1>", this.userService.size());
} catch (UserServiceException e) {
return String.format("Couldn't fetch total users because %s", e.getMessage());
}
}
#PUT
#Path("add/{name}/{surname}")
#Produces(MediaType.TEXT_HTML)
public String add(#PathParam("name") String name, #PathParam("surname") String surname) {
try {
User u = new User(name, surname, LocalDateTime.now());
this.userService.addUser(u);
return String.format("<h1>New user with id %d</h1>", u.getId());
} catch (UserServiceException e) {
return String.format("<h1>Couldn't fethc total users because %s</h1>", e.getMessage());
}
}
#DELETE
#Path("remove/{id}")
#Produces(MediaType.TEXT_HTML)
public String remove(#PathParam("id") int id) {
User u;
try {
u = this.userService.getUser(id);
this.userService.removeUser(u);
return String.format("<h1>User name=%s surname=%s removed correctly</h1>", u.getName(), u.getSurname());
} catch (UserServiceException e) {
return String.format("<h1>Couldn't remove user because %s</h1>", e.getMessage());
}
}
}
Thanks for any kind reply
How can I solve this issue?
Most likely you are missing SCR in your Karaf runtime. You can install it with feature:install scr
What is osgi.component bundle? Why is needed?
It's not a bundle but a requirement. Basically it says your bundle needs SCR (or something) that knows how to process and register the components defined in it via Declarative Services.
Why maven-bundle-plugin (thereby also bnd), declares it inside the entry "Require-Capability"?
Because it sees that you are using Declarative Services and knows they will not work unless you have something at runtime that understands how they are declared and knows how to manage their lifecycle. If the requirement was not there (which I believe was the case with earlier versions of bnd) then your bundle would start without issues but services would still be not registered / activated.
If I need to install it on the OSGi framework, where may I find it?
In Karaf it's available as feature (see the answer to your first question). In plain OSGi runtime (Felix, Equinox, ...) you need to install it manually. It's available in Maven central.
I had the same issue and in my case I was using to recent version of maven-bundle-plugin (4.x). After I downgraded the version (3.x) the issue disappeared.
Looks like the 3.x version of the plugin generates osgi.extender=osgi.component Require-Capability that my OSGi container can provide.
Related
I am working on this tutorial using Spring Tool Suites.
I've copied what it says and my code and pom look the same (copied for easy review)
package com.javatpoint.spring_boot_example_sts;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringBootExampleSts
{
public static void main(String[] args){
SpringApplication.run(SpringBootExampleSts.class, args);
}
}
My issue is that I am getting a red line under ' org.springframework.boot.SpringApplication. To my knowledge, this library is not deprecated and I can't seem to find any instance of it being moved.
Thanks in advance.
May be maven either maven dependency is not downloaded or your IDE has some issues.
You can try to restart your IDE.
If issue still persist, Please build using mvn clean package.
When running XACML-PAP-ADMIN and XACML-PAP-REST on Windows 10. Java jdk1.8.0_144. I get next error:
Error scanning entry META-INF/versions/9/module-info.class from jar file:///D:/Projects/XACML/XACML-PAP-ADMIN/target/xacml-pap-admin-2.0.0-SNAPSHOT/WEB-INF/lib/log4j-api-2.11.0.jar
That could be linked to your version of Jetty, considering it fails on log4j 2.11 jar.
See this question:
log4j 2.9 and later are multi-release jars for Java 9.
Make sure to use a Jetty compatible with that, or use slf4j instead.
You can create a custom DevMode JettyLauncher:
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.shell.jetty.JettyLauncher;
import org.eclipse.jetty.webapp.WebAppContext;
import java.io.File;
public class DevModeJettyLauncher extends JettyLauncher {
#Override
protected WebAppContext createWebAppContext(TreeLogger logger, File appRootDir) {
WebAppContext webAppContext = super.createWebAppContext(logger, appRootDir);
webAppContext.setAttribute("org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern", "none");//this is just a regex that matches nothing
return webAppContext;
}
}
And then configure it when launching.
Dev Mode Parameters: -server <package>.DevModeJettyLauncher
I have a generally understanding Problem with the Maven-Dependency in Grails 2.3.8.
I want to Import jsoup - functionality into my Project.
Therefore I did this in my BuildConfig.groovy:
dependencies {
.
.
/// jsoup
compile "org.jsoup:jsoup:1.7.3"
}
All is okay. Grails downloads the jar File into my local repo
C:\Users\xxx\.m2\repository\org\jsoup\jsoup\1.7.3
Now my confusion. I thougt all is done and i can write my code against Jsoup but this is wrong. I have to
copy the jar file into the Grails - lib Folder
set up the buildpath for Jsoup.jar
do a "grails compile"
Is this the right way? Why do i config dependencies when grails doesnt use them? It seems there is a plugin (compile ":html-cleaner:0.2") where Jsoup is included but when i need Jsoup i use Jsoup and not html-cleaner.
When i did this without my steps i got an Compiler Error:
package f
import grails.transaction.Transactional
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document
/***
*
* #author MG
*
*/
//#Transactional
class xyService {
def getXyFromIndex(String searchKeyword) {
def html = ""
Document doc = Jsoup.parse(html);
}
}
==> 'Groovy:unable to resolve class org.jsoup.nodes.Document' -GGTS 3.5.1
You don't need to copy jar it should automatically get copied either by ivy or maven. Maven is recommended so in BuildConfig.groovy change the resolver value to maven like below. Now when you start your application all jar will get copied to .m2 directory.
grails.project.dependency.resolver = "maven"
Did you try to import JSoup at the top of your file ?
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.select.Elements
import org.jsoup.parser.Tag
#Transactional
class myClass {
}
I have an OSGI bundle (awesome.test) that calls code from a jar file (testlibrary.jar). I have included the bundle as a Liberty feature (awesome.test.feature) and I have it installed on a WebSphere Application Server Liberty Profile V8.5.5. I also have an OSGI bundle (awesometest) that is a part of an OSGI application (awesometest.app) and it has an Activator class.
Here is a picture of my workspace setup
What I want to do is call methods in testlibrary.jar through methods in awesome.test, which includes testlibrary.jar in its build path. My awesome.test.feature is available to any applicaions running on my Liberty server. I want my applications to be able to use that feature to gain access to the functionality in testlibrary.jar through what I provide in awesome.test. I don't want OSGI applications to directly import packages from testlibrary.jar.
The following error appears in the binary logs when I run the application on the server:
CWWKZ0402E: A bundle exception was generated when trying to install the application awesometest.app into an OSGi framework. The error text from the OSGi framework is: Exception in awesometest.Activator.start() of bundle awesometest.
Debugging the problem finds that this exception is thrown:
java.lang.ClassNotFoundException: testlibrary.test.TestAPI
Source from TestLibraryRunner.java in awesome.test:
package awesome.test;
import testlibrary.test.TestAPI;
public class TestLibraryRunner {
public static void runNonLibTest() {
System.out.println("No Library code is being called");
}
public static void runLibTest() {
TestAPI ta = new TestAPI("This is a message.");
ta.display();
}
}
Note that runNonLibTest() will work when called from the OSGI application. Calling the TestAPI code in runLibTest from the OSGI application will cause the error above.
Source from Activator.java in awesometest:
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
System.out.println("Starting...");
TestLibraryRunner.runNonLibTest();
TestLibraryRunner.runLibTest();
System.out.println("Finishing...");
}
public void stop(BundleContext context) throws Exception {
System.out.println("Stopping...");
}
}
Source from MANIFEST.MF in awesometest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: awesometest
Bundle-SymbolicName: awesometest
Bundle-Version: 1.0.0
Bundle-Activator: awesometest.Activator
Import-Package: awesome.test,
org.osgi.framework
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: awesometest
In summary, my OSGI application cannot touch code from the jar in the build path of the bundle included in my Liberty feature. Is there something fundamental I'm missing here? Is what I'm trying to do even possible?
Thanks
Having had the same runtime exceptions in my educational project, the simplest solution I have found is to add the used JARs under Runtime - Classpath of the imported bundle (in your case awesome.test).
I hope this late answer helps someone else.
You use the package testlibrary.test but you do not import it. You should add that package to the Import-Package statement of the bundle.
It looks like the problem is in the packaging of awesome.test. The awesometest bundle (application bundle) can find your feature code fine, but then problems occur in the feature bundle. Have you confirmed that testlibrary.jar is packaged within awesome.test (feature bundle) and that the manifest of awesome.test includes the embedded jar?
You'll also need to list your exported feature packages in your feature manifest using the IBM-API-Package header, but I assume you've already done that or your application bundle activator wouldn't be able to see the feature bundle's TestLibraryRunner.
The problem with my project was that I was not including the testlibrary.jar correctly. While it was in the build path of awesome.test, it wasn't being included with the OSGI feature bundle.
There are two possible solutions:
1.) In Eclipse, go to File > Import and choose OSGi > Java Archive into an OSGi Bundle and create a new bundle. This will put the jar in its own bundle and then awesome.test can import the packages it needs from that new bundle.
2.) In Eclipse, go to File > Import and choose OSGi > Java Archive into an OSGi Bundle and include it in an existing bundle. This has the same effect as making the jar its own bundle, but it's less modular. The advantage of this approach is that you can not export the packages from the jar and just export your own interfaces.
There is also the BND Tool. It can help automate a lot of this process. I haven't used it myself.
Using Helios, spring 3.0.5 (TestContext Framework) and JUnit 4.7. I am getting an initialization error indicating that it cannot find the ContextConfiguration. I ran ProcMon in the background and determined it is not apparently looking at all. I have tried the logical locations for the xml file to no avail. I am unclear of what I am doing incorrectly. Here is the code:
package com.hwcs.veri.agg.dao;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import com.hwcs.veri.jpa.License;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "/JpaIntegrationTests-context.xml" })
#TransactionConfiguration( transactionManager = "transactionManager",
defaultRollback = true )
#Transactional
public class JpaIntegrationTests
extends AbstractTransactionalJUnit4SpringContextTests
{
#Autowired
protected LicenseDao licenseDao;
#Test
public void getLicenses()
{
List<License> licenses = this.licenseDao.getLicenses();
assertEquals( "Expecting 1 license from the query",
super.countRowsInTable( "product_schema.license" ),
licenses.size() );
}
}
Is there some particular step that needs to be done to run this as a JUnit test inside Eclipse?
First and foremost, set the log level for org.springframework.test.context to DEBUG. That should tell you everything that the Spring TestContext Framework (TCF) is doing.
Note that with your above configuration, the TCF will attempt to load your application context from classpath:/JpaIntegrationTests-context.xml (i.e., in the root of your classpath). So make sure that the JpaIntegrationTests-context.xml file in fact exists in the root of the classpath (e.g., /src/test/resources/JpaIntegrationTests-context.xml for a Maven project layout). For the Maven project layout, you need to make sure that /src/test/resources is configured as a source folder in your IDE.
If this doesn't help you solve your problem, post the DEBUG output from the log.
Regards,
Sam (author of the Spring TestContext Framework)
Quoting Java Project: Failed to load ApplicationContext
"From the Sping-Documentation: A plain path, for example "context.xml", will be treated as a classpath resource from the same package in which the test class is defined. A path starting with a slash is treated as a fully qualified classpath location, for example "/org/example/config.xml".