I am trying to figure out how to disable javamelody grails plugin completely. Following http://www.grails.org/plugin/grails-melody, I set javamelody.disabled = true in GrailsMelodyConfig.groovy. For some reason, this disables monitoring in a sense that I cannot navigate to myapp/monitoring to view info. More debugging showed that even if I disabled it, it is still calling doWithDyanmicMethod which adds invokeMethod on each services.
Is there something else I am missing? If it adds invokeMethod on each services, this defeats the point of disable.
According to the documentation:
The parameter disabled (false by default) just disables the
monitoring. This allows for example to disable the monitoring
temporarily or only on some servers, from the tomcat context or from
system properties without modifying the web.xml file neither the war
file of the monitored webapp.
But maybe you can disable the whole monitoring by using the 'url-exclude-pattern' option. Hope this helps.
This could be disabled all meta programming by adding context-param javamelody.disabled in web.xml. So to avoid calling doWithDyanmicMethod part.
Related
The description of "Vite" was tempting and I was stupid enough to enable this new feature. Since then I am stuck with endless UI recompile loops! I.e. each time after I logged into my application the frontend gets recompiled AGAIN and the application restarts. ||-(
Disabling Vite in the lower right control-dialog is not accepted, it remains activated. How do I get rid of this unbaked feature again?
This is using Vaadin 23.1.7 and Java 17.
In Vaadin 23.1 you can remove the feature flag by deleting it from src/main/resources/vaadin-featureflags.properties.
Note that Vaadin 23.2 uses Vite by default. If you want to continue using Webpack going forward, you need to instead add this feature flag to the properties file:
com.vaadin.experimental.webpackForFrontendBuild=true
I'm looking for ways to configure/reconfigure log4j after it may, or may not have been initialized. This should work running standalone or in a web container.
The configuration may be represented by a configuration file at a particular arbitrary URI. The knowledge of the URI comes from the application, not log4j framework. The configuration may also be done programmatically (less problematic but problematic still).
The public API is unfortunately sorely lacking so developers are forced to write brittle code using implementation classes from log4j core. From weeks of studying documentation and stepping through log4j code I see two ways to accomplish reconfiguration:
Stopping the current context and re-initializing using log4j.core.config.Configurator,
similar to the following:
((LoggerContext) LogManager.getContext(false)).stop();
Configurator.initialize(buildDefaultConfiguration()); //programmatically building a configuration
or
((LoggerContext) LogManager.getContext(false)).stop();
Configurator.initialize(null, ConfigurationSource.fromUri(loggingUri)); //passing the configuration source constructed from a known URI
The first line in both examples will stop the current context if it has already been created and started (when running in a web container for example). If log4j has not been initialized (when running as a standalone app for example) it will initialize log4j with the default configuration and start the context first (as a side effect of calling getContext()), and then stop it.
If the current context is not stopped first the call to Configurator.initialize() will have no effect. log4j will ignore your attempt to re-initialize, will not give you any indication of it, and just simply return the current context. This behavior is not mentioned in the "Reconfigure Log4j Using ConfigurationBuilder with the Configurator" section of the Manual. It simply says: "However, should any logging be attempted before Configurator.initialize() is called then the default configuration will be used for those log events." The default configuration will also be used for all subsequent log events in the provided examples because calling Configurator.initialize() will have no effect, unless the current context is stopped first.
Setting a new configuration location on the existing context thus forcing reconfiguration,
similar to the following:
((LoggerContext) LogManager.getContext(false)).setConfigLocation(loggingUri);
This works in a similar fashion: if log4j hasn't been initialized the call to getContext() will trigger initialization and creation of the default context that will then be reconfigured; and if it has been initialized then the current context, whatever it may have been, will get reconfigured. The configuration source will be created from the URI by the log4j framework.
The difference is that in the first way the context is replaced and all loggers in the old (stopped) context will be dead. If any code on the stack holds references to these dead loggers and tries to log to them it will be a no-op. In the second way the context is kept but the configuration is replaced and existing loggers are updated with the new configuration.
Both methods use core code and are therefore brittle, but both work for the sunny day scenario (using log4j-core 2.10.0 anyway). However, neither one appears to afford the user any control over handling any exceptional events, or even inform the user that something went wrong. Log4j will "eat up" any exceptions, and make its own executive decision how to handle them.
If a problem occurs after Configurator.initialize() is called log4j will create a default configuration that effectively cuts all logging off other than errors to the console and happily return the new context back not giving the calling code any clue that logging has effectively been stopped.
If a problem occurs after LoggerContext.setConfigLocation() is called log4j will do essentially the same thing except the current context will be kept. One would think that particularly in the case of a reconfiguration failure the most typical handling would be to revert back to the old configuration. There doesn't appear to be a way to accomplish this because log4j will simply stop logging (other than errors to the console) and give the calling code no indication of the failure.
Here's a typical scenario: several applications extend a common framework. The framework configures the same logging for all extending applications (to facilitate reuse and simplify post-processing of the logs). Some application has a unique logging need and attempts to reconfigure log4j from its own metadata (config file at a known URI). The XML parser throws an exception parsing this file. The exception gets handled internally by log4j, logging is quietly stopped, and no one knows. Well, there is an error log sent to the StatusLogger with the exception, but the calling code doesn't know.
So with this lengthy preamble, the question is: is there a mechanism I haven't discovered yet to modify log4j configuration in a predictable fashion and be able to handle abnormal events should they arise? That is, other than something drastic like (for the example above) extending the XML configuration class and replacing code that handles exceptions, thus running a risk of creating undesirable side effects in the current log4j implementation, not talking about an even greater risk of breaking in the future if the implementation changes.
Any help would be greatly appreciated!
I know I can do it manually but is there any grails create-service counterpart for removing a service?
No, there is not. As others have said, removal is more dangerous than creation. Either use an IDE, or remove the service manually after checking for any usages.
I recently learned how to register custom grails artifacts (I need it for dynamic controllers in my application) using grailsApplication.addArtefact(java.lang.String artefactType, GrailsClass artefactGrailsClass) and it works fine, but now I realized that I also want to be able to unregister them.
Unfortunately, interface GrailsApplication provides no clear way to do so and it seems that unregistering unwanted dynamically registered grails artifacts can only be done by restarting the whole application.
Maybe I'm missing something and an artifact can be removed from an application without having to restart the app?
Thank you
You can always rebuild the GrailsApplication. That throws away all artefacts and loads the default ones. That obviously means you'd have to addArtefact the artefacts you want to keep again.
Other option is access the loadedClasses set (which is protected) and make the changes manually and then call populateAllClasses to make available (this method is protected too).
I'm wondering where utility code can be placed, that doesn't cause a restart of container. Updating controllers doesn't cause a container restart & the updated code is available to run (great), but I wanted a more general library/utility place for my utility code.
Putting the code in /utils or in src/groovy does cause a restart on save, at least using Intellij, but I imagine this is the same regardless of where Grails is developed.
Perhaps you have some general info/insights on how Grails does this -- includes new code but doesn't need to restart the container, if that's only special to controllers?
(v. 1.3.7)
You're out of luck out of the box unless you want to use 2.0. The alternative is to turn off auto-reloading and add in something like jrebel. See this blog for details.