I am using component factory to create a multiple unique instances which in-turn uses services which is servicefactories to create multiple instance.
My structure looks like
TInterface - interface/service
TInterfaceInline - which implements TInterface also consists of #Reference for another service.
Tinterfaceimpl1 - extends TInterfaceInline which is a servicefactory with filter property.
TConsumer - component factory which consumes the TInterfaceInline
by getting it in #Reference.
TConsumer
#Component(name = "TConsumer", factory = "TConsumer")
#Service
public class TConsumer implements IConsumer {
// #Reference(bind = "bindInterface1", unbind = "unbindInterface1", target =
// "(className=Interface)")
// private Tinterface interface1;
#Reference(referenceInterface = ParentProfile.class, bind = "bindInterface11", unbind = "unbindInterface11", target = "(className=interface1)", policy = ReferencePolicy.STATIC, cardinality = ReferenceCardinality.MANDATORY_UNARY)
private ParentProfile interface11;
#Activate
public void activate(BundleContext aBundleContext) {
System.out.println("Object = " + interface11);
}
protected void bindInterface11(ParentProfile interface11) {
this.interface11 = interface11;
System.out.println("ref object11 created");
}
protected void unbindInterface11(ParentProfile interface11) {
interface11 = null;
}
TinterfaceImpl
#Component(name = "TInterfaceImol")
#Service(serviceFactory = true,value=ParentProfile.class)
#Properties(value = { #Property(name = "className", value = "interface1") })
public class Tinterfaceimpl1 extends TinterfaceInline {
public Tinterfaceimpl1() {
System.out.println("Generalprofile class : " + this);
}
}
TinterfaceInline
#Component(name = "TinterfaceInline ")
#Service
public class TinterfaceInline implements java.io.Serializable, ParentProfile {
// #Reference(bind = "bindtestin", unbind = "unbindtestin", cardinality =
// ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
public Testint testin;
protected synchronized void bindtestin(Testint inter) {
this.testin = inter;
System.out.println("Profile Class : binded parameterresolver " + testin);
}
protected synchronized void unbindtestin(Testint inter) {
this.testin = inter;
}
}
ParentClass
#Component(name = "PResolver")
#Service
public class ProfileClass implements Testint {
public ProfileImpl() {
System.out.println("Parameter class impl : which extends ");
}
}
Apart from this remaining things are marker interfaces. If i try to install in karaf , the state of the Tinterfaceimpl1 is REGISTERED. ie) i am using servicefactories and accessing service factories from component factory. Servicefactory class extends a class which implements Interface. What is the reason Tinterfaceimpl1 is REGISTERED.
Related
I am writing OSGI services .After Starting the service,I got Below Message.Kindly suggest to overcome this Issue.
#Component (service = Service.class, immediate = true)
public class ServiceImpl implements Service{
#Reference (name = "CounterService", policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.MANDATORY,
bind = "bindCounter", unbind = "unbindCounter", service = CounterService.class)
public static final AtomicReference<CounterService> myCounterService = new AtomicReference<>();
public void bindCService(CounterService counterService)
{
this.cacheService= cacheService;
}
public void unbindService(CounterService cacheService)
{
this.cacheService= null;
}
}
And i got this Message after Starting Service
-!MESSAGE [com.xxx.xxx.xxx.CounterImpl(29)] Field counterService in component class com.xxx.xxx.xxx.CounterImpl has unsupported type
java.util.concurrent.atomic.AtomicReference
Well, why the AtomicReference? You also don't need bind and unbind services. You seem confused :-) You might want to take a look at the videos or the OSGi starter
For the dynamic case, this is what would work:
#Component(immediate = true)
public class ServiceImpl implements Service {
#Reference
volatile CounterService myCounterService;
#Activate
void activate() {
...
}
}
If the CounterService is not dynamic, this is a very nice pattern:
#Component(immediate = true)
public class ServiceImpl implements Service {
final CounterService myCounterService;
#Activate
public ServiceImpl( #Reference CounterService c ) {
this.myCounterService = c;
}
}
I have a class annotated with #Component which is use to initialze application.yml config properties. Service classe is using configuration property. But sometime my Service class instance created before the Configuration class and I get null property value in service class, Its random not specific pattern.
Configuration Initializer class..
#Component
public class ConfigInitializer implements InitializingBean {
private static final Logger log = LoggerFactory.getLogger(ConfigInitializer.class);
#Autowired
ProxyConfig proxyConfig;
/*#PostConstruct
public void postConstruct(){
setProperties();
}
*/
#Override
public void afterPropertiesSet() {
setProperties();
}
private void setSystemProperties(){
log.debug("Setting properties...");
Properties props = new Properties();
props.put("PROXY_URL", proxyConfig.getProxyUrl());
props.put("PROXY_PORT", proxyConfig.getProxyPort());
System.getProperties().putAll(props);
}
}
#Component
#ConfigurationProperties(prefix = "proxy-config")
public static class ProxyConfig {
private String proxyUrl;
private String proxyPort;
public String getProxyUrl() {
return proxyUrl;
}
public void setProxyUrl(String proxyUrl) {
this.proxyUrl = proxyUrl;
}
public String getProxyPort() {
return proxyPort;
}
public void setProxyPort(String proxyPort) {
this.proxyPort = proxyPort;
}
}
Service Class..
#Service("receiverService")
public class ReceiverService {
private static final Logger logger = LoggerFactory.getLogger(ReceiverService.class);
private ExecutorService executorService = Executors.newSingleThreadExecutor();
#Autowired
public ReceiverService() {
initClient();
}
private void initClient() {
Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
String value = System.getProperty("PROXY_URL"); **//Here I am getting null**
logger.info("Values : " + value);
}
});
System.out.println("future.get() = " + future.get());
}
}
Above Service class get null values String value = System.getProperty("PROXY_URL")
When I use #DependsOn annotation on Service class, it works fine.
In my little knowledge, I know Spring does not have specific order of bean creation.
I want to know If I use #Configuration instead of #Component on ConfigInitializer class like below, Will spring initialize ConfigInitializer
class before other beans ?.
#Configuration
public class ConfigInitializer implements InitializingBean {
//code here
}
I'm trying to create annotations from inner string which contains other annotations.
This is SimpleAnnotation that should be processed:
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.SOURCE)
public #interface SimpleAnnotation {
String[] value() default {};
}
This is annotated class
#SimpleAnnotation({
"#com.demo.annotations.Entity(name = \"simple_name\")",
"#com.demo.annotations.CustomAnnotation"
})
public class Simple {
}
The compilation result of annotated class should be
#com.demo.annotations.Entity(name = "simple_name")
#com.demo.annotations.CustomAnnotation
public class Simple {
}
I've tried to use custom annotation processor
that processes class declaration. It gets class modifiers with annotations and analyzes derived annotation as tree
public class SimpleAnnotationProcessor extends AbstractProcessor {
private Messager messager;
private Trees trees;
private ChangeTranslator visitor;
#Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton(SimpleAnnotation.class.getCanonicalName());
}
#Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.RELEASE_8;
}
#Override
public synchronized void init(ProcessingEnvironment processingEnv) {
............
}
#Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elementsAnnotatedWith = roundEnv.getElementsAnnotatedWith(SimpleAnnotation.class);
for (Element element : elementsAnnotatedWith) {
Name simpleName = element.getSimpleName();
System.out.println(simpleName);
messager.printMessage(Diagnostic.Kind.NOTE, "found with annotation " + simpleName);
JCTree tree = (JCTree) trees.getTree(element);
visitor.setElement(element);
tree.accept(visitor);
}
return true;
}
public class ChangeTranslator extends TreeTranslator {
private JavacProcessingEnvironment javacProcessingEnvironment;
private TreeMaker treeMaker;
private Messager messager;
public ChangeTranslator(JavacProcessingEnvironment javacProcessingEnvironment, TreeMaker treeMaker, Messager messager) {
this.javacProcessingEnvironment = javacProcessingEnvironment;
this.treeMaker = treeMaker;
this.messager = messager;
}
#Override
public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
super.visitClassDef(jcClassDecl);
if (isNeedProcessing(jcClassDecl)) {
JCTree.JCModifiers modifiers = jcClassDecl.getModifiers();
List<JCTree.JCAnnotation> annotations = modifiers.getAnnotations();
List<JCTree.JCAnnotation> jcAnnotations = List.nil();
for (JCTree.JCAnnotation a : annotations) {
if (a.getAnnotationType().toString().contains(SimpleAnnotation.class.getSimpleName())) {
List<JCTree.JCExpression> arguments = a.getArguments();
for (JCTree.JCExpression arg : arguments) {
JCTree.JCNewArray expressions = (JCTree.JCNewArray) ((JCTree.JCAssign) arg).getExpression();
List<JCTree.JCExpression> elems = expressions.elems;
for (JCTree.JCExpression expression : elems) {
// parse annotation from string
String value = (String) ((JCTree.JCLiteral) expression).getValue();
// e.g com.demo.annotations.Entity
String substringName = value.trim().substring(1, 28);
Class<? extends Class> aClass = null;
try {
aClass = Class.forName(substringName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 1 - attribute to create annotation from
Attribute attribute = new Attribute.Compound(aClass, null);
// 2 - place where annotation should be created
treeMaker.Annotation(attribute);
}
}
}
}
modifiers.annotations = jcAnnotations;
System.out.println(result);
}
}
private boolean isNeedProcessing(JCTree.JCClassDecl jcClassDecl) {
return jcClassDecl.getModifiers().toString().contains("#SimpleAnnotation");
}
}
}
The issue is to get information from Class type to create com.sun.tools.javac.code.Type.ClassType which is used to create JCAnnotation.
Any help is appreciated.
public class SimpleAnnotationProcessor extends AbstractProcessor {
...
#Override
public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
...
ListBuffer<JCTree.JCExpression> params = new ListBuffer<JCTree.JCExpression>();
params.append(treeMaker.Assign(treeMaker.Ident(names.fromString("name")), treeMaker.Literal("simple_name")));
JCTree.JCAnnotation entity = treeMaker.Annotation(select("com.demo.annotations.Entity"), params.toList());
JCTree.JCAnnotation customAnnotation = treeMaker.Annotation(select("com.demo.annotations.CustomAnnotation"), List.nil());
// then append annotation to modifiers of you want
// NOTE: List<A>.append() method will return a new List in javac
...
}
JCTree.JCExpression select(String path) {
JCTree.JCExpression expression = null;
int i = 0;
for (String split : path.split("\\.")) {
if (i == 0)
expression = treeMaker.Ident(names.fromString(split));
else {
expression = treeMaker.Select(expression, names.fromString(split));
}
i++;
}
return expression;
}
}
Hope it helps those who have the same problem
Let's say we have interface:
public interface IAuthentication { }
and two implementations:
public class LdapAuthentication implements IAuthentication {}
public class DbAuthentication implements IAuthentication {}
And finally we have a bean that is responsible for processing authentication. This bean should use one of the implementations shown above (based on configuration specified in for example db).
#Service
public class AuthenticationService {
public boolean authenticate(...) {
boolean useDb = ...; //got from db
//my problem here
//how to get right implementation: either LdapAuthentication or DbAuthentication?
IAuthentication auth = ...;
return auth.authenticate(...);
}
}
Question:
How to get the right implementation?
If parameter value does not change:
#Service
public class AuthenticationService {
private IAuthentication auth;
#PostConstruct
protected void init() {
boolean useDb = ...; //got from db
this.auth = ...; //choose correct one
}
public boolean authenticate(...) {
return auth.authenticate(...);
}
}
If parameter is dynamic
#Service
public class AuthenticationService {
#Autowired
private ApplicationContext сontext;
public boolean authenticate(...) {
boolean useDb = ...; //got from db
IAuthentication auth = context.getBean(useDb ? DbAuthentication.class : LdapAuthentication.class);
return auth.authenticate(...);
}
}
I am looking for a design pattern / solution for the following problem, that is related to the Observer pattern, I have already studied.
In my code I have a MyModel class. It has many properties.
public class MyModel {
private List<Flower> flowers = new ArrayList<Flower>();
private List<Toys> toys = new ArrayList<Toys>();
private List<Coffee> coffees = new ArrayList<Coffee>();
private List<IBusinessEntityListener> listener =
new ArrayList<IBusinessEntityListener>();
public void addChangeListener(IBusinessEntityListener newListener) {
listener.add(newListener);
}
}
So classes that implement IBusinessEntityListener can register to MyModel class.
Then I have 10+ listeners that are interested only in some properties of MyModel. They all implement IBusinessEntityListener. But how can I specify (for example with Java Generics?) that some listener are only interested in Flowers, some only about Toys, etc.?
So How to design such class structure that would support listening to certain properties?
All listeners would anyway implement 3 methods for the operations add, update and delete.
How about an application of the Extrinsic Visitor pattern?
Define an interface for properties:
public interface ListenableProperty {
// Degenerate interface for listeners
public interface Listener {}
public void acceptUpdate(Listener listener);
}
Then implement a class for each property, and a Listener interface for each property, and use like so from your model:
public class MyModel {
public static class FlowersProperty implements ListenableProperty {
public interface Listener extends ListenableProperty.Listener {
public void update(FlowersProperty p);
}
#Override
public void acceptUpdate(ListenableProperty.Listener listener) {
if (listener instanceof FlowersProperty.Listener) {
Listener myListenerType = (Listener)listener;
myListenerType.update(this);
}
}
// some property accessors here
}
public static class ToysProperty implements ListenableProperty {
public interface Listener extends ListenableProperty.Listener {
public void update(ToysProperty p);
}
#Override
public void acceptUpdate(ListenableProperty.Listener listener) {
if (listener instanceof ToysProperty.Listener) {
Listener myListenerType = (Listener)listener;
myListenerType.update(this);
}
}
// some property accessors here
}
private FlowersProperty flowers = new FlowersProperty();
private ToysProperty toys = new ToysProperty();
private List<ListenableProperty> properties = new ArrayList();
// CopyOnWrite so that listeners can remove themselves during update if desired
private List<ListenableProperty.Listener> listeners =
new CopyOnWriteArrayList<>();
// Convenience interface for implementors that want all properties
public interface AllPropertiesListener extends
FlowersProperty.Listener,
ToysProperty.Listener
{}
public MyModel() {
properties.add(flowers);
properties.add(toys);
}
public void addListener(ListenableProperty.Listener l) {
if (!listeners.contains(l)) {
listeners.add(l);
}
}
private void updateAll() {
for (ListenableProperty p : properties) {
for (ListenableProperty.Listener l : listeners) {
p.acceptUpdate(l);
}
}
}
private void updateToys() {
for (ListenableProperty.Listener l : listeners) {
toys.acceptUpdate(l);
}
}
private void updateFlowers() {
for (ListenableProperty.Listener l : listeners) {
flowers.acceptUpdate(l);
}
}
}
Listeners can then implement as many or as few of the listener interfaces as they please, or all of them via the convenience interface MyModel.AllPropertiesListener
You could also move the update routines for individual properties to the properties themselves.
for any type of Listeners have a class :
FlowerListerner implemts IBusinessEntityListener;
ToyListerner implemts IBusinessEntityListener;
and a listener list:
public class MyModel {
private List<Flower> flowers = new ArrayList<Flower>();
private List<Toys> toys = new ArrayList<Toys>();
private List<IBusinessEntityListener> flowerListeners =
new ArrayList<IBusinessEntityListener>();
private List<IBusinessEntityListener> toyListeners =
new ArrayList<IBusinessEntityListener>();
public void addListener(IBusinessEntityListener newListener) {
if(newListener instance of FlowerListener)
flowerListeners.add(newListener);
else if (newListener instance of ToyListener)
} toyListeners.add(newListener);
updateFlowerListeners() { ....}
updateToyListeners() { ....}
}
and any changes to each property reflect to related listeners.
UPDATE
another solution is that u have a list of interest in Listener Object:
Class Listener {
private List<Class> interests;
public Listener(List<Class> interests) {
this.interests = interests;
}
public boolean isInterested(Class clazz) {
return list.contains(clazz);
}
public void update() { ... }
}
an in model :
public class MyModel {
private List<Flower> flowers = new ArrayList<Flower>();
private List<Toys> toys = new ArrayList<Toys>();
private List<Listener> listeners =
new ArrayList<Listener>();
public void addListener(Listener newListener) {
listeners.add(newListener);
}
updateFlowerListeners() {
for(Listener l : listerners) {
if(l.isInterested(Flower.class)
l.update();
}
updateToyListeners() { ... }
}