Hi,
The below is my customised servlet :
@SuppressWarnings("serial")
@SlingServlet(paths="/services/trialServlet",methods="GET")
public class trialServlet extends SlingAllMethodsServlet {
@Reference Name1 varname;
@Override
protected void doGet(SlingHttpServletRequest request,SlingHttpServletResponse response)throws ServletException,IOException
{
String test;
test=request.getParameter("name");
try {
response.getWriter().write("test");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException
{
varname.setName("teju");
String n=varname.getName();
response.getWriter().write(n);
/*String test;
test=request.getParameter("name");*/
try {
response.getWriter().write(n);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I'm checking in the bundle, I'm getting Component #2994 com.myTectra.workflowstep.trialServlet, state unsatisfied (reference).
Please let me know why this is happening and what is the solution for it.
Solved! Go to Solution.
Hi Pooja
@reference should be used to refer a service. If any @reference annotation is not able to pick the correct service , bundle will throw unsatisfied service error. Please check if Name1 is properly initialized as a service and is available in the Felix console as a service. Let me know if you need any more information around this .
Thanks
Veena
Hi,
May I know which service you are trying to inject to.
Like in your code I see @Reference Name1 varname;
~Ratna.
Views
Replies
Total Likes
Looks like you are trying to inject a data type that does not exist in the OSGi Service layer. You have to ensure that any service you inject - it must be available.
Hi Pooja
@reference should be used to refer a service. If any @reference annotation is not able to pick the correct service , bundle will throw unsatisfied service error. Please check if Name1 is properly initialized as a service and is available in the Felix console as a service. Let me know if you need any more information around this .
Thanks
Veena
I'm using @Reference to inject the service Name1. Here's the interface Name1:
public interface Name1 {
String getName();
void setName(String name);
}
Please let me know if this initialisation is right.
Views
Replies
Total Likes
You cannot do that!
In OSGi, an interface is used to create a custom Service that has an implementation class.
See this Article - a very basic example --
Scott's Digital Community: Creating your first AEM Service using an Adobe Maven Archetype project
For example - we have an interface named keyService
public
interface
KeyService {
public
void
setKey(
int
val);
public
String getKey();
}
Then we have an implementation class named KeyServiceImpl
that uses @Component and @Service:
import
com.adobe.cq.KeyService;
import
org.apache.felix.scr.annotations.Component;
import
org.apache.felix.scr.annotations.Service;
//This is a component so it can provide or consume services
@Component
@Service
public
class
KeyServiceImpl
implements
KeyService {
//Define a class member named key
private
int
key =
0
;
@Override
//A basic setter method that sets key
public
void
setKey(
int
val)
{
//Set the key class member
this
.key = val ;
}
@Override
//A basic getter that gets key
public
String getKey()
{
//return the value of the key class member
//Convert the int to a String to display it within an AEM web page
String strI = Integer.toString(
this
.key);
return
strI;
}
}
Now we have a custom service in AEM named keyService (when the OSGi bundle is deployed and in an Active State).
You can inject this keyService into another AEM service using @Reference. (note that if you are using HTL WCMUSEPOJO - you cannot use @REference)
For example - assume we have keyService2
public
interface
KeyService2 {
public
void
setKey(
int
val);
public
String getKey();
}
The following example shows an implementation class that injects KeyService into it using @Reference.
import
com.adobe.cq.KeyService2; // implem interface
import
com.adobe.cq.KeyService; //used for dep inject
import
org.apache.felix.scr.annotations.Component;
import
org.apache.felix.scr.annotations.Service;
@Reference
public KeyService myKey
//This is a component so it can provide or consume services
@Component
@Service
public
class
KeyServiceImpl2
implements
KeyService2 {
//Define a class member named key
private
int
key =
0
;
@Override
//A basic setter method that sets key
public
void
setKey(
int
val)
{
//Set the key class member
this
.key = val ;
}
@Override
//A basic getter that gets key
public
String getKey()
{
//return the value of the key class member
//Convert the int to a String to display it within an AEM web page
String strI = Integer.toString(
this
.key);
return
strI;
}
}
This is how dependency injection works in AEM. You can only inject an all ready running service using @Reference.
See this article - we inject a DataSourcePool Service into a custom service to work with a relational database.
Hope this clears up how to use dependency injection in AEM.
Please write a service which implements this interface as scott has explained below and then you can use the same snippet you wer using to refer the service,
Views
Replies
Total Likes
I have written an implementation class as below:
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
@Component(metatype=true)
@Service
public class Name1Impl implements Name1 {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
}
And changed my existing class according:
public class trialServlet extends SlingAllMethodsServlet {
@Reference Name1Impl varname;
@Override
protected void doGet(SlingHttpServletRequest request,SlingHttpServletResponse response)throws ServletException,IOException
{
String test;
test=request.getParameter("name");
try {
response.getWriter().write("test");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void doPost(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException
{
varname.setName("teju");
String n=varname.getName();
response.getWriter().write(n);
/*String test;
test=request.getParameter("name");*/
try {
response.getWriter().write(n);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now I see that in the console:
Component #3022 com.myTectra.serviceImpl.Name1Impl, state satisfied
and my class still unsatisfied.
Views
Replies
Total Likes
You should reference the service interface, not the service implementation.
@Reference Name1 varname;
Jörg
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies