Prevent (tomcat) web application from starting if configuration incomplete
How do I set a "configuration check" on a web application startup (Tomcat or other) and if the condition is not met the application should not start.
Let's say the application require a the file /tmp/dummy to exist on the fs in order to start. So I have something like
public class TestConfig
public static void TestServerConfiguration()
if (! new File("/tmp/dummy").exists())
// don't start this web application ...
Where should I include this test?
Thanks!
tomcat web-applications startup
add a comment |
How do I set a "configuration check" on a web application startup (Tomcat or other) and if the condition is not met the application should not start.
Let's say the application require a the file /tmp/dummy to exist on the fs in order to start. So I have something like
public class TestConfig
public static void TestServerConfiguration()
if (! new File("/tmp/dummy").exists())
// don't start this web application ...
Where should I include this test?
Thanks!
tomcat web-applications startup
add a comment |
How do I set a "configuration check" on a web application startup (Tomcat or other) and if the condition is not met the application should not start.
Let's say the application require a the file /tmp/dummy to exist on the fs in order to start. So I have something like
public class TestConfig
public static void TestServerConfiguration()
if (! new File("/tmp/dummy").exists())
// don't start this web application ...
Where should I include this test?
Thanks!
tomcat web-applications startup
How do I set a "configuration check" on a web application startup (Tomcat or other) and if the condition is not met the application should not start.
Let's say the application require a the file /tmp/dummy to exist on the fs in order to start. So I have something like
public class TestConfig
public static void TestServerConfiguration()
if (! new File("/tmp/dummy").exists())
// don't start this web application ...
Where should I include this test?
Thanks!
tomcat web-applications startup
tomcat web-applications startup
asked Nov 14 '18 at 18:52
StefanGStefanG
7518
7518
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I would go with a ServletContextListner. As with the servlet answer, it will not stop Tomcat but it will prevent the web application from loading. One advantage over the servlet answer is from the Javadoc:
All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.
As an example:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FileVerifierContextListener implements ServletContextListener
@Override
public void contextInitialized(ServletContextEvent sce)
// verify that the file exists. if not, throw a RuntimeException
@Override
public void contextDestroyed(ServletContextEvent sce)
Above assumes that your web.xml
specifies a Servlet 3.0 or above environment (or that you don't have a web.xml
at all):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
If you're using a lower servlet spec then you'll want to remove the @WebListener
annotation and declare the listener in web.xml
:
<web-app ...>
<listener>
<listener-class>
com.example.package.name.FileVerifierContextListener
</listener-class>
</listener>
</web-app>
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
@StefanG - the@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.
– stdunbar
Nov 14 '18 at 21:25
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
add a comment |
One idea (but there can be others) is to implement a servlet that will do this check and exit when the condition is false. You need to run it at the beginning of the context deployment with the adequate load-on-startup tag. The web.xml
will then look like :
<servlet>
<display-name>startup condition servlet</display-name>
<servlet-name>startup condition</servlet-name>
<servlet-class>com.xxx.yyy.ConditionChecker</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>FILE_TO_CHECK</param-name>
<param-value>/tmp/dummy</param-value>
</init-param>
</servlet>
This servlet could execute System.exit(1)
when the condition is not met (/tmp/dummy doesn't exist).
Please not this will kill the Tomcat. Not exactly stop the deployment process. If anyone want to fine tune this, you can edit my post.
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53306955%2fprevent-tomcat-web-application-from-starting-if-configuration-incomplete%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would go with a ServletContextListner. As with the servlet answer, it will not stop Tomcat but it will prevent the web application from loading. One advantage over the servlet answer is from the Javadoc:
All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.
As an example:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FileVerifierContextListener implements ServletContextListener
@Override
public void contextInitialized(ServletContextEvent sce)
// verify that the file exists. if not, throw a RuntimeException
@Override
public void contextDestroyed(ServletContextEvent sce)
Above assumes that your web.xml
specifies a Servlet 3.0 or above environment (or that you don't have a web.xml
at all):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
If you're using a lower servlet spec then you'll want to remove the @WebListener
annotation and declare the listener in web.xml
:
<web-app ...>
<listener>
<listener-class>
com.example.package.name.FileVerifierContextListener
</listener-class>
</listener>
</web-app>
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
@StefanG - the@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.
– stdunbar
Nov 14 '18 at 21:25
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
add a comment |
I would go with a ServletContextListner. As with the servlet answer, it will not stop Tomcat but it will prevent the web application from loading. One advantage over the servlet answer is from the Javadoc:
All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.
As an example:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FileVerifierContextListener implements ServletContextListener
@Override
public void contextInitialized(ServletContextEvent sce)
// verify that the file exists. if not, throw a RuntimeException
@Override
public void contextDestroyed(ServletContextEvent sce)
Above assumes that your web.xml
specifies a Servlet 3.0 or above environment (or that you don't have a web.xml
at all):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
If you're using a lower servlet spec then you'll want to remove the @WebListener
annotation and declare the listener in web.xml
:
<web-app ...>
<listener>
<listener-class>
com.example.package.name.FileVerifierContextListener
</listener-class>
</listener>
</web-app>
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
@StefanG - the@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.
– stdunbar
Nov 14 '18 at 21:25
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
add a comment |
I would go with a ServletContextListner. As with the servlet answer, it will not stop Tomcat but it will prevent the web application from loading. One advantage over the servlet answer is from the Javadoc:
All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.
As an example:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FileVerifierContextListener implements ServletContextListener
@Override
public void contextInitialized(ServletContextEvent sce)
// verify that the file exists. if not, throw a RuntimeException
@Override
public void contextDestroyed(ServletContextEvent sce)
Above assumes that your web.xml
specifies a Servlet 3.0 or above environment (or that you don't have a web.xml
at all):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
If you're using a lower servlet spec then you'll want to remove the @WebListener
annotation and declare the listener in web.xml
:
<web-app ...>
<listener>
<listener-class>
com.example.package.name.FileVerifierContextListener
</listener-class>
</listener>
</web-app>
I would go with a ServletContextListner. As with the servlet answer, it will not stop Tomcat but it will prevent the web application from loading. One advantage over the servlet answer is from the Javadoc:
All ServletContextListeners are notified of context initialization before any filters or servlets in the web application are initialized.
As an example:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FileVerifierContextListener implements ServletContextListener
@Override
public void contextInitialized(ServletContextEvent sce)
// verify that the file exists. if not, throw a RuntimeException
@Override
public void contextDestroyed(ServletContextEvent sce)
Above assumes that your web.xml
specifies a Servlet 3.0 or above environment (or that you don't have a web.xml
at all):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>
If you're using a lower servlet spec then you'll want to remove the @WebListener
annotation and declare the listener in web.xml
:
<web-app ...>
<listener>
<listener-class>
com.example.package.name.FileVerifierContextListener
</listener-class>
</listener>
</web-app>
answered Nov 14 '18 at 20:06
stdunbarstdunbar
5,97561528
5,97561528
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
@StefanG - the@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.
– stdunbar
Nov 14 '18 at 21:25
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
add a comment |
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
@StefanG - the@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.
– stdunbar
Nov 14 '18 at 21:25
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
I upvote, this is a nice answer.
– Eugène Adell
Nov 14 '18 at 20:16
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Eclipse does not like the @Override annotation in the listener. Otherwise, this is the solution I will adopt!
– StefanG
Nov 14 '18 at 20:39
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
Why Eclipse does not like the @Override annotation in the listener? Multiple markers at this line - The method contextInitialized(ServletContextEvent) of type FileVerifierContextListener must override a superclass method - implements javax.servlet.ServletContextListener.contextInitialized As expected, the code is ok (Maven build it without any problem). What am I missing? This is the solution I will adopt! I will confirm it tomorrow.
– StefanG
Nov 14 '18 at 21:02
@StefanG - the
@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.– stdunbar
Nov 14 '18 at 21:25
@StefanG - the
@Override
is totally not needed. I'm not sure why Eclipse doesn't like it - perhaps because it's for an interface, not a class. I'd remove it as it is not needed.– stdunbar
Nov 14 '18 at 21:25
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
Found it. It was the "Compiler compliance level" ... was set to 1.5. I changed it to 1.8 and Eclipse is now happy.
– StefanG
Nov 14 '18 at 21:39
add a comment |
One idea (but there can be others) is to implement a servlet that will do this check and exit when the condition is false. You need to run it at the beginning of the context deployment with the adequate load-on-startup tag. The web.xml
will then look like :
<servlet>
<display-name>startup condition servlet</display-name>
<servlet-name>startup condition</servlet-name>
<servlet-class>com.xxx.yyy.ConditionChecker</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>FILE_TO_CHECK</param-name>
<param-value>/tmp/dummy</param-value>
</init-param>
</servlet>
This servlet could execute System.exit(1)
when the condition is not met (/tmp/dummy doesn't exist).
Please not this will kill the Tomcat. Not exactly stop the deployment process. If anyone want to fine tune this, you can edit my post.
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
add a comment |
One idea (but there can be others) is to implement a servlet that will do this check and exit when the condition is false. You need to run it at the beginning of the context deployment with the adequate load-on-startup tag. The web.xml
will then look like :
<servlet>
<display-name>startup condition servlet</display-name>
<servlet-name>startup condition</servlet-name>
<servlet-class>com.xxx.yyy.ConditionChecker</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>FILE_TO_CHECK</param-name>
<param-value>/tmp/dummy</param-value>
</init-param>
</servlet>
This servlet could execute System.exit(1)
when the condition is not met (/tmp/dummy doesn't exist).
Please not this will kill the Tomcat. Not exactly stop the deployment process. If anyone want to fine tune this, you can edit my post.
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
add a comment |
One idea (but there can be others) is to implement a servlet that will do this check and exit when the condition is false. You need to run it at the beginning of the context deployment with the adequate load-on-startup tag. The web.xml
will then look like :
<servlet>
<display-name>startup condition servlet</display-name>
<servlet-name>startup condition</servlet-name>
<servlet-class>com.xxx.yyy.ConditionChecker</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>FILE_TO_CHECK</param-name>
<param-value>/tmp/dummy</param-value>
</init-param>
</servlet>
This servlet could execute System.exit(1)
when the condition is not met (/tmp/dummy doesn't exist).
Please not this will kill the Tomcat. Not exactly stop the deployment process. If anyone want to fine tune this, you can edit my post.
One idea (but there can be others) is to implement a servlet that will do this check and exit when the condition is false. You need to run it at the beginning of the context deployment with the adequate load-on-startup tag. The web.xml
will then look like :
<servlet>
<display-name>startup condition servlet</display-name>
<servlet-name>startup condition</servlet-name>
<servlet-class>com.xxx.yyy.ConditionChecker</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>FILE_TO_CHECK</param-name>
<param-value>/tmp/dummy</param-value>
</init-param>
</servlet>
This servlet could execute System.exit(1)
when the condition is not met (/tmp/dummy doesn't exist).
Please not this will kill the Tomcat. Not exactly stop the deployment process. If anyone want to fine tune this, you can edit my post.
answered Nov 14 '18 at 19:27
Eugène AdellEugène Adell
2,0942925
2,0942925
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
add a comment |
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
The server must remain up. I was unable to workaround your idea but is not working. The solution that stdunbar provided is the solution to my problem.
– StefanG
Nov 14 '18 at 20:37
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53306955%2fprevent-tomcat-web-application-from-starting-if-configuration-incomplete%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown