Expand my Community achievements bar.

SOLVED

Unsatisfied (reference) error for a POJO class

Avatar

Level 5

I have a Json response from SAP eCommerce. And for that I created a POJO class to map the keys and its values. Now when I'm referencing it into my servlet, I'm getting Unsatisfied (reference) error in system/console/components for that particular Reference. 

goyalkritika_0-1675912789198.png

Can anyone provide clarity on why this is happening?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @goyalkritika ,

Few things to be considered here as below

  • @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 eCommerceResponse is properly initialized as a service and is available in the Felix console as a service. 

  • Just in case - You should reference the service interface, not the service implementation.

Hope that helps!

Regards,

Santosh

View solution in original post

3 Replies

Avatar

Community Advisor

@goyalkritika Can you please post your servlet code here. 

I see that, you are trying to invoke the Sling model from the sling servlet. 

Thanks,
Siva

Avatar

Correct answer by
Community Advisor

Hi @goyalkritika ,

Few things to be considered here as below

  • @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 eCommerceResponse is properly initialized as a service and is available in the Felix console as a service. 

  • Just in case - You should reference the service interface, not the service implementation.

Hope that helps!

Regards,

Santosh

Avatar

Employee Advisor

I think you have referenced EcommerceResponse in your servlet using @reference annotation and EcommerceResponse is a POJO class right?

 

We use @Reference  annotation to inject OSGi service. As EcommerceResponse is not an OSGi service and  EcommerceResponse is not available in OSGi Service Registry that's why you are getting unsatisfied here.

 

 

Sharing one example here -

 

Employee is a POJO class here -

/**
 * 
 */
package com.aem.demo.core.models;

/**
 * @author debal
 *
 *         This Employee POJO represents entity Employee
 */
public class Employee {

	private String firstName;
	private String lastName;
	private String designation;

	/**
	 * @Param firstName
	 * @Param lastName
	 * @Param designation
	 */
	public Employee(String firstName, String lastName, String designation) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.designation = designation;
	}

	/**
	 * @Return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @Param firstName the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @Return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @Param lastName the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @Return the designation
	 */
	public String getDesignation() {
		return designation;
	}

	/**
	 * @Param designation the designation to set
	 */
	public void setDesignation(String designation) {
		this.designation = designation;
	}

}

Interface -

/**
 * 
 */
package com.aem.demo.core.services;

import com.aem.demo.core.models.Employee;

/**
 * @author debal
 * 
 *         This service is responsible to store Employee From Data into AEM
 *         repository
 *
 */
public interface WriteEmployeeData {

	public void storeEmployeeData(Employee employee);

}

Service Impl -

/**
 * 
 */
package com.aem.demo.core.services.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;
import com.aem.demo.core.models.Employee;
import com.aem.demo.core.services.WriteEmployeeData;
import com.drew.lang.annotations.NotNull;
import com.drew.lang.annotations.Nullable;

/**
 * @author debal
 * 
 *         This implementation class is responsible to store Employee form data
 *         into AEM repository Employee information will be persisted in terms
 *         of node and property as user generated content
 */
@Component(service = WriteEmployeeData.class, immediate = true)
public class WriteEmployeeDataImpl implements WriteEmployeeData {

	private final Logger logger = LoggerFactory.getLogger(WriteEmployeeDataImpl.class);

	@Reference
	ResourceResolverFactory resourceResolverFactory;

	Map<String, Object> map = new HashMap<String, Object>();

	@Override
	public void storeEmployeeData(Employee employee) {

		String uniqueID = UUID.randomUUID().toString();
		ResourceResolver resourceResolver = getResourceResolver();
		@Nullable
		Resource resource = resourceResolver.getResource("/content/usergenerated/formdata");

		if (Objects.nonNull(resource)) {
			map.put("firstName", employee.getFirstName());
			map.put("lastName", employee.getLastName());
			map.put("designation", employee.getDesignation());
			try {
				@NotNull
				Resource employeeData = resourceResolver.create(resource, uniqueID, map);
				logger.info(" Resource Name {}", employeeData.getName());

				resourceResolver.commit();

			} catch (PersistenceException pe) {
				logger.error("Unable to save Employee details {} ", pe.getMessage());

			} finally {
				if (Objects.nonNull(resourceResolver)) {
					resourceResolver.close();
				}

			}

		}

	}

	private ResourceResolver getResourceResolver() {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(resourceResolverFactory.SUBSERVICE, "readWriteService");
		ResourceResolver serviceResourceResolver = null;
		try {

			serviceResourceResolver = resourceResolverFactory.getServiceResourceResolver(map);
		} catch (LoginException e) {
			logger.error("Could not get service user [ {} ]", "demoSystemUser", e.getMessage());
		}
		return serviceResourceResolver;

	}

}

 

 

Now I have used Employee class in my sling servlet here -

/**
 * 
 */
package com.aem.demo.core.servlets;

import java.io.IOException;

import javax.servlet.Servlet;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.demo.core.models.Employee;
import com.aem.demo.core.services.WriteEmployeeData;
import com.google.common.base.Strings;

/**
 * @author debal This servlet will be invoked during Employee Form submission
 *
 */

@Component(service = Servlet.class, property = { "sling.servlet.paths=" + "/bin/employeeForm",
		"sling.servlet.methods=" + HttpConstants.METHOD_POST })
public class EmployeeFormServlet extends SlingAllMethodsServlet {
	private final Logger logger = LoggerFactory.getLogger(EmployeeFormServlet.class);

	/**
	 * 
	 */
	@Reference
	WriteEmployeeData writeEmploeeData;

	private static final long serialVersionUID = -3743088247910006615L;

	protected void doPost(SlingHttpServletRequest slingHttpServletRequest,
			SlingHttpServletResponse slingHttpServletResponse) {

		String employeeFname = slingHttpServletRequest.getParameter("fname");
		String employeelname = slingHttpServletRequest.getParameter("lname");
		String employeeDesignation = slingHttpServletRequest.getParameter("designation");

		logger.info("**** Employee First Name ***** {}", employeeFname);

		logger.info("**** Employee Last Name ***** {}", employeelname);
		logger.info("**** Employee Designation ***** {}", employeeDesignation);

		if (!Strings.isNullOrEmpty(employeeFname) && !Strings.isNullOrEmpty(employeelname)
				&& !Strings.isNullOrEmpty(employeeDesignation)) {

			Employee employee = new Employee(employeeFname, employeelname, employeeDesignation);
			writeEmploeeData.storeEmployeeData(employee);
			try {
				slingHttpServletResponse.sendRedirect("/content/demo/us/en/reports.html");

			} catch (IOException e) {
				logger.error(" Unable to submit Form {}", e.getMessage());

			}

		}

	}
}

Please focus on Employee part only.

Hope this will help.