Esta conversación ha sido bloqueada debido a la inactividad. Cree una nueva publicación.
Nivel 1
Nivel 2
Iniciar sesión en la comunidad
Iniciar sesión para ver todas las insignias
Esta conversación ha sido bloqueada debido a la inactividad. Cree una nueva publicación.
Hi There,
We have a scenario in which we need to create an reference of class B in a class A and Class A in class B. We need to know whether there is any solution to this as we are getting "service unsatisfied" and a sling exception is thrown by the service.
Example:
class A{ @reference class B } and class B { @reference class A}
Please provide your suggestions and let us know if our approach is correct or not. Thanks in advance.
Regards,
Ravi
¡Resuelto! Ir a solución.
Los temas ayudan a categorizar el contenido de la comunidad e incrementan la posibilidad de encontrar contenido relevante.
Vistas
Respuestas
Total de me gusta
Add on to @Jörg_Hoh,
You can try inheriting the implementation class(ClassA or ClassB) along side implementing the interface. Check the below example.
ServiceOne
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(service=ServiceOne.class)
public class ServiceOneImpl implements ServiceOne {
@Reference
ServiceTwo serviceTwo;
@Override
public String methodOne() {
return "{\"ServiceOne\": \"methodOne\"}";
}
@Override
public String reuseMethodTwo() {
return serviceTwo.methodTwo();
}
}
ServiceTwo
import org.osgi.service.component.annotations.Component;
@Component(service=ServiceTwo.class)
public class ServiceTwoImpl extends ServiceOneImpl implements ServiceTwo {
@Override
public String methodTwo() {
return "{\"ServiceTwo\": \"methodTwo\"}";
}
@Override
public String reuseMethodOne() {
return super.methodOne();
}
}
I am using a Servlet to invoke the ServiceTwo, which is internally calling ServiceOne method.
Servlet
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.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(service=Servlet.class, property={
"sling.servlet.methods=" + "GET",
"sling.servlet.paths="+ "/bin/test-servlet"
})
public class TestServlet extends SlingAllMethodsServlet{
private static final long serialVersionUID = 1L;
@Reference
ServiceOne serviceOne;
@Reference
ServiceTwo serviceTwo;
@Override
public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
response.setContentType("application/json");
try {
response.getWriter().print(serviceOne.methodOne());
response.getWriter().print(serviceOne.reuseMethodTwo());
response.getWriter().print(serviceTwo.methodTwo());
response.getWriter().print(serviceTwo.reuseMethodOne());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
{"ServiceOne": "methodOne"}{"ServiceTwo": "methodTwo"}{"ServiceTwo": "methodTwo"}{"ServiceOne": "methodOne"}
Vistas
Respuestas
Total de me gusta
This is a conflict which the system cannot handle itself. But in many cases it is also a sign of a bad application design.
I see 2 options:
1) Make a reference optional and deal with this optionality in the application code. Just make sure that the optional reference is greedy, so it's getting satisfied as soon as the reference target is available.
2) Redesign your services so you don't have this circular dependency anymore. Most likely the creation of a third service C makes sense, which both A and B can depend on.
Vistas
Respuestas
Total de me gusta
Vistas
Respuestas
Total de me gusta
instead of a regular "@Reference" annotation you use "@Reference(policy=ReferencePolicy.DYNAMIC,policyOption=ReferencePolicyOption.GREEDY,cardinality=ReferenceCardinality.OPTIONAL)"
(I am using the OSGI annotations here)
When you have that in place, this annotated variable can be NULL, and your code should be able to deal with it. The comprehensive documentation for it is https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html
Vistas
Respuestas
Total de me gusta
Add on to @Jörg_Hoh,
You can try inheriting the implementation class(ClassA or ClassB) along side implementing the interface. Check the below example.
ServiceOne
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(service=ServiceOne.class)
public class ServiceOneImpl implements ServiceOne {
@Reference
ServiceTwo serviceTwo;
@Override
public String methodOne() {
return "{\"ServiceOne\": \"methodOne\"}";
}
@Override
public String reuseMethodTwo() {
return serviceTwo.methodTwo();
}
}
ServiceTwo
import org.osgi.service.component.annotations.Component;
@Component(service=ServiceTwo.class)
public class ServiceTwoImpl extends ServiceOneImpl implements ServiceTwo {
@Override
public String methodTwo() {
return "{\"ServiceTwo\": \"methodTwo\"}";
}
@Override
public String reuseMethodOne() {
return super.methodOne();
}
}
I am using a Servlet to invoke the ServiceTwo, which is internally calling ServiceOne method.
Servlet
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.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(service=Servlet.class, property={
"sling.servlet.methods=" + "GET",
"sling.servlet.paths="+ "/bin/test-servlet"
})
public class TestServlet extends SlingAllMethodsServlet{
private static final long serialVersionUID = 1L;
@Reference
ServiceOne serviceOne;
@Reference
ServiceTwo serviceTwo;
@Override
public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
response.setContentType("application/json");
try {
response.getWriter().print(serviceOne.methodOne());
response.getWriter().print(serviceOne.reuseMethodTwo());
response.getWriter().print(serviceTwo.methodTwo());
response.getWriter().print(serviceTwo.reuseMethodOne());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
{"ServiceOne": "methodOne"}{"ServiceTwo": "methodTwo"}{"ServiceTwo": "methodTwo"}{"ServiceOne": "methodOne"}
Vistas
Respuestas
Total de me gusta
Vistas
me gusta
Respuestas
Vistas
me gusta
Respuestas
Vistas
me gusta
Respuestas