Expand my Community achievements bar.

Radically easy to access on brand approved content for distribution and omnichannel performant delivery. AEM Assets Content Hub and Dynamic Media with OpenAPI capabilities is now GA.
SOLVED

unsatisfied service

Avatar

Former Community Member

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.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

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

View solution in original post

8 Replies

Avatar

Level 10

Hi,

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

Like in your code I see  @Reference Name1 varname;

~Ratna.

Avatar

Level 10

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.

Avatar

Correct answer by
Community Advisor

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

Avatar

Former Community Member

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.

Avatar

Level 10

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 ...

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

Avatar

Community Advisor

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,

Avatar

Former Community Member

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.

Avatar

Employee Advisor

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

@Reference Name1 varname;

Jörg