SEVERE: Begin event threw error java.lang.ExceptionInInitializerError Intellij/Tomcat - java

I got a new project which I wanted to work with in Intellij. As local server we use Tomcat 7.0.68 and JDK 1.8.
This is my configuration in tomcat.
lib/catalina/org/apache/catalina/startup/Authenticators.properties:
NIGHTSHIFT=com.glit.swidA9O.v1.authenticator.NightShiftAuthenticator
conf/catalina.properties:
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,/Users/Administrator/dev/server/apache-tomcat-7.0.68/shared/nightShift/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
conf/context:
<Valve className="com.glit.swidA9O.v1.authenticator.NightShiftAuthenticator" changeSessionIdOnAuthentication="true"/>
<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
virtualClasspath="/Users/Administrator/dev/PROJECT/config;/Users/Administrator/dev/PROJECT/data"/>
conf/server.xml
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<Realm className="com.glit.swidA7U.v1.realm.NightShiftRealm" roleClassNames="com.glit.swidBS0.v1.shared.principals.NightShiftGroup" userClassNames="com.glit.swidBS0.v1.shared.principals.NightShiftUser"/>
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
Our problem
Inside our local tomcat server we want to use a specific library called "NightShift". Unfortunately every time we try to build our application with intellij/tomcat we get this error somehow:
Complete stacktrace
Which is funny because if we try to build the application with eclipse tomcat runs smoothly and can actually build the project properly.
Those are the settings for Intellij/Tomcat we made:
These are my vm-options (actually I don't even know if you need this but just in case):
-DLOG4J2-ROOT=/Users/Administrator/dev/PROJECT/data/logs
-Djava.security.auth.login.config=/Users/Administrator/dev/PROJECT/config/NightShift-config/common/NightShiftJAAS.conf
-Dpu8.config.path=/Users/Administrator/dev/PROJECT/config/NightShift-config
-Dpu8.configuration.id=A7U
-Dpu8.environment=ide
-Djava.util.logging.config.file=/Users/Administrator/dev/PROJECT/config/NightShift-config/log-config.properties
-Djava.security.manager
-Djava.security.policy="/Users/Administrator/dev/server/apache-tomcat-7.0.68/conf/catalina.policy"
This is what our tomcat looks like:
Inside "shared" is a folder called "nightshift" and there are all the neccessary .jar files which we mentioned in the catalina.properties file.
Inside our artifacts we didn't include the "nightshift" jars, cause we want it installed in tomcat and not in our application.

There appears to be a problem with your application's logging initialization:
Caused by: java.util.NoSuchElementException
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:365)
at java.util.ServiceLoader$LazyIterator.access$700(ServiceLoader.java:323)
at java.util.ServiceLoader$LazyIterator$2.run(ServiceLoader.java:407)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:409)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at com.glit.swidPV4.v1.common.log.LogFactory.getInstance(LogFactory.java:32)
at com.glit.swidPV4.v1.common.log.LogFactory.getLog(LogFactory.java:42)
at com.glit.swidA7R.v1.businessdelegate.VerifierBDFactory.<clinit>(VerifierBDFactory.java:29)
... 75 more
It looks like it is looking for a service provider that doesn't exist, and then failing to deal with that properly. That leads to a runtime exception which cascades into other things.
Look at the source code for com.glit.swidPV4.v1.common.log.LogFactory to figure out what what it is looking for.
Figure out why it is missing. My guess would be a missing / misplaced JAR file or a missing / misplaced config file.
Fix it.
(Maybe) fix the LogFactory code to be more resilient ... or to throw a custom exception rather than just bombing out with an obscure NoSuchElementException.
Figuring out remotely where JAR and config files should be for your particular case is too difficult. But this is just standard Java / Tomcat troubleshooting ... once you have figured out what is causing the problem.
Unfortunately every time we try to build our application with intellij/tomcat we get this error:
One "solution" would be to switch to using Maven or something to build WAR files, and test / deploy them by hand rather than relying of the "shiny" Intellij integration stuff.
(You shouldn't be hot deploying into a production server anyway. That's poor practice. You are one mistake away from trashing your production env. And if this is just a dev / test environment, it is a good idea to get into the habit of doings things the right way in dev.)

Related

Setup Tomcat for multiple websites in one server (linux)

I know this question might be similar to others, however, I haven't been able to solve this.
I have a server with 25 websites, all of them uses Tomcat. I'm migrating to a new server which has Tomcat 8 (the regular version), whereas the old server uses "CPanel's easy tomcat".
I started migrating one website, which is now running on the new server, however, when a JSP is called from the browser, the browser shows the JSP code instead of executing it.
In my old server, I had to execute a feature from CPanel's easy-tomcat called "install servlets", which I really don't know what it does, however, after executing that, Tomcat would execute JSP's.
Now, in my new server, accordgin to what I've read, I've added this to the %CATALINA_HOME%/conf/server.xml file, inside the <Engine></Engine> tags (which I also had to include in my old server):
<Host name="mydomain.com" appBase="/home/myAccName/public_html/">
<Context path="" reloadable="false" docBase="/home/myAccName/public_html" />
</Host>
As you can see, the application is not located under %CATALINA_HOME%/webapps/ directory, and that's the way I need it to be.
What am I missing?
Any help will be really appreciated
I'm using Tomcat 8, EasyApache 4 and CentOS 7.6
check that the following in in your tomcat/conf.web.xml file
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
You can create VirtualHosts to setup multiple websites with multiple domain names in one server. You can try out same in tomcat 7, 8 and in 9 as well.
1.Edit your relevant server.xml file and include Virtual hosts as below.
Make sure to restart your tomcat server for the applied changes to take effect.
<Host name="example.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Alias>www.example.com</Alias>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="example_access_log" suffix=".txt"
pattern="%h %l %u %t %r %s %b" />
<Context path="" docBase="/opt/tomcat/webapps/myapp1"
debug="0" reloadable="true"/>
</Host>
<Host name="mydomain.org" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Alias>www.mydomain.org</Alias>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="mydomain_access_log" suffix=".txt"
pattern="%h %l %u %t %r %s %b" />
<Context path="" docBase="/opt/tomcat/webapps/myapp2"
debug="0" reloadable="true"/>
</Host>
Explanation
For example.com domain, /opt/tomcat/webapps/myapp1 is the document root (for your web 1).
For mydomain.org domain, /opt/tomcat/webapps/myapp2 is the document root(for your web 1).
This is the way I managed to solve this. I don't know if it's the best way, but it works. Just follow the next 3 steps:
1)
In %CATALINA_HOME%/conf/server.xml:
<Host name="mydomain.com" appBase="webapps" autoDeploy="false" unpackWARs="false"></Host>
2)
Then I had to add a file:
%CATALINA_HOME%/conf/mydomain.com/ROOT.xml
<Context displayName="My Website 1" docBase="/home/accountfolder/public_html" reloadable="true">
<Resource
name="jdbc/rhwebDB"
.
.
.
(database connection info, optional)
/>
</Context>
Then on the Apache side, I had to configure the mod_proxy_ajp connector
I've edited the file:
3)
/etc/apache2/conf.d/userdata/std/2/accountfolder/mydomain.com/cp_jkmount.conf
<IfModule mod_jk.c>
JkMount /*.jsp ajp13
JkMount /servlet/* ajp13
JkMount /servlets/* ajp13
</IfModule>
<IfModule mod_proxy_ajp.c>
ProxyRequests Off
<Proxy *>
AddDefaultCharset Off
Order deny,allow
Allow from all
</Proxy>
ProxyPass / ajp://mydomain.com:8009/
ProxyPassReverse / ajp://mydomain.com:8009/
My application/website is located on /home/accountfolder/public_html/ and there's nothing on the %CATALINA_HOME%/webapps/ directory. For me this is better since I can upload a jsp or whatever directly where the app is located using a FTP user.
If you have any trouble, check the folder permissions and owners in your /home/accountfolder/public_html/ directory, Tomcat needs permissions for reading/executing etc. A Tomcat's 404 error will be shown if Tomcat can't access those files & folders.
As I mentioned in this post, my app is "exploded" (if that's the correct term), I mean, it's NOT packed in a WAR file.

Java App not loading on tomcat 9 centos 7

I'm pretty new to linux and I've been thrown into it. So far I made it work a few times, but this time it got me bad. The aim is to cluster tomcat and load balance with nginx but the app error is taking too much time from me. The app is correctly deployed by tomcat but is not accesible through browser. I've checked permissions, dns resolution, ports. The app resides out of webapps folder.
Java 8 installed from yum
Tomcat 9 taken with wget
Configured tomcat service to autostart
Added execution permits to .sh's
I honestly dont know what I'm missing. The same app currently runs under centos 6 on production server.
Thanks in advance
Finally I got it working. I was missing the <Context.../> just beneath my <Host.../> declaration. Production server doesn't have that line, so I supposed there was no need for it. Nevertheless the first time I got it working, I don't remeber having that set up.
Like this:
</Realm>
<Host name="hostname" appBase="/app/base/" unpackWARs="true" autoDeploy="false">
<Context path="" docBase="/app/base/" reloadable="true"/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>

Tomcat: status code 404 on requests of every application

Every application deployed on my Tomcat returns status code 404 on every request I make. I've tried several projects, helloworlds or skeletons and every project behaves the same as others:
Some of the projects I've used:
https://github.com/mwarman/skeleton-ws-spring-boot
https://spring.io/guides/gs/rest-service/ (I can run it with mvn spring-boot:run but it's not working as deployed to Tomcat)
https://github.com/shagstrom/spring-mvc-hibernate-skeleton
I'm using the newest Tomcat8 (8.0.27), Oracle JDK 8. I've also tried Tomcat7 with OpenJDK 7.
Used Tomcats are running on MAC and Debian.
I've build apps via mvn and via Intellij Idea.
Tomcats are clean, no configs are changed (except adding manager-gui user).
Since I've tried many different projects, I don't believe the problem is in the code. Is it in Tomcat's config? How can I get it to work?
EDIT:
server.xml code:
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
If you installed tomcat successfully, you may have seen tomcat main page from browser http://localhost:8080/ URL. (Otherwise, you need to check tomcat installation first.)
I guess you may have built jar by fallowing above sites that you mentioned.
I am wondering whether you applied the jar into your tomcat or not because you mentioned same result from any other projects.
You need to apply jar or war into your tomcat in order to apply java program.
Here are links that I wish they might be helpful to you.
Packaging war : How to make war file in Eclipse
Tomcat - war file deployment : https://www.youtube.com/watch?v=9X9DA8oVodk
If tomcat returns 404 response, you have to check those points:
check if your deploy was correct
check if war bootstrap and its ServletContext initialization has no errors
check if the resource your invoking was successfully exposed.
To test these issues you have to expose:
static resource test
web service resource test
in this way you can exclude the pitfalls you can meet during application deploy

TransformerFactory not found in web app in tomcat root

I have created a web app that uses the Saxon library for XSLT transformations.
This application works well when the web application is deployed on Tomcat using its own name (equal to the name of the subdirectory in the webapps directory).
But now I have changed server.xml to use this web application as the root application and now it cannot load the Saxon library.
I think this has something to do with the class loader. I've used the class loader to find configuration files which also broke down when I made this application the tomcat root application. I was able to load the config files using the ServletContext, so that problem was solved.
But now I get the following error:
Caused by: javax.xml.transform.TransformerFactoryConfigurationError: Provider net.sf.saxon.TransformerFactoryImpl not found
which was called using:
TransformerFactory tf = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",null);
The changes I made to server.xml (I've added the <Context> element):
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context docBase="foodvoc-pipelines" path="/" reloadable="true"/>
</Host>
It seems that tomcat cannot find the SAXON library when the TransformerFactory is created using the class name in the newInstance method.
Can I add a directory (the lib directory in the web app) to the classpath programmatically? Or should I add the SAXON library to another directory (which?) that is used by tomcat in its classpath? Can I create a Saxon TransformerFactory directly (without class loaders)? Or is my configuration to make this application the root application wrong?
I was able to get this working by adding the lib directory in the tomcat webapp programatically to the class loader.
To be honest, I'm not really happy with the solution, but it works...
The path has to be added statically as described in the answer to this question. This is a static method in my FoodVocApplication class.
private static void addPath(File file) throws NoSuchMethodException, MalformedURLException, InvocationTargetException, IllegalAccessException {
URI u = file.toURI();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<URLClassLoader> urlclass = URLClassLoader.class;
Method method = urlclass.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(classLoader, new Object[]{u.toURL()});
}
This method can then be called during initialisation by:
FoodVocApplication.addPath(new File(webInff, "lib"));
where webInff is a File object pointing to the WEB-INF directory in the webapp.

where/how to setup configuration resources for Tomcat .war files

I have a source tree for a .war file that I need to modify so that I can add some application-specific configuration info (in this case a jdbc connection string, but I may have other properties-like resources). What are the best practices for where to put configuration info and how to access this from within the Servlet?
I'm guessing this Tomcat configuration reference has something to do with it, but my eyes glaze over when I try to read it.
For web app configuration you can place the config on the classpath somewhere. Then you can get to it from your application with getResourceAsStream or if you prefer Spring:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:my-config.properties</value>
</list>
</property>
</bean>
There are a number of places you can put the properties on the classpath in Tomcat. in order it looks at:
/WEB-INF/classes of your web application
/WEB-INF/lib/*. jar of your web application
$CATALINA_HOME/common/classes
$CATALINA_HOME/common/endorsed/*.jar
$CATALINA_HOME/common/i18n/*.jar
$CATALINA_HOME/common/lib / *. jar
$CATALINA_BASE/shared/classes
$CATALINA_BASE/shared/lib/*.jar
For example, if you put my-config.properties both in a .jar file and in WEB-INF/classes the one in WEB-INF/classes will be used. You could use this mechanism to default to test config and override prod config on prod servers.
For the specific case of a JDBC connection string, I would recommend using a Tomcat-managed connection pool instead. You can read more about doing this here:
http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html
It's more work, but I think in the long run it will serve you better.
Hmm. It looks like the easiest path to getting what I want on the Java side of the application is to use Servlet.getServletConfig().getInitParameter(parameterName) e.g. getInitParameter("myApp.connectionString");
But I don't know where to set this. The Tomcat docs talk about various permutations of context.xml but I want to make sure this parameter only affects my servlet and not any others. I also don't want to locate it within my .war file so that I can keep this parameter independent of the applications (for instance if I install an upgrade).
Update: I figured it out, key/value parameters accessible by ServletContext.getInitParameter() go here (or can go here) in ${CATALINA_HOME}/conf/server.xml:
<Server port=... >
...
<Service name="Catalina" ...>
<Engine name="Catalina" ...>
...
<Host name="localhost" ...>
<Context path="/myWarFile">
<Parameter name="foo" value="123" />
<Parameter name="bar" value="456" />
...
</Context>
</Host>
</Engine>
</Service>
</Server>
This sets two parameters, "foo" = "123", "bar" = "456" for the servlet myWarFile.war (or more accurately with the URL path /myWarFile) and I can get at them in Java with Servlet.getServletConfig().getInitParameter("foo") or Servlet.getServletConfig().getInitParameter("bar").
I also looked at JIRA's server.xml entry (and what they tell you to set it to for MySQL), they use a Resource rather than a Parameter, not quite sure of the subtleties of this but it seems like it could be more appropriate method.
<Server port=... >
<Service name="Catalina" ...>
<Engine name="Catalina" ...>
<Host name="localhost" ...>
<Context path="/jira" docBase="${catalina.home}/atlassian-jira"
reloadable="false">
<Resource name="jdbc/JiraDS" auth="Container" type="javax.sql.DataSource"
username="jirauser"
password="..."
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/jiradb1?autoReconnect=true&useUnicode=true&characterEncoding=UTF8"
maxActive="20"
validationQuery="select 1"
/>
</Context>
</Host>
</Engine>
</Service>
</Server>
you can add the path to your properties files in your CATALINA_HOME/conf/catalina.properties in the "common" classloader common.loader.

Categories

Resources