unsatisfied service | Community
Skip to main content
September 29, 2017
Solved

unsatisfied service

  • September 29, 2017
  • 8 replies
  • 8246 views

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.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by VeenaVikraman

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

8 replies

Ratna_Kumar
Level 10
September 29, 2017

Hi,

May I know which service you are trying to inject to.

Like in your code I see  @Reference Name1 varname;

~Ratna.

smacdonald2008
Level 10
September 29, 2017

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.

VeenaVikraman
Community Advisor
VeenaVikramanCommunity AdvisorAccepted solution
Community Advisor
September 29, 2017

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

September 29, 2017

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.

smacdonald2008
Level 10
September 29, 2017

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.

Scott's Digital Community: Injecting a DataSourcePool Service into an Adobe Experience Manager OSGi bundle

Hope this clears up how to use dependency injection in AEM.

VeenaVikraman
Community Advisor
Community Advisor
September 29, 2017

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,

September 30, 2017

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.

joerghoh
Adobe Employee
Adobe Employee
September 30, 2017

You should reference the service interface, not the service implementation.

@Reference Name1 varname;

Jörg