activemq jndi tomcat error - java

I am trying to use ActiveMQ via JNDI, deploying the application in Tomcat 7.0 server.
I have made the settings for ActiveMQ connection factory and queue in Tomcat context.xml configuration file, and they look like this:
<Resource
auth="Container"
brokerName="LocalActiveMQBroker"
brokerURL="vm://localhost"
clientID="TomcatClientID"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
name="jms/ConnectionFactory"
password="password"
type="org.apache.activemq.ActiveMQConnectionFactory"
userName="user"/>
<Resource
auth="Container"
description="Order Queue"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
name="jms/orderQ"
physicalName="orderQ"
type="org.apache.activemq.command.ActiveMQQueue"/>
and I try to get the connection factory this way:
nnectionFactory connectionFactory = (ConnectionFactory) context
.lookup("java:comp/env/jms/ConnectionFactory");
but I get an exception:
java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:230)
I tried to find out the cause of the exception, but I found only that it could come from commons-logging jar, which I have added to tomcat lib folder.
Where am I wrong?

commons-logging is a library that has to do with logging indeed, but it's from Apache. Also slf4j is just a facade, you need to provide an actual implementation for slf4j. I would suggest logback, which is a "better" way to do logging in java. So you are going to need 3 jars on your classpath: slf4j-api.jar, logback-core.jar and logback-classic.jar.
If on the other hand you do not want to use logback then any other implementation will work.

Related

websphere liberty - Not able to generate application specific logging using slf4j or log4j

How can I generate Application specific logs in IBM Websphare Liberty server, I am using SLF4j, the message.log and console.log is updating fine but the application specific logs are not getting generated.
If the logging issue can be resolved using Log4j, then also will work for me.
Tried loading log4j2 file explicitly in static block and also placed in resource folder, both didnt worked.
able to see liberty server log but application logs are not generating at all.
The root cause of not seeing log4j logs is usually because the log4j2 configuration file is not being picked up by the classloader. You have a few options here to solve your problem.
Copy to Liberty shared-library directory. It can be one of the following:
${shared.config.dir}/lib/global
${server.config.dir}/lib/global
You can refer to IBM websites to find out the exact location of ${shared.config.dir} and ${server.config.dir} in your Liberty installation
at here
Alternatively, you can place the log4j configuration file anywhere on your file system and add the following lines to your server.xml
<library id="log4jConfig">
<folder dir="/{directory containning log4j config file}" scanInterval="5s" />
</library>
<webApplication id="myapp" location="myapp.war" name="My App"/>
<classloader commonLibraryRef="log4jConfig"/>
</webApplication>
Set as a JVM argument inside the jvm.options file
-Dlog4j.configurationFile=file:/path/to/log4j2.xml
Package it inside your maven application war file under src/main/resources
Blow fix worked for me, from the application class or entry point use below code to reload the slf4j configuration.
private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(theClassfromwheregeneratinglogs.class);
static {
try {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(context);
// Call context.reset() to clear any previous configuration, e.g. default
// configuration. For multi-step configuration, omit calling context.reset().
context.reset();
configurator.doConfigure("/appserver/wlpusr/servers/applogs/logback.xml"); //This will reload the slf4j configuration from the given file location.
} catch (JoranException je) {
// StatusPrinter will handle this
}}

Where to put c3p0 dependency in Tomcat Container

I was under the impression that the libraries for both the database driver (postgres-x.x.jar'in my case) and the connection pooler (c3p0) had to reside in the container's lib (e.g. for Tomcat7, $CATALINA_HOME/lib).
However, the official C3p0 documentation doesn't provide any information with regards to put the connection pool's jar in the container vs having it in the application's war:
Place the files lib/c3p0-0.9.5.2.jar and lib/mchange-commons-java-0.2.11.jar somewhere in your CLASSPATH (or any other place where your application's classloader will find it). That's it!
A current issue in a new tomcat installation (java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector, when I have the mchange-commons-java dependency in the application's WAR and the c3p0 dependency in $CATALINA_HOME/lib) made me revisit this, but I can't find any authoritative information regarding where to put these libraries.
Usual application configuration
In my case the c3p0 configuration is made via spring bean within the application's classpath:
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
scope="singleton" destroy-method="close">
<property name="driverClass">
<value>org.postgresql.Driver</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.user}</value>
</property>
<property name="password">
<value>${jdbc.pw}</value>
</property>
...
<bean>
If I have multiple applications in the same Tomcat container, each will have one c3p0 bean like this contained in its war.
Memory Leaks?
The assumption for having the postgres.jar and c3p0.jar in the container's lib/ and not in the war was that the latter would cause memory leaks.
Leak in Postgres Driver
This user states that JDBC drivers register themselves in the JVM-wide singleton DriverManager which is shared by all web apps. If you have the same (as in class name) JDBC driver register twice from two different web apps, this might cause your problem. This is even more problematic if your web apps use different versions of the same JDBC driver.
Leak in c3p0
We moved c3p0 to $CATALINA_HOME/lib after this comment on Stackoverflow (we had a similar warning when undeploying an application).
Should they reside in Tomcat or the application's lib/ ?
Whether or not you need to put a jar in Tomcat's lib directory depends on whether Tomcat needs to know about it or not. And that depends on how you are configuring things.
As a general rule, if you are mentioning a class in a Tomcat config file, then that class (and those that it depends on) must be in Tomcat's lib directory.
For example, if you configure your DataSource in Tomcat's config files, then you need to make your driver class available to Tomcat. If instead you configure your DataSource within your application's code then you do not.
You do not specify how you are configuring C3P0, so we cannot tell you where the jar needs to be. Of course, if Tomcat needs it and it is not there, then you should expect to see an exception logged and things won't work properly.

Logback JNDI Connection Source

Logback allows you to define an DBAppender with a JNDI data source like so:
<connectionSource class="ch.qos.logback.core.db.JNDIConnectionSource">
<jndiLocation>java:comp/env/jdbc/dbLogging</jndiLocation>
</connectionSource>
I will be deploying this Java app as a WAR to Tomcat, but want DB logging to work when I'm testing locally in Eclipse or in a standalone Tomcat instance. Where/how do I configure the JNDI data source that Logback will use when it reads the above configuration? Thanks in advance!
In a standalone tomcat instance you would configure server.xml or context.xml in tomcat to define the data source as per normal (see here)
For using it locally in Eclipse, i.e. without a Web container, you'd change your connectionSource to something like:
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://host_name:3306/datebase_name</url>
<user>username</user>
<password>password</password>
</connectionSource>
See also, logback manual on appenders which has a tomcat example.

Name jdbc is not bound in this Context in Tomcat

I'm having trouble with JDBC Connection Pooling, I've done all the same with explained here: JNDI Resources HOW-TO, and here is also question (the same configuration with mine) regarding this topic which has not been resolved, I think.
What else should I consider?
I hope you have done the ResourceLink configuration to your webapp, too.
<Context>
...
<ResourceLink global="jdbc/MyDS" name="jdbc/MyDS" type="javax.sql.DataSource" />
...
</Context>
I had this error when the JDBC driver was deleted from classpath. In my setup, Tomcat expected libraries in a special directory, which was filled by Maven executing a special target. Whenever I cleaned and forgot to execute the Maven's target prior to running Tomcat, I had precisely this error.

How to deploy the same webapp with different logging? (Tomcat, Solr)

We are using multiple solr instances on tomcat but want that they log into different log files. How could we do this?
We are using the follwing xml file under tomcat/conf/Catalina/localhost to make it working:
<Context docBase="/pathtosolr/dist/apache-solr-1.4.0.war" debug="0" crossContext="true" >
<Environment name="solr/home" type="java.lang.String" value="/pathtosolr/solr" override="true" />
</Context>
Update: From Jems answer I found this documentation:
Tomcat offers a choice between settings for all applications or settings specifically for the Solr application.
To change logging settings for Solr only, edit tomcat/webapps/solr/WEB-INF/classes/logging.properties. You will need to create the classes directory and the logging.properties file. You can set levels from FINEST to SEVERE for a class or an entire package. Here are a couple of examples:
org.apache.commons.digester.Digester.level = FINEST
org.apache.solr.level = WARNING
Alternately, if you wish to change Tomcat’s JDK Logging API settings for every application in this instance of Tomcat, edit tomcat/conf/logging.properties.
See the documentation for the SLF4J Logging API for more information:
http://slf4j.org/docs.html
You might wanna take a look at this page: http://globalgateway.wordpress.com/2010/01/06/configuring-solr-1-4-logging-with-log4j-in-tomcat/
There seems to be no good solution:
2008 and 2010
except repacking the solr.war file with a different logging configuration file.
Update: see accepted answer!

Categories