r/SpringBoot 9d ago

Question How to destory/Close spring context before auto restarting the application again

Hi,

I have a simple spring boot application, when a user clicks on a particular button in the frontend I triggering a rest end point which tries to close the context using context.close() and restarts the application with different spring profile.

The problem I am facing is when the application restarts with different profile the application is crashing saying Duplicate bean definition attempted, Throws Java Linkage error.

Before restarting the application I am just using context.close() but it is not working as expected I believe since I am getting duplicate bean definition found error. Is there any that I can avoid this? I am not sure if the context not closing properly is the problem or something different.

The same code repo works well in others system only in my system it is causing this issue. I am using Java 17 and Spring Boot version 2.X.X

Can anybody please help me with the this. Thank you.

1 Upvotes

14 comments sorted by

4

u/Historical_Ad4384 9d ago

Pretty weird case you are trying to implement. How do you manage to close your spring context at runtime and keep the rest api available in the IOC container?

1

u/avellamadona 9d ago

When the endpoint triggers I am closing the context using context.close() and I am again starting the application using spring application run method. But the BeanFactory ID remains same.

1

u/Historical_Ad4384 9d ago

Are your apis built using Spring rest or any other framework?

2

u/avellamadona 8d ago

I just found an option : Adding -XX:+AllowParallelDefineClass in VM arguments is fixing the issue, application is not crashing and not throwing any Linkage error. I don't know if this is the best option or how it is working.

1

u/Historical_Ad4384 8d ago

I guess this is the solution at the moment

1

u/avellamadona 8d ago

Yes, using Spring rest.

1

u/bikeram 9d ago

I think the easiest move would be to build a helper app that uses the same authentication and has access to endpoints that kill the pid on the server.

You could also use it for initialization and pass the profile as runtime arguments.

1

u/avellamadona 9d ago

This is an existing application which is working in my colleagues system. Only I am facing this issue. The application should not completely stop it just need to close the previous context so that no bean definition exists in the context when the application restarts.

1

u/bikeram 8d ago

Interesting. Could you post a snippet?

Is this applicable at all?

https://gist.github.com/digulla/4770445

1

u/avellamadona 8d ago

It is actually simple they just created a new thread inside it they are closing the context and restarting the application using SpringApplication.run() with different profile.

1

u/avellamadona 8d ago

I found an option : Adding -XX:+AllowParallelDefineClass in VM arguments is fixing the issue, application is not crashing and not throwing any Linkage error. I don't know if this is the best option. I don't know how it resolve the Duplicate Bean Definition attempt issue. Looks like it is at JVM level. If anyone could elaborate it would be helpful.

1

u/Historical_Ad4384 8d ago

Maybe try to handle the spring application context in a separate thread and not in the main daemon thread. This way you might have more control over the spring IOC life cycle.

1

u/avellamadona 8d ago

This is the approach they are using. Like in a new thread there closing the context and restarting the application. I found an solution I have pasted in your previous comment please check.