How to force Tomcat (embedded in Spring Boot) to use standard java.util.logging instead of JULI? [duplicate] - spring-boot

This question already has an answer here:
Can't override java.util.logging.LogManager in a Spring Boot web application: Getting java.lang.ClassNotFoundException on already loaded class
(1 answer)
Closed 10 months ago.
I'm running Tomcat as an embedded server inside of a Springboot app, so all the additional functionality in JULI such as multiple class loaders etc is not needed and just gets in the way.
I just want my app to use java.util.logging directly without the extra complication of JULI. I want a flat configuration where everything just flows directly to java.util.logging and the way I have configured it.
How can I ditch JULI?
UPDATE
The actual problem I'm having is that I'm unable to load a custom Handler... getting a ClassNotFound. I initially thought this was caused by JULI but really seems to be related to Spring Boot's System Class Manager unwillingness to load classes from BOOT-INF.

JULI is just a logging facade used by Tomcat for its internal logging (cf. javadoc) based on Apache Commons Logging. It is not a logging framework and does not perform any logging by itself.
By default it uses java.util.logging plain and simple the way you configured it.
The additional functionality you can find in a standalone Tomcat (per classloader configuration, multiple handlers of the same class, etc.) is provided by ClassLoaderLogManager. In order to use it you need to set:
-Djava.util.logging.logmanager=org.apache.juli.ClassLoaderLogManager
as JVM parameter (anywhere else it will be probably ignored).
Tomcat's startup scripts add the above mentioned Java system property, but your Spring Boot application almost certainly does not. Hence your application is using java.util.logging plain and simple (unless you are using spring-boot-starter-logging in which case java.util.logging is redirected to LogBack).
TL;DR: by default Tomcat JULI simply forwards messages to java.util.logging. There are no complications.

Related

CVE-2022-22965 - Tomcat Specific

I am trying to understand the Spring posted description of the problem and resolution alternatives
https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement
However, I do not understand why this would be Tomcat specific. Wouldnt the same issue exist for war files deployed to Jetty or Wildfly?
This particular exploit demostration is based on the custom custom implementation of one of tomcat specific classloaders having referrence to the servlet environment context. This is why this demo is tomcat specific especially that is exploits the fact that one of the logger valves is the first one in the processing pipeline (this is used to write custom jsp code as a log file in webapps root)
Also it requires Java9+ as it uses access trough class.getModule() which is not present in earlier versions

Apache Tomee session Management with gemFire Integration

I am trying to do session management using tomcat modules in gemFire. Reference link we used is [https://gemfire.docs.pivotal.io/95/geode/tools_modules/http_session_mgmt/tomcat_installing_the_module.html].
Application server that we are using is tomee 7.0.5. After making the changes mentioned in the link. When i tried to make the server up, we were getting an error "getContainer() method not found in class DeltaSessionManager".There is a module geode-modules-9.5.1.jar provided by gemFire(gfsh Client) which helps for session management. Inside that there is a class DeltaSessionManager which extends another class org.apache.catalina.session.ManagerBase . But the ManagerBase class in catalina.jar inside tomee 7.0.5 doesn't have this method. But when we downloaded tomcat catalina jar separately we were able to see this method. Is there any difference in the approach for tomee.
Any help would be appreciable
Looking at the tomee source code, I suspect tomee 7.0.5 is actually embedding Tomcat 8. In that case, you need to use Tomcat8DeltaSessionManager, which supports Tomcat 8 and above.

Spring Boot best practices for hiding or encrypting passwords

I have been using the Spring Framework for about 4 years now, and now Spring Boot for the last couple of months. My Spring MVC applications are usually deployed on a Java EE container such as JBoss/WildFly or WebLogic. Doing so allows me to use JNDI for things like datasources or any other sensitive data that involve secrets/passwords. That makes my app "consume" that JNDI resource based on its name.
Now with Spring Boot and especially for self-contained microservices (embedded tomcat), that information is now stored within the application (application.properties and/or in Spring Java Config classes), so versioned in Git.
That makes that information a lot more exposed to other developers, which I'm not very comfortable with. I also don't like having those details show up in SonarQube and Jenkins (through workspaces).
Question is: Are there any best practices for this specific requirement?
* UPDATE *
I see some articles here and there about the use of Jasypt, but I wonder if it's still a valid library to use since the last stable release is dated from 2014.
Thank you
You could consider using a vault. Spring supports a few of them out of the box. You can find more information here http://projects.spring.io/spring-vault/.
If you have spring cloud in your stack, then it's very easy. Use encrypt the value and put it in the application properties. Follow the instruction mentioned here.
Other way is, set the values as environmental variables and using the environmental variables in the application properties. Instructions here

How to only auto configure the embedded container?

I'm trying bootify my app, which is XML configured. I'd love to have an embedded tomcat server that I can just run through the main method.
The simplest way to do it is to bootstrap the app using the existing XML config through #ImportResource("classpath:app-servlet.xml").
I cannot use auto configuration. We have certain circular dependencies that are not trivial to fix at this point.
The problem is that the embedded tomcat server only gets automatically configured if you use #EnableAutoConfiguration.
Is there a way to only auto configure the embedded server? I tried looking that Spring Boot's sources, namely EmbeddedServletContainerAutoConfiguration, including extending it and "running" it through my setup, but it only runs the customizers, not the ServletInitializer, therfore I'm getting an error "Root context already initialized".
Any help would be greatly appreciated.

Share spring container between test application and embedded tomcat

We are using cucumber-jvm to write an integration test layer in our application. One of the challenges we are finding is managing the database between the tests and the web application.
A typical scenario is that we want to persist some entities in a Given step of a scenario, then perform some actions on the user interface that may, in turn, persoist more entities. At the end, we want to clean the database. Because the cucumber-jvm tests are in one jvm and the web application is running in another jvm we cannot share a transaction (at least in a way of which I am aware) so the database must be cleaned manually.
My initial thought was to use an Embedded Tomcat server running off of an embedded in-memory database (HSQLDB) in the same JVM as the cucumber-jvm test. This way we might be able to share a single spring container, and by extension a single transaction, from which all objects could be retrieved.
During my initial tests it looks like Spring gets loaded and configured twice: once when the test starts and the cucumber.xml is read, and a second time when the embedded tomcat starts and the web application reads its applicationContext.xml. These appear to be in two completely separate containers because if I try to resolve an object in one container that is specified in the other container then it doesn't resolve. If I duplicate my configuration then I get errors about duplicate beans with the same id.
Is there a way that I can tell Spring to use the same container for both my test application and the embedded tomcat?
I'm using Spring 3.2.2.GA and Embedded Tomcat 7.0.39 (latest versions of both libraries).
Am I crazy? Do I need to provide more technical details? Apologies if I use some incorrect terminology.
Thanks
p.s. If my problem seems familiar to you and you can suggest an alternative solution to the one I am trying, please let me know!
Jeff,
It is normal that spring is loaded twice. There are two places where two spring contexts are created:
In the servlet container listener org.springframework.web.context.ContextLoaderListener that is configured in web.xml. This one reads its configuration from the file set by the context-param contextConfigLocation.
In the implementation of ObjectFactory provided by cucumber-spring plugin cucumber.runtime.java.spring.SpringFactory. This one reads its configuration from cucumber.xml.
The two spring contexts are totally different and their instances are kept in two different places. As a servlet context attribute for the former and kept by the JavaBackend for the latter.
When starting the embedded tomcat, it is possible to get access to the servlet context and thus set ourself the spring context used bt tomcat with the one from cucumber. But, spring has a special class called WebApplicationContext for context used in a servlet container. The cucumber SpringFactory on other hand creates its context through ClassPathXmlApplicationContext. So unless there is a way to specify the type of application context from the xml config, we will have to provide an ObjectFactory that shoots a WebApplicationContext.
What we can do is to have two web.xml. One for the normal and one for the test. For the test, we use our version of the ContexLoader listener.

Resources