релиз Android 6.0 (API Level 23) удаляет поддержку для HTTP-клиента Apache. Следовательно, вы не можете использовать эту библиотеку непосредственно в API 23. Но есть способ ее использования. Добавьте useLibrary 'org.apache.http.legacy' в ваш файл build.gradle, как показано ниже -
android {
useLibrary 'org.apache.http.legacy'
}
Если это не сработает, вы можете применить следующий хак -
- Скопируйте файл org.apache.http.legacy.jar, который находится в каталоге / platform / android-23 / optional вашего каталога Android SDK в папку вашего приложения / libs вашего проекта.
- Теперь добавьте файлы компиляции ('libs /org.apache.http.legacy.jar ') внутри зависимых {} разделов файла build.gradle.
Начиная с версии 6.0.24, Tomcat поставляется с функцией обнаружения утечки памяти , что, в свою очередь, может привести к появлению подобных предупреждающих сообщений, когда в файле [app1] для веб-сервера есть JDBC 4.0-совместимый драйвер, auto- регистрирует сам во время запуска webapp, используя ServiceLoader
API , но который сам не отключился deregister во время отключения Webapp. Это сообщение является чисто неофициальным, Tomcat уже принял меры по предотвращению утечки памяти.
Что вы можете сделать?
/WEB-INF/lib
, но только на сервере /lib
. Если вы все еще сохраняете его в файле /WEB-INF/lib
в webapp, вам необходимо зарегистрировать его вручную и отменить его с помощью ServletContextListener
. OutOfMemoryError
во время горячих рассылок Tomcat. /lib
Tomcat и подключите пул данных к источнику данных для управления драйвером. Обратите внимание, что встроенный DBCP от Tomcat не отменяет регистрацию драйверов должным образом при закрытии. См. Также ошибку DBCP-322 , которая закрыта как WONTFIX. Вы хотели бы заменить DBCP другим пулом соединений, который лучше выполняет свою работу, чем DBCP. Например, HikariCP , BoneCP или, возможно, Tomcat JDBC Pool . В вашем контексте контекст-слушатель контекстного методаDestroyed () вручную отмените регистрацию драйверов:
// This manually deregisters JDBC driver, which prevents Tomcat 7 from complaining about memory leaks wrto this class
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
LOG.log(Level.INFO, String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
LOG.log(Level.SEVERE, String.format("Error deregistering driver %s", driver), e);
}
}
Я столкнулся с этой проблемой, когда я развертывал приложение Grails на AWS. Это вопрос драйвера JDBC по умолчанию для драйвера org.h2. Как вы можете видеть это в Datasource.groovy внутри вашей папки конфигурации. Как вы можете видеть ниже:
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver" // make this one comment
username = "sa"
password = ""
}
Прокомментируйте эти строки везде, где упоминается org.h2.Driver в файле datasource.groovy, если вы не используете эту базу данных. В противном случае вам нужно загрузить этот файл jar базы данных.
Спасибо.
Это прослушиватель, который я написал для решения проблемы: он автоматически определяет, был ли водитель зарегистрирован и действует соответственно .it
Важно: это должен использоваться ТОЛЬКО, когда баннер драйвера развертывается в WEB-INF / lib, а не в Tomcat / lib, как многие из них предлагают, так что каждое приложение может позаботиться о своем собственном драйвере и запустить на нетронутом Tomcat. Таким образом, это должно быть IMHO.
Просто настройте слушателя в вашем web.xml перед любым другим и наслаждайтесь.
добавить в верхней части web.xml :
<listener>
<listener-class>utils.db.OjdbcDriverRegistrationListener</listener-class>
</listener>
сохранить как utils / db / OjdbcDriverRegistrationListener.java :
package utils.db;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import oracle.jdbc.OracleDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Registers and unregisters the Oracle JDBC driver.
*
* Use only when the ojdbc jar is deployed inside the webapp (not as an
* appserver lib)
*/
public class OjdbcDriverRegistrationListener implements ServletContextListener {
private static final Logger LOG = LoggerFactory
.getLogger(OjdbcDriverRegistrationListener.class);
private Driver driver = null;
/**
* Registers the Oracle JDBC driver
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
this.driver = new OracleDriver(); // load and instantiate the class
boolean skipRegistration = false;
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver instanceof OracleDriver) {
OracleDriver alreadyRegistered = (OracleDriver) driver;
if (alreadyRegistered.getClass() == this.driver.getClass()) {
// same class in the VM already registered itself
skipRegistration = true;
this.driver = alreadyRegistered;
break;
}
}
}
try {
if (!skipRegistration) {
DriverManager.registerDriver(driver);
} else {
LOG.debug("driver was registered automatically");
}
LOG.info(String.format("registered jdbc driver: %s v%d.%d", driver,
driver.getMajorVersion(), driver.getMinorVersion()));
} catch (SQLException e) {
LOG.error(
"Error registering oracle driver: " +
"database connectivity might be unavailable!",
e);
throw new RuntimeException(e);
}
}
/**
* Deregisters JDBC driver
*
* Prevents Tomcat 7 from complaining about memory leaks.
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
if (this.driver != null) {
try {
DriverManager.deregisterDriver(driver);
LOG.info(String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
LOG.warn(
String.format("Error deregistering driver %s", driver),
e);
}
this.driver = null;
} else {
LOG.warn("No driver to deregister");
}
}
}
@WebListener
и опустить конфигурацию web.xml
.
– Basil Bourque
12 May 2016 в 03:02
Я обнаружил, что реализация простого метода destroy () для деинсталляции любых драйверов JDBC прекрасно работает.
/**
* Destroys the servlet cleanly by unloading JDBC drivers.
*
* @see javax.servlet.GenericServlet#destroy()
*/
public void destroy() {
String prefix = getClass().getSimpleName() +" destroy() ";
ServletContext ctx = getServletContext();
try {
Enumeration<Driver> drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()) {
DriverManager.deregisterDriver(drivers.nextElement());
}
} catch(Exception e) {
ctx.log(prefix + "Exception caught while deregistering JDBC drivers", e);
}
ctx.log(prefix + "complete");
}
Я нашел ту же проблему с Tomcat версии 6.026.
Я использовал Mysql JDBC.jar в библиотеке WebAPP, а также в TOMCAT Lib.
Чтобы исправить это, удалив Jar из папки TOMCAT lib.
Итак, я понимаю, что TOMCAT правильно обрабатывает утечку памяти JDBC. Но если JSB JQB JQB дублируется в WebApp и Tomcat Lib, Tomcat сможет обрабатывать только банку в папке Tomcat Lib.
У меня была аналогичная проблема, но дополнительно я получал ошибку Java Heap Space в любое время, когда я модифицировал / сохранил JSP-страницы с сервером Tomcat, поэтому контекст не был полностью перезаряжен.
Мои версии были Apache Tomcat 6.0.29 и JDK 6u12.
Обновление JDK до 6u21, как предлагается в Ссылки в разделе URL http: / /wiki.apache.org/tomcat/MemoryLeakProtection решил проблему Java Heap Space (контекст теперь перезагружает OK), хотя ошибка драйвера JDBC все еще появляется.
Удаляет приложение (tomcat6). Файлы conf сохраняются. Это как-то ломается. Я не уверен, как это делается.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mywebsite</groupId>
<artifactId>emusicstore</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
MyWebAppContextListener.java
package com.emusicstore.utils;
import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
public class MyWebAppContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("************** Starting up! **************");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("************** Shutting down! **************");
System.out.println("Destroying Context...");
System.out.println("Calling MySQL AbandonedConnectionCleanupThread checkedShutdown");
AbandonedConnectionCleanupThread.checkedShutdown();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
try {
System.out.println("Deregistering JDBC driver {}");
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
System.out.println("Error deregistering JDBC driver {}");
ex.printStackTrace();
}
} else {
System.out.println("Not deregistering JDBC driver {} as it does not belong to this webapp's ClassLoader");
}
}
}
}
web.xml
<?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_4_0.xsd"
version="4.0">
<listener>
<listener-class>com.emusicstore.utils.MyWebAppContextListener</listener-class>
</listener>
<!-- ... -->
</web-app>
Источник , который вдохновил меня на исправление этой ошибки.
Это чисто проблема регистрации / снятия регистрации с сервера в mysql`s driver или tomcats webapp-classloader. Скопируйте mysql-драйвер в папку tomcats lib (так что он загружен jvm напрямую, а не tomcat), и сообщение исчезнет. Это приводит к выгрузке драйвера mysql jdbc только при отключении JVM, и никто не заботится о утечке памяти.
Если вы получаете это сообщение от измененного военного изменения Maven, укажите область действия драйвера JDBC и поместите его копию в каталог lib. Например:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
<!-- put a copy in /usr/share/tomcat7/lib -->
<scope>provided</scope>
</dependency>
lib
). – lapo 25 November 2014 в 10:42