https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java
shows
RegistrationPolicy.FAIL_ON_EXISTING
being set.
We are using spring boot created WARs in a standalone tcserver.
New deployments occur before old versions are un-deployed so you can have multiple versions deployed.
I am already using
spring.jmx.default-domain=[app name]
to avoid clashes across apps...but
We are seeing errors like
UnableToRegisterMBeanException: Unable to register MBean with key 'dataSourceMBean'
nested exception is javax.management.InstanceAlreadyExistsException
for our datasource Mbean across different version of the same app.
I would like to set a
RegistrationPolicy.IGNORE_EXISTING
as per http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jmx.html#jmx-exporting-registration-behavior.
Can I do this easily while maintaining the ObjectNamingStrategy and defaultDomain? Although not at all difficult, I am hoping I don't have to pretty much override all of JmxAutoConfiguration?
shame there is not a
spring.jmx.mbeanExporter.registrationPolicy
spring boot property
Cheers
Although this question was asked some time ago and maybe you have already found the answer, I will give my 2 cents here once I faced this problem and found a solution that worked for me.
Initially it was not completely clear what I needed to do, but when carefully reading the same spring documentation you provided in your question I figured out you can control the registration behavior on SpringBoot by introducing the class annotation
#EnableMBeanExport(registration=RegistrationPolicy.IGNORE_EXISTING)
to allow Spring ignore a second JMX registration if the MBean was already registered, as can be seen at the spring documentation here
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Spring boot is not adopted in our organisation.
The disadvantages cited are bloated jars, less control and flexibility.
I have tried to investigate above points but so far they dont seem valid.
bloated jars - The spring blog states that a simple web server
can be launched with 10 MB of heap.
less control and flexibility - Netflix uses spring
boot.Moreover,when I did some poc's, I didnt face flexibility issues.
I wanted to know if there are any mistakes in assesment.
1)Any examples on the loss of control/flexibility will be helpfull.
2)What are the anti patterns we need to be aware so the bloated jars issue dosent happen.
It is often a question of concern and responsability. With Spring boot, the developper team has full control of the deployed environment, including the servlet container configuration. And the production team has nothing to tweak.
Without Spring boot, the developper team has only control over the web application. And the production can/has to tweak the servlet container configuration. When you have a large number of different web apps, it can make sense to let the knowledge on that part only in the production team. In that case, you would not use Spring boot.
On the other end, if the hosting is externalized, Spring boot allows to give a full package.
So both approaches can be used but they target different organizations.
Bloated Jars - I think this can be fixed by properly maintaining the jars using a build tool like maven (But, yes there are some instances where you may need to add a lot of jars just because spring needs it)
Less control and flexiblity - I think this is usually with control freaks who want to control each and every piece of code they write. If you are okay with what spring provides already, this shouldn't be an issue.
I believe that the biggest disadvantage that you might encounter using spring is using it without understanding what value it might add to your project.
It might be completely not aligned with your requirements and it is possible that you will configure everything by yourself at some point, when you think, you should not have started with spring itself.
Ask your self a few questions,
You can create standalone java application? Why Spring at the first place? What value it adds to your project?
Spring has embedded tomcat, jetty, so no need to build a war. But, what if you have to build war anyway? Little config will do the trick but it's not any major advantage. Also, when you start it as a java service, what happens to your service if somehow the java process got killed?
What if you have many legacy spring modules? What if you need to patch it up? This will increase the jar count as well as legacy classes count. Are you sure want to convert this into a spring-boot application?
What if spring autoconfig configuration is not aligning with your requirements
And, I myself used spring-boot for a few of our production applications, which are mostly standalone REST API services and, haven't faced any issues with it.
Some best practices will be,
Use spring-boot mostly for microservices instead of a single complete (MVC) web application (I always use it to build the standalone REST API and build the UI with ReactJS and NodeJS).
Build your spring-boot app as a docker image and deploy using some kubernates cluster (kubernates will take care of failed docker containers and deploying to new containers) for maximum uptime.
Always keep only the jars required by your project and remove unwanted jars.
Any examples on the loss of control/flexibility will be helpfull.
You need familiarity on the life cycle of a bean in a Spring Boot application. Not knowing this might hinder your experience in spring boot. This will force you to structure your beans to prevent circular dependencies and other problems.
In Spring Security, configuring your other login methods is not really that intuitive.
In Spring Data JPA, repo classes requires you to name the methods in a specific way to perform queries. Locking/releasing data rows is also not straightforward.
etc...
What are the anti patterns we need to be aware so the bloated jars issue dosent happen.
Review the dependency tree of your jars. Make sure to add dependencies only in the modules they are needed. Also, remove dependencies you don't need.
Is there a way to implement schema multi tenancy in dropwizard?
The only solution I've found so far is https://github.com/flipkart-incubator/dropwizard-multitenancy but that is using descriminator multi tenancy.
We basically had the same problem. We wanted to support multi-tenancy, but not only on database level. Different customers have certain services configured differently. In order to avoid passing through the tenancyId everywhere, we came up with a custom scope using Guice. This way, every service that is #TenancyScoped can get its own predefined configuration or simply the tenancyId in its constructor. Then your DAOs can use different schemas based on the tenancyId.
It works quite well for us, even though it might not properly scale if you have too many (maybe > 1000, really depends how complex your configuration is) tenants.
I have posted the details about Guice and custom scopes here: Multi tenancy with Guice Custom Scopes and Jersey.
I had the same problem and I created a multitenant hibernate bundle by modifying the current hibernate bundle code. If you still have the requirement you can check it out.
Here is the link: https://github.com/uditnarayan/dropwizard-hibernate-multitenant/
I am starting to learn Spring and came across a feature of Spring - overriding spring bean declared in one xml config in another config.
I do not understand where this feature can be useful. It seems illogical because same container will be configured using two different xmls and even when there are two beans with same ID, instead of reporting the ambiguity it is defaulting to the last one.
Is there a practical scenario where this can actually be useful? Is this good practice?
There are reasons why this could be useful for instance
Testing
Developing Component Libraries
Testing
When testing you can choose to override 1 or more beans. For instance a DataSource you probably don't want to test against the production instance of your database. But maybe an in memory one or one specially for testing. For this you can then just override the DataSource bean.
Developing Component Libraries
You can provide a starting configuration for your libraries and let users override certain components or let them implement interfaces. A sample of this is how the different Spring portfolio projects work (Spring Security, Spring Batch) with their default configuration.
Also when overriding beans spring will log this at startup of your application.
I asked a question yesterday ( Using Spring in standalone apps ) on how you would use Spring in a standalone application. From that I learned that you only create the application context object once. So now the question is (even though it was partially answered in a comment) what happens when you create the application context?
Does Spring create the beans and wire them together when you say
new ClassPathXmlApplicationContext("some.xml") ?
I am not sure if I understand the boot strapping, and why it is like that.
The idea behind the ApplicationContext in Spring is that in order to properly inject objects where they are needed, some thing needs to be aware of the configuration the user specifies and inject dependencies based on this configuration.
The ApplicationContext is the thing that understands the user's wishes in terms of where and what should be injected (as well as other things such as AOP pointcuts and such) based on the configuration a user provides, either through an xml file or annotations.
Yes it will parse the bean definition file , it will create the beans , give them the dependencies,
The easiest way to debug is to go with the output print statements,
Put the statements in constructor & setter methods and try different possibilities to track the flow
What if you don't want to start a separate project for grails but instead sneak it into an existing webapp?
I have to build an admin interface/crud for some new entities and thought it would be a perfect way to learn grails.
I'm trying to make one application with a Grails app and a Spring app.
I've tried to sneak the Grails App into the Spring one, but this is "impossible". It's easier to sneak the Spring app into the Grails app. Grails knows what Spring is, but Spring has no idea of what Grails is.
In this article you can find useful information about how to use your hibernate mapping files or annotations in Grails, so you don't have to remap everything. Also you can use all your java clases (put them into src/java). You can put the beans defined in the ApplicationContext.xml in conf/spring/resources.xml. You can leave them in ApplicationContext, but I've had some problems.
I don't have ended the job (almost) and it looks good.
It would be hard to "sneak it in" unless the existing app has the correct dir structure that maps exactly to how grails likes it - after all, convention over config is where the power of grails comes from.
You can try doing the admin interface as a "seperate" app to the original/existing spring app, and map the existing database to the grails domain objects. though i m not sure how you would run them side by side easily without more information on the existing app. It is possible definitely though.
I agree that building your admin interface is a good exercise to learn Grails, and also agree with the previous answer that Grails is difficult if not impossible to integrate with an existing Spring application. You could probably get it done, but the headache would not be worth it.
Grails is built on top of Hibernate for its ORM, so if you're already using Hibernate with this Spring app you can work this to your advantage. It's not too difficult to configure a Grails app to use pre-existing Hibernate models, and this is explained well in Grails documentation.
So, I'd recommend building up your admin console as an independent Grails app but make use of the Hibernate models you already have, if in fact you've used Hibernate.