Reputation: 2053
I'm a complete newb at this so I apologize in advance. I'm trying to create an OSGi component that simply shows a hello world message and is configurable via the input from felix. Then spits it out on a jsp page. I'm using scr annotations to help do this. Here is my java code
package com.training.cq5.trainingApp;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.apache.sling.commons.osgi.PropertiesUtil;
@Component(label= "Welcome Message",
description = "Welcome Message for the training excercise",
immediate = true, enabled = true, metatype=true)
@Properties({
@Property(name = "welcome.message", value = "WelcomeMessage")
})
@Service(WelcomeMessage.class)
public class WelcomeMessage {
private static String welcome_message = "Welcome";
@Activate
protected void activate(ComponentContext ctx) {
welcome_message = PropertiesUtil.toString(ctx.getProperties().get(welcome_message), welcome_message);
}
public static String getMessage() {
return welcome_message;
}
}
Here is were I am calling it in the JSP:
<%@ page import="com.training.cq5.trainingApp.WelcomeMessage" %>
<h2><%= WelcomeMessage.getMessage() %></h2>
Is there any reason why it's not updating from felix? All I'm getting is the "Welcome" text from the welcome_message string.
Upvotes: 3
Views: 5615
Reputation: 99
Change this line:-
welcome_message = PropertiesUtil.toString(ctx.getProperties().get(welcome_message), welcome_message);
to
welcome_message = PropertiesUtil.toString(ctx.getProperties().get("welcome.message"), welcome_message);
notice the difference :-ctx.getProperties().get(welcome_message) vs ctx.getProperties().get("welcome.message")
Upvotes: 0
Reputation: 1763
You are accessing WelcomeMessage.getMessage() as a static method, but what you want is the actual service. When you annotate a class with the @Service and @Component annotation, you indicate to the OSGI framework that you want an instance of this class registered as a service. This service instance is managed by the OSGI framework, in terms of its lifecycle (when its instantiated) or through which classloader the appropriate classes are loaded.
However in order to use the @Component and @Service annotations, you'll have to use the Apache Felix SCR plugin. Once that works, your service will be instantiated.
Then you'll have to access the service. The easiest way in Sling, which you appear to be using, is SlingScriptHelper.getService() which lets you lookup a service.
Update
In OSGI services are registered by their type. When you declare a service with @Service(MyClass.class), the service will be registered under the type MyClass. To retrieve it you would query the service registry for a service of the given type. In Java code you'd be using either getServiceReference(Class clazz)/getService(ServiceReference reference) the @Reference annotation.
In a JSP on a Sling system you can use the SlingScriptHelper, as outlined earlier. Here's a short code sample (assuming correct imports):
<%
SlingBindings bindings = (SlingBindings) req.getAttribute(SlingBindings.class.getName());
SlingScriptHelper scriptHelper = bindings.getSling();
MyService service = scriptHelper.getService(MyService.class);
// ... do stuff with service.
%>
If you are going to work more with OSGI, I highly recommend the OSGI specification. It's free to download and explains everything in great detail.
Upvotes: 6
Reputation: 6100
ilikeorangutans is correct that you don't want a static method on your OSGi service - the idea is that a service implements an interface, clients retrieve it from their OSGi context and use it via its service interface.
The Apache Sling webloader sample uses this technique to access a Webloader service in its request processing scripts. The scripts are ESP in this case (server-side javascript) but the principle is exactly the same with JSP.
The service interface is defined in Webloader.java, and WebLoaderImpl.java implements it as an OSGi service.
Then, the html.esp script gets the service using sling.getService:
var loader = sling.getService(Packages.org.apache.sling.samples.webloader.Webloader);
Upvotes: 2