- Хроники
- Chaotic Throne: High Five
- Grand Cursade
- Исходники
- Присутствуют
- Сборка
- L2JUnity
Пытаюсь переделать DatabaseFactory.java.
По дефолту юнити юзают c3p0, я же хочу использовать hikari, но не могу одуплить последние пару строк.
Подскажите, на что последние пару строк менять?
На что нужно заменить эти строки, чтобы затарахтело? Ничего подобного не нашел в hikari.
з.ы. На счет _source.getIdleTimeout(_databaseConfig.getIdleTimeout()); не уверен.
Возможно нужно будет указать так: _source.getIdleTimeout(0);
По дефолту юнити юзают c3p0, я же хочу использовать hikari, но не могу одуплить последние пару строк.
Java:
/**
* Gets the busy connection count.
* @return the busy connection count
* @throws SQLException the SQL exception
*/
public int getBusyConnectionCount() throws SQLException
{
return _source.getNumBusyConnectionsDefaultUser();
}
/**
* Gets the idle connection count.
* @return the idle connection count
* @throws SQLException the SQL exception
*/
public int getIdleConnectionCount() throws SQLException
{
return _source.getNumIdleConnectionsDefaultUser();
}
Java:
/*
* Copyright (C) 2004-2015 L2J Unity
*
* This file is part of L2J Unity.
*
* L2J Unity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* L2J Unity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.l2junity.commons.sql;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
import org.l2junity.commons.util.concurrent.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* This class manages the database connections.
*/
public final class DatabaseFactory
{
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseFactory.class);
private static DatabaseFactory _instance;
private ComboPooledDataSource _source;
private IDatabaseConfig _databaseConfig = null;
protected DatabaseFactory()
{
// visibility
}
public void setDatabaseConfig(IDatabaseConfig config)
{
_databaseConfig = config;
}
public void init() throws SQLException
{
if (_databaseConfig == null)
{
throw new NullPointerException("Database Config is not specified!");
}
try
{
// Sorry, no noob support. If you really want that crap, use ConfigLoader#loadImpl(PropertiesParser, PropertiesParser)
// if (_databaseConfig.getMaxConnections() < 2) { _databaseConfig.getMaxConnections() = 2; LOGGER.warn("A minimum of {} db connections are required.", _databaseConfig.getMaxConnections()); }
_source = new ComboPooledDataSource();
_source.setAutoCommitOnClose(true);
_source.setInitialPoolSize(10);
_source.setMinPoolSize(10);
_source.setMaxPoolSize(Math.max(10, _databaseConfig.getMaxConnections()));
_source.setAcquireRetryAttempts(0); // try to obtain connections indefinitely (0 = never quit)
_source.setAcquireRetryDelay(500); // 500 milliseconds wait before try to acquire connection again
_source.setCheckoutTimeout(0); // 0 = wait indefinitely for new connection
// if pool is exhausted
_source.setAcquireIncrement(5); // if pool is exhausted, get 5 more connections at a time
// cause there is a "long" delay on acquire connection
// so taking more than one connection at once will make connection pooling
// more effective.
_source.setIdleConnectionTestPeriod(3600); // test idle connection every 60 sec
_source.setMaxIdleTime(_databaseConfig.getMaxIdleTime()); // 0 = idle connections never expire
// *THANKS* to connection testing configured above
// but I prefer to disconnect all connections not used
// for more than 1 hour
// enables statement caching, there is a "semi-bug" in c3p0 0.9.0 but in 0.9.0.2 and later it's fixed
_source.setMaxStatementsPerConnection(100);
_source.setBreakAfterAcquireFailure(false); // never fail if any way possible
// setting this to true will make
// c3p0 "crash" and refuse to work
// till restart thus making acquire
// errors "FATAL" ... we don't want that
// it should be possible to recover
_source.setJdbcUrl(_databaseConfig.getJdbcURL());
_source.setUser(_databaseConfig.getUsername());
_source.setPassword(_databaseConfig.getPassword());
/* Test the connection */
_source.getConnection().close();
}
catch (SQLException x)
{
// re-throw the exception
throw x;
}
catch (Exception e)
{
throw new SQLException("Could not init DB connection:" + e.getMessage());
}
LOGGER.info("Initialized DB '{}' as user '{}'.", _databaseConfig.getJdbcURL(), _databaseConfig.getUsername());
}
private void closeSource()
{
if (_source != null)
{
_source.close();
}
// Is this really necessary?
_source = null;
}
/**
* Shutdown.
*/
public static void shutdown()
{
if (_instance == null)
{
return;
}
LOGGER.info("Shutting down.");
try
{
DatabaseFactory.getInstance().closeSource();
}
catch (Exception e)
{
LOGGER.warn("", e);
}
}
/**
* Gets the single instance of L2DatabaseFactory.
* @return single instance of L2DatabaseFactory
*/
public static DatabaseFactory getInstance()
{
synchronized (DatabaseFactory.class)
{
if (_instance == null)
{
_instance = new DatabaseFactory();
}
}
return _instance;
}
/**
* Gets the connection.
* @return the connection
*/
public Connection getConnection()
{
Connection con = null;
while (con == null)
{
try
{
con = _source.getConnection();
ThreadPool.schedule(new ConnectionCloser(con, new RuntimeException()), _databaseConfig.getConnectionCloseTime(), TimeUnit.MILLISECONDS);
}
catch (SQLException e)
{
LOGGER.warn("getConnection() failed, trying again", e);
}
}
return con;
}
/**
* The Class ConnectionCloser.
*/
private static final class ConnectionCloser implements Runnable
{
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionCloser.class);
/** The connection. */
private final Connection c;
/** The exception. */
private final RuntimeException exp;
/**
* Instantiates a new connection closer.
* @param con the con
* @param e the e
*/
public ConnectionCloser(Connection con, RuntimeException e)
{
c = con;
exp = e;
}
@Override
public void run()
{
try
{
if (!c.isClosed())
{
LOGGER.warn("Unclosed connection! Trace: {}", exp.getStackTrace()[1], exp);
}
}
catch (SQLException e)
{
LOGGER.warn("", e);
}
}
}
/**
* Gets the busy connection count.
* @return the busy connection count
* @throws SQLException the SQL exception
*/
public int getBusyConnectionCount() throws SQLException
{
return _source.getNumBusyConnectionsDefaultUser();
}
/**
* Gets the idle connection count.
* @return the idle connection count
* @throws SQLException the SQL exception
*/
public int getIdleConnectionCount() throws SQLException
{
return _source.getNumIdleConnectionsDefaultUser();
}
}
Java:
package l2j.commons.sql;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
import l2j.commons.util.concurrent.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.HikariDataSource;
/**
* This class manages the database connections.
*/
public final class DatabaseFactory
{
private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseFactory.class);
private static DatabaseFactory _instance;
private HikariDataSource _source;
private IDatabaseConfig _databaseConfig = null;
protected DatabaseFactory()
{
// visibility
}
public void setDatabaseConfig(IDatabaseConfig config)
{
_databaseConfig = config;
}
public void init() throws SQLException
{
if (_databaseConfig == null)
{
throw new NullPointerException("Database Config is not specified!");
}
try
{
_source = new HikariDataSource();
_source.setAutoCommit(true);
_source.setJdbcUrl(_databaseConfig.getJdbcURL());
_source.setUsername(_databaseConfig.getUsername());
_source.setPassword(_databaseConfig.getPassword());
_source.setMaximumPoolSize(Math.max(10, _databaseConfig.getMaxConnections()));
_source.getIdleTimeout(_databaseConfig.getIdleTimeout());
/* Test the connection */
_source.getConnection().close();
}
catch (SQLException x)
{
// re-throw the exception
throw x;
}
catch (Exception e)
{
throw new SQLException("Could not init DB connection:" + e.getMessage());
}
LOGGER.info("Initialized DB '{}' as user '{}'.", _databaseConfig.getJdbcURL(), _databaseConfig.getUsername());
}
private void closeSource()
{
if (_source != null)
{
_source.close();
}
// Is this really necessary?
_source = null;
}
/**
* Shutdown.
*/
public static void shutdown()
{
if (_instance == null)
{
return;
}
LOGGER.info("Shutting down.");
try
{
DatabaseFactory.getInstance().closeSource();
}
catch (Exception e)
{
LOGGER.warn("", e);
}
}
/**
* Gets the single instance of L2DatabaseFactory.
* @return single instance of L2DatabaseFactory
*/
public static DatabaseFactory getInstance()
{
synchronized (DatabaseFactory.class)
{
if (_instance == null)
{
_instance = new DatabaseFactory();
}
}
return _instance;
}
/**
* Gets the connection.
* @return the connection
*/
public Connection getConnection()
{
Connection con = null;
while (con == null)
{
try
{
con = _source.getConnection();
ThreadPool.schedule(new ConnectionCloser(con, new RuntimeException()), _databaseConfig.getConnectionCloseTime(), TimeUnit.MILLISECONDS);
}
catch (SQLException e)
{
LOGGER.warn("getConnection() failed, trying again", e);
}
}
return con;
}
/**
* The Class ConnectionCloser.
*/
private static final class ConnectionCloser implements Runnable
{
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionCloser.class);
/** The connection. */
private final Connection c;
/** The exception. */
private final RuntimeException exp;
/**
* Instantiates a new connection closer.
* @param con the con
* @param e the e
*/
public ConnectionCloser(Connection con, RuntimeException e)
{
c = con;
exp = e;
}
@Override
public void run()
{
try
{
if (!c.isClosed())
{
LOGGER.warn("Unclosed connection! Trace: {}", exp.getStackTrace()[1], exp);
}
}
catch (SQLException e)
{
LOGGER.warn("", e);
}
}
}
/**
* Gets the busy connection count.
* @return the busy connection count
* @throws SQLException the SQL exception
*/
public int getBusyConnectionCount() throws SQLException
{
return _source.getNumBusyConnectionsDefaultUser();
}
/**
* Gets the idle connection count.
* @return the idle connection count
* @throws SQLException the SQL exception
*/
public int getIdleConnectionCount() throws SQLException
{
return _source.getNumIdleConnectionsDefaultUser();
}
}
Java:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.zaxxer.hikari;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
import java.io.Closeable;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HikariDataSource extends HikariConfig implements DataSource, Closeable {
private static final Logger LOGGER = LoggerFactory.getLogger(HikariDataSource.class);
private final AtomicBoolean isShutdown = new AtomicBoolean();
private final HikariPool fastPathPool;
private volatile HikariPool pool;
public HikariDataSource() {
this.fastPathPool = null;
}
public HikariDataSource(HikariConfig configuration) {
configuration.validate();
configuration.copyStateTo(this);
LOGGER.info("{} - Starting...", configuration.getPoolName());
this.pool = this.fastPathPool = new HikariPool(this);
LOGGER.info("{} - Start completed.", configuration.getPoolName());
this.seal();
}
public Connection getConnection() throws SQLException {
if (this.isClosed()) {
throw new SQLException("HikariDataSource " + this + " has been closed.");
} else if (this.fastPathPool != null) {
return this.fastPathPool.getConnection();
} else {
HikariPool result = this.pool;
if (result == null) {
synchronized(this) {
result = this.pool;
if (result == null) {
this.validate();
LOGGER.info("{} - Starting...", this.getPoolName());
try {
this.pool = result = new HikariPool(this);
this.seal();
} catch (PoolInitializationException var5) {
if (var5.getCause() instanceof SQLException) {
throw (SQLException)var5.getCause();
}
throw var5;
}
LOGGER.info("{} - Start completed.", this.getPoolName());
}
}
}
return result.getConnection();
}
}
public Connection getConnection(String username, String password) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
public PrintWriter getLogWriter() throws SQLException {
HikariPool p = this.pool;
return p != null ? p.getUnwrappedDataSource().getLogWriter() : null;
}
public void setLogWriter(PrintWriter out) throws SQLException {
HikariPool p = this.pool;
if (p != null) {
p.getUnwrappedDataSource().setLogWriter(out);
}
}
public void setLoginTimeout(int seconds) throws SQLException {
HikariPool p = this.pool;
if (p != null) {
p.getUnwrappedDataSource().setLoginTimeout(seconds);
}
}
public int getLoginTimeout() throws SQLException {
HikariPool p = this.pool;
return p != null ? p.getUnwrappedDataSource().getLoginTimeout() : 0;
}
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}
public <T> T unwrap(Class<T> iface) throws SQLException {
if (iface.isInstance(this)) {
return this;
} else {
HikariPool p = this.pool;
if (p != null) {
DataSource unwrappedDataSource = p.getUnwrappedDataSource();
if (iface.isInstance(unwrappedDataSource)) {
return unwrappedDataSource;
}
if (unwrappedDataSource != null) {
return unwrappedDataSource.unwrap(iface);
}
}
throw new SQLException("Wrapped DataSource is not an instance of " + iface);
}
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
if (iface.isInstance(this)) {
return true;
} else {
HikariPool p = this.pool;
if (p != null) {
DataSource unwrappedDataSource = p.getUnwrappedDataSource();
if (iface.isInstance(unwrappedDataSource)) {
return true;
}
if (unwrappedDataSource != null) {
return unwrappedDataSource.isWrapperFor(iface);
}
}
return false;
}
}
public void setMetricRegistry(Object metricRegistry) {
boolean isAlreadySet = this.getMetricRegistry() != null;
super.setMetricRegistry(metricRegistry);
HikariPool p = this.pool;
if (p != null) {
if (isAlreadySet) {
throw new IllegalStateException("MetricRegistry can only be set one time");
}
p.setMetricRegistry(super.getMetricRegistry());
}
}
public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory) {
boolean isAlreadySet = this.getMetricsTrackerFactory() != null;
super.setMetricsTrackerFactory(metricsTrackerFactory);
HikariPool p = this.pool;
if (p != null) {
if (isAlreadySet) {
throw new IllegalStateException("MetricsTrackerFactory can only be set one time");
}
p.setMetricsTrackerFactory(super.getMetricsTrackerFactory());
}
}
public void setHealthCheckRegistry(Object healthCheckRegistry) {
boolean isAlreadySet = this.getHealthCheckRegistry() != null;
super.setHealthCheckRegistry(healthCheckRegistry);
HikariPool p = this.pool;
if (p != null) {
if (isAlreadySet) {
throw new IllegalStateException("HealthCheckRegistry can only be set one time");
}
p.setHealthCheckRegistry(super.getHealthCheckRegistry());
}
}
public boolean isRunning() {
return this.pool != null && this.pool.poolState == 0;
}
public HikariPoolMXBean getHikariPoolMXBean() {
return this.pool;
}
public HikariConfigMXBean getHikariConfigMXBean() {
return this;
}
public void evictConnection(Connection connection) {
HikariPool p;
if (!this.isClosed() && (p = this.pool) != null && connection.getClass().getName().startsWith("com.zaxxer.hikari")) {
p.evictConnection(connection);
}
}
public void close() {
if (!this.isShutdown.getAndSet(true)) {
HikariPool p = this.pool;
if (p != null) {
try {
LOGGER.info("{} - Shutdown initiated...", this.getPoolName());
p.shutdown();
LOGGER.info("{} - Shutdown completed.", this.getPoolName());
} catch (InterruptedException var3) {
LOGGER.warn("{} - Interrupted during closing", this.getPoolName(), var3);
Thread.currentThread().interrupt();
}
}
}
}
public boolean isClosed() {
return this.isShutdown.get();
}
public String toString() {
return "HikariDataSource (" + this.pool + ")";
}
}
з.ы. На счет _source.getIdleTimeout(_databaseConfig.getIdleTimeout()); не уверен.
Возможно нужно будет указать так: _source.getIdleTimeout(0);
Последнее редактирование: