Lastly, I was facing interview coding question, when I realized for one use case, it was throwing "Stack Overflow Error", looking at the input I figure out that problem is linked to circular dependency.
Let me briefly walk you towards the scenarios with very simple details:
We have service which has two method:
Service class that has 2 method
public class Service{
private List<String> list=new ArrayList<String>();
private Service proxyService;
private String serviceName;
public Service(String name){
servicename=name;
}
public void register(Service s){
this.proxyService=s;
}
public void add(String st){
if(proxyService!=null){
proxyService.add(st);
}
list.add(st);
}
public void print(){
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
Now, there is a use case as shown below:
Service s1=new Service("s1");
Service s2=new Service("s2");
s1.register(s2);
s2.register(s1);
s1.add("Test");
s2.add("Test2")
s1.print();
The above use case will lead to circular dependency and the error snippet as shown below:
Exception in thread "main" java.lang.StackOverflowError
at xx.Service.add(Service.java:18)
at xx.Service.add(Servicejava:22)
at xx.Service.add(Service.java:22)
Let me briefly walk you towards the scenarios with very simple details:
We have service which has two method:
Service class that has 2 method
- register: In this method, we will register a new service let say proxy service.
- add: In this method, we will add an element to a List and will also call add method of proxy Service if any.
public class Service{
private List<String> list=new ArrayList<String>();
private Service proxyService;
private String serviceName;
public Service(String name){
servicename=name;
}
public void register(Service s){
this.proxyService=s;
}
public void add(String st){
if(proxyService!=null){
proxyService.add(st);
}
list.add(st);
}
public void print(){
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
Now, there is a use case as shown below:
Service s1=new Service("s1");
Service s2=new Service("s2");
s1.register(s2);
s2.register(s1);
s1.add("Test");
s2.add("Test2")
s1.print();
The above use case will lead to circular dependency and the error snippet as shown below:
Exception in thread "main" java.lang.StackOverflowError
at xx.Service.add(Service.java:18)
at xx.Service.add(Servicejava:22)
at xx.Service.add(Service.java:22)
Now, I tried lot of work around but nothing worked perfectly, when I resolve it with static ArrayList code as shown below:
public class Service{
private List<String> list=new ArrayList<String>();
private Service proxyService;
private String serviceName;
static List<String> isVisited = new ArrayList<String>();
public Service(String name){
servicename=name;
}
public void register(Service s){
this.proxyService=s;
}
public void add(String st){
if(!isVisited.contains(serviceName)) {
proxyService.add(st);
isVisited.clear();
}
list.add(st);
}
Now, the same above use case will print:
Service s1=new Service("s1");
Service s2=new Service("s2");
s1.register(s2);
s2.register(s1);
s1.add("Test");
s2.add("Test1);
s1.print();
Will print the output:
Test
Test1
I know my solution won't work for multi-thread approach and we need to change former design altogether for production. But, it worked pretty well for single thread environment.
I hope you are able to follow my post, if you have any better solution, please write it down in comments, I will incorporate it in my post.
private List<String> list=new ArrayList<String>();
private Service proxyService;
private String serviceName;
static List<String> isVisited = new ArrayList<String>();
public Service(String name){
servicename=name;
}
public void register(Service s){
this.proxyService=s;
}
public void add(String st){
if(!isVisited.contains(serviceName)) {
isVisited.add(serviceName);if(proxyService!=null){
proxyService.add(st);
isVisited.clear();
}
list.add(st);
}
}
public void print(){
}for(int i=0;i<list.size();i++){System.out.println(list.get(i));}
Now, the same above use case will print:
Service s1=new Service("s1");
Service s2=new Service("s2");
s1.register(s2);
s2.register(s1);
s1.add("Test");
s2.add("Test1);
s1.print();
Will print the output:
Test
Test1
I know my solution won't work for multi-thread approach and we need to change former design altogether for production. But, it worked pretty well for single thread environment.
I hope you are able to follow my post, if you have any better solution, please write it down in comments, I will incorporate it in my post.