[Вопрос] HikariCP

Psycho

Жнец
Модератор
Орден Золотого Заката
Победитель в номинации 2023
Победитель в номинации 2022
Победитель в номинации 2021
Участник Новогоднего Фонда 2021
Неукротимое пламя
Старожил II степени
Победитель в номинации 2020
Победитель в номинации 2019
Знаток великого письма
Знаток письма
Веселый флудер
Мастер реакций
Любитель реакций
Знаток Lineage2
Старожил I степени
Победитель в номинации 2017
Победитель в номинации 2016
Медаль за активность на Форуме
За веру и верность форуму
Сообщения
4 768
Розыгрыши
1
Решения
3
Репутация
4 398
Реакции
3 186
Баллы
2 543
Хроники
  1. Chaotic Throne: High Five
  2. Grand Cursade
Исходники
Присутствуют
Сборка
L2JUnity
Пытаюсь переделать DatabaseFactory.java.
По дефолту юнити юзают 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 + ")";
    }
}
Подскажите, на что последние пару строк менять?
На что нужно заменить эти строки, чтобы затарахтело? Ничего подобного не нашел в hikari.
з.ы. На счет _source.getIdleTimeout(_databaseConfig.getIdleTimeout()); не уверен.
Возможно нужно будет указать так: _source.getIdleTimeout(0);
 
Последнее редактирование:
В лыже это выглядит так, но мне же нужно сохранить реализацию конфигов:
Java:
package com.l2jserver.commons.database.pool.impl;

import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

import javax.sql.DataSource;

import com.zaxxer.hikari.HikariDataSource;

/**
 * HikariCP Pooled Connection Factory implementation.
 * @author Zoey76
 * @version 2.6.1.0
 */
public class HikariCPPooledConnectionFactory implements PooledConnectionFactory {
    
    private static final int MAX_LIFETIME = 15;
    
    private final HikariDataSource _dataSource;
    
    public HikariCPPooledConnectionFactory(String driver, String url, String user, String password, int maxPoolSize, int maxIdleTime) {
        _dataSource = new HikariDataSource();
        _dataSource.setDriverClassName(driver);
        _dataSource.setJdbcUrl(url);
        _dataSource.setUsername(user);
        _dataSource.setPassword(password);
        _dataSource.setMaximumPoolSize(maxPoolSize);
        _dataSource.setIdleTimeout(SECONDS.toMillis(maxIdleTime));
        _dataSource.setMaxLifetime(MINUTES.toMillis(MAX_LIFETIME));
    }
    
    @Override
    public void close() {
        try {
            _dataSource.close();
        } catch (Exception e) {
            LOG.warn("There has been a problem closing the data source!", e);
        }
    }
    
    @Override
    public DataSource getDataSource() {
        return _dataSource;
    }
}
 
Посмотрите в сторону метрик которые расположены в пакете hikari. Там можно как-то попытаться их вытащить и юзать, возможно нужно будет заюзать рефлексию. Сами эти метрики используют метод getPoolStats в HikariPool, который собственно смотрит на все коннекты.
Можно конечно вытащить пулл через рефлексию с ДСа, далше дёрнуть этот же метод getPoolStats и получить стату, но имо, лучше первый вариант.
PS: начните с метода setMetricsTrackerFactory на ДСе
там даже через конфиг можно поставить метрику
 
Последнее редактирование:
Посмотрите в сторону метрик которые расположены в пакете hikari. Там можно как-то попытаться их вытащить и юзать, возможно нужно будет заюзать рефлексию. Сами эти метрики используют метод getPoolStats в HikariPool, который собственно смотрит на все коннекты.
Можно конечно вытащить пулл через рефлексию с ДСа, далше дёрнуть этот же метод getPoolStats и получить стату, но имо, лучше первый вариант.
Для начала пойду погуглю: метрик и рефлексию. :D
 
Не хотелось бы углубляться в изучение всей этой дичи ради пары строк.
 
Последнее редактирование:
Я ничего не понял если честно, хотя что Таке метрики и рефлексия вроде понимаю))
 
index.webp


Короче прикрутил, но еррор тот же бьет, что и с c3p0:
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.setDriverClassName(_databaseConfig.getDriver());
            _source.setJdbcUrl(_databaseConfig.getJdbcURL());
            _source.setUsername(_databaseConfig.getUsername());
            _source.setPassword(_databaseConfig.getPassword());
            _source.setMaximumPoolSize(Math.max(10, _databaseConfig.getMaxConnections()));
            _source.setIdleTimeout(Math.max(0,_databaseConfig.getMaxIdleTime()));

            /* 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);
            }
        }
    }
}
Код:
[main] INFO l2j.commons.util.CommonUtil - -----------------------------------------------------------------------------------------------------------=[ Database ]
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[main] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization.
java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:232)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:165)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1199)
    at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:560)
    at org.mariadb.jdbc.MariaDbConnection.newConnection(MariaDbConnection.java:174)
    at org.mariadb.jdbc.Driver.connect(Driver.java:92)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
    at l2j.commons.sql.DatabaseFactory.init(DatabaseFactory.java:53)
    at l2j.commons.util.AppInit.defaultInit(AppInit.java:115)
    at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:58)
    at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:934)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:850)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:507)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1195)
    ... 14 more
[main] ERROR l2j.commons.util.AppInit - Could not initialize database!
java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:232)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:165)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1199)
    at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:560)
    at org.mariadb.jdbc.MariaDbConnection.newConnection(MariaDbConnection.java:174)
    at org.mariadb.jdbc.Driver.connect(Driver.java:92)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
    at l2j.commons.sql.DatabaseFactory.init(DatabaseFactory.java:53)
    at l2j.commons.util.AppInit.defaultInit(AppInit.java:115)
    at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:58)
    at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:934)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:850)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:507)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1195)
    ... 14 more
[main] INFO l2j.commons.lang.management.ShutdownManager - A shutdown command was issued: missing critical functionality!
[CumulativeShutdownHook] INFO l2j.commons.util.CommonUtil - ---------------------------------------------------------------------------------------------------=[ Shutdown Hook(s) ]
[CumulativeShutdownHook] INFO l2j.commons.sql.DatabaseFactory - Shutting down.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool - Shutting down.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... executing 1 scheduled tasks.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... executing 0 tasks.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... success: true in 0 ms.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... 0 scheduled tasks left.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... 0 tasks left.
Как это лечить вообще? Пароли/юзеры правильные.
 
Последнее редактирование:
  • Ха-ха-ха
Реакции: kick
Метод init() ранее был исполнен?
Без понятия. Пробовал на не тронутых сурсах запускать, та же ошибка. Даже если указываю не root юзера, он всё равно стучится в root@localhost.
Я блеать вообще нихера не понимаю что происходит с этим дерьмом. Любой другой сурс на изи стартует.

Похоже что этот сурс меня тупо тролит...

Сбилдил и запустил батником, получаю вот такое:
Код:
Starting L2J Login Server.

[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------=[ Configuration
]
[main] WARN l2j.commons.config.ConfigPropertiesLoader - Property key 'Driver' is
missing, using default value!
[main] INFO l2j.commons.config.ConfigManager - Loaded 3 config file(s).

[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------=[ Shutdown Hook
]
[main] INFO l2j.commons.lang.management.ShutdownManager - Initialized.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
------------------------------------------------------------=[ Deadlock Detector
]
[main] INFO l2j.commons.lang.management.DeadlockDetector - Disabled.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
---------------------------------------------------------------=[ Thread Pool(s)
]
[main] INFO l2j.commons.util.concurrent.ThreadPool - Initialized with
[main] INFO l2j.commons.util.concurrent.ThreadPool -    ... 4/4 scheduled thread
(s).
[main] INFO l2j.commons.util.concurrent.ThreadPool -    ... 4/4 thread(s).
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
---------------------------------------------------------------------=[ Database
]
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.

[main] INFO l2j.commons.sql.DatabaseFactory - Initialized DB 'jdbc:mysql://local
host/l2j?useSSL=false&serverTimezone=Europe/Moscow' as user 'root'.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
------------------------------------------------------------------=[ Application
]
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------------=[ Manager
]
[main] INFO l2j.loginserver.LoginController - Loading LoginController...
[main] INFO l2j.loginserver.LoginController - Cached 10 KeyPairs for RSA communi
cation
[main] INFO l2j.loginserver.LoginController - Stored 20 keys for Blowfish commun
ication
[main] INFO l2j.loginserver.GameServerTable - Loaded 1 registered Game Servers
[main] INFO l2j.loginserver.GameServerTable - Cached 10 RSA keys for Game Server
communication.
[main] INFO l2j.loginserver.GameServerTable - Loaded 126 server names
[main] INFO l2j.loginserver.L2LoginServer - Loaded 2 IP Bans.
[main] INFO l2j.loginserver.L2LoginServer - Listening for GameServers on 127.0.0
.1:9014
[main] INFO l2j.loginserver.L2LoginServer - L2LoginServer: is now listening on:
*:2106
[main] WARN l2j.commons.util.AppInit - Exception occured on thread: Thread[main,
5,main]
java.lang.NullPointerException
        at l2j.commons.util.jar.VersionInfo.<init>(VersionInfo.java:43)
        at l2j.commons.util.jar.VersionInfo.of(VersionInfo.java:110)
        at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:140)
        at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
:For What:
 
Последнее редактирование:
@Psycho, что в ниже указанных строках? Откуда там NPE?
Код:
java.lang.NullPointerException
        at l2j.commons.util.jar.VersionInfo.<init>(VersionInfo.java:43)
        at l2j.commons.util.jar.VersionInfo.of(VersionInfo.java:110)
        at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:140)
        at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
 
@Psycho, что в ниже указанных строках? Откуда там NPE?
Код:
java.lang.NullPointerException
        at l2j.commons.util.jar.VersionInfo.<init>(VersionInfo.java:43)
        at l2j.commons.util.jar.VersionInfo.of(VersionInfo.java:110)
        at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:140)
        at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
Java:
package l2j.commons.util.jar;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;

/**
* A simple class to gather the manifest version information of JAR files.
* @author lord_rex
*/
public final class VersionInfo
{
    /** A default string for the cases when version info cannot be retrieved. (IDE Mode) */
    private static final String IDE_MODE = "Version Info - IDE Mode.";
   
    private String _filename = null;
    private final Map<String, String> _manifestAttributes;
   
    /**
     * Gather version information from the class.
     * @param clazz
     */
    public VersionInfo(final Class<?> clazz)
    {
        _manifestAttributes = new HashMap<>();
       
        final File file = Locator.getClassSource(clazz);
        if (!file.isFile())
        {
            return;
        }
       
        final String filename = file.getName();
        _filename = filename.substring(0, filename.lastIndexOf("."));
       
        try (final JarFile jarFile = new JarFile(file);)
        {
            final Attributes attributes = jarFile.getManifest().getMainAttributes();
            attributes.entrySet().forEach((entry) -> _manifestAttributes.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())));
        }
        catch (IOException e)
        {
            // ignore, IDE mode, etc...
        }
    }
   
    /**
     * Gets a manifest from the manifest attribute map, shows {@link #IDE_MODE} if null.
     * @param name
     * @return manifest info
     */
    public String getManifest(final String name)
    {
        return _manifestAttributes.getOrDefault(name, IDE_MODE);
    }
   
    /**
     * Gets a pretty formatted class info.
     * @return formatted class info
     */
    public String getFormattedClassInfo()
    {
        if ((_filename == null) || _filename.isEmpty())
        {
            return IDE_MODE;
        }
       
        final StringBuilder sb = new StringBuilder();
       
        sb.append(_filename).append(": ");
        sb.append(getManifest(VersionInfoManifest.GIT_HASH_SHORT)).append(", ");
        sb.append(getManifest(VersionInfoManifest.GIT_COMMIT_COUNT)).append(", ");
        sb.append(getManifest(VersionInfoManifest.IMPLEMENTATION_TIME));
        sb.append(" [ ").append(getManifest(VersionInfoManifest.GIT_BRANCH)).append(" ]");
       
        return sb.toString();
    }
   
    /**
     * Standard manifest attribute constants.
     * @author lord_rex
     */
    public interface VersionInfoManifest
    {
        String CREATED_BY = "Created-By";
        String BUILT_BY = "Built-By";
        String IMPLEMENTATION_URL = "Implementation-URL";
        String IMPLEMENTATION_TIME = "Implementation-Time";
        String GIT_BRANCH = "Git-Branch";
        String GIT_HASH_FULL = "Git-Hash-Full";
        String GIT_HASH_SHORT = "Git-Hash-Short";
        String GIT_COMMIT_COUNT = "Git-Commit-Count";
    }
   
    /**
     * Gather version info of multiply classes. You can use it to gather information of Commons/Network/MMOCore/GeoDriver/ETC from LS/GS or any other application.
     * @param classes
     * @return string array of version info
     */
    public static List<String> of(final Class<?>... classes)
    {
        List<String> versions = new ArrayList<>();
        for (final Class<?> clazz : classes)
        {
            final VersionInfo versionInfo = new VersionInfo(clazz);
            versions.add(versionInfo.getFormattedClassInfo());
        }
       
        return versions;
    }
}
Java:
package l2j.loginserver;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;

import l2j.commons.lang.management.ShutdownManager;
import l2j.commons.lang.management.TerminationStatus;
import l2j.commons.util.AppInit;
import l2j.commons.util.AppInit.ApplicationMode;
import l2j.commons.util.CommonUtil;
import l2j.commons.util.jar.VersionInfo;
import l2j.loginserver.config.EmailConfig;
import l2j.loginserver.config.LoginConfigMarker;
import l2j.loginserver.config.LoginServerConfig;
import l2j.loginserver.config.MMOCoreConfig;
import l2j.loginserver.mail.MailSystem;
import l2j.loginserver.network.L2LoginClient;
import l2j.loginserver.network.L2LoginPacketHandler;
import l2j.commons.network.MMOClient;
import l2j.commons.network.SelectorConfig;
import l2j.commons.network.SelectorThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author KenM
*/
public final class L2LoginServer
{
    private static final Logger LOGGER = LoggerFactory.getLogger(L2LoginServer.class);
   
    public static final int PROTOCOL_REV = 0x0106;
    private static L2LoginServer _instance;
    private GameServerListener _gameServerListener;
    private SelectorThread<L2LoginClient> _selectorThread;
    private Thread _restartLoginServer;
   
    public static void main(String[] args)
    {
        new L2LoginServer();
    }
   
    public static L2LoginServer getInstance()
    {
        return _instance;
    }
   
    private L2LoginServer()
    {
        _instance = this;
       
        AppInit.defaultInit(ApplicationMode.LOGIN, LoginConfigMarker.class.getPackage().getName(), LoginThreadPools.class, LoginDatabaseConfig.class);
       
        CommonUtil.printSection("Manager");
       
        try
        {
            LoginController.load();
        }
        catch (GeneralSecurityException e)
        {
            LOGGER.error("FATAL: Failed initializing LoginController. Reason: " + e.getMessage(), e);
            ShutdownManager.exit(TerminationStatus.ENVIRONMENT_MISSING_COMPONENT_OR_SERVICE);
            return;
        }
       
        GameServerTable.getInstance();
       
        loadBanFile();
       
        if (EmailConfig.EMAIL_SYS_ENABLED)
        {
            MailSystem.getInstance();
        }
       
        InetAddress bindAddress = null;
        if (!LoginServerConfig.LOGIN_BIND_ADDRESS.equals("*"))
        {
            try
            {
                bindAddress = InetAddress.getByName(LoginServerConfig.LOGIN_BIND_ADDRESS);
            }
            catch (UnknownHostException e)
            {
                LOGGER.warn("WARNING: The LoginServer bind address is invalid, using all avaliable IPs. Reason: " + e.getMessage(), e);
            }
        }
       
        final SelectorConfig sc = new SelectorConfig();
        sc.MAX_READ_PER_PASS = MMOCoreConfig.MMO_MAX_READ_PER_PASS;
        sc.MAX_SEND_PER_PASS = MMOCoreConfig.MMO_MAX_SEND_PER_PASS;
        sc.SLEEP_TIME = MMOCoreConfig.MMO_SELECTOR_SLEEP_TIME;
        sc.HELPER_BUFFER_COUNT = MMOCoreConfig.MMO_HELPER_BUFFER_COUNT;
       
        final L2LoginPacketHandler lph = new L2LoginPacketHandler();
        final SelectorHelper sh = new SelectorHelper();
        try
        {
            _selectorThread = new SelectorThread<>(sc, sh, lph, sh, sh);
        }
        catch (IOException e)
        {
            LOGGER.error("FATAL: Failed to open Selector. Reason: " + e.getMessage(), e);
            ShutdownManager.exit(TerminationStatus.ENVIRONMENT_MISSING_COMPONENT_OR_SERVICE);
            return;
        }
       
        try
        {
            _gameServerListener = new GameServerListener();
            _gameServerListener.start();
            LOGGER.info("Listening for GameServers on " + LoginServerConfig.GAME_SERVER_LOGIN_HOST + ":" + LoginServerConfig.GAME_SERVER_LOGIN_PORT);
        }
        catch (IOException e)
        {
            LOGGER.error("FATAL: Failed to start the Game Server Listener. Reason: " + e.getMessage(), e);
            ShutdownManager.exit(TerminationStatus.ENVIRONMENT_MISSING_COMPONENT_OR_SERVICE);
            return;
        }
       
        try
        {
            _selectorThread.openServerSocket(bindAddress, LoginServerConfig.PORT_LOGIN);
            _selectorThread.start();
            LOGGER.info(getClass().getSimpleName() + ": is now listening on: " + LoginServerConfig.LOGIN_BIND_ADDRESS + ":" + LoginServerConfig.PORT_LOGIN);
        }
        catch (IOException e)
        {
            LOGGER.error("FATAL: Failed to open server socket. Reason: " + e.getMessage(), e);
            ShutdownManager.exit(TerminationStatus.ENVIRONMENT_MISSING_COMPONENT_OR_SERVICE);
            return;
        }
       
        AppInit.defaultPostInit(VersionInfo.of(AppInit.class, L2LoginServer.class, MMOClient.class), LoginUPnPConfig.class);
    }
   
    public GameServerListener getGameServerListener()
    {
        return _gameServerListener;
    }
   
    private void loadBanFile()
    {
        final File bannedFile = new File("./banned_ip.cfg");
        if (bannedFile.exists() && bannedFile.isFile())
        {
            try (FileInputStream fis = new FileInputStream(bannedFile);
                InputStreamReader is = new InputStreamReader(fis);
                LineNumberReader lnr = new LineNumberReader(is))
            {
                //@formatter:off
                lnr.lines()
                    .map(String::trim)
                    .filter(l -> !l.isEmpty() && (l.charAt(0) != '#'))
                    .forEach(line -> {
                        String[] parts = line.split("#", 2); // address[ duration][ # comments]
                        line = parts[0];
                        parts = line.split("\\s+"); // durations might be aligned via multiple spaces
                        String address = parts[0];
                        long duration = 0;
                       
                        if (parts.length > 1)
                        {
                            try
                            {
                                duration = Long.parseLong(parts[1]);
                            }
                            catch (NumberFormatException nfe)
                            {
                                LOGGER.warn("Skipped: Incorrect ban duration (" + parts[1] + ") on (" + bannedFile.getName() + "). Line: " + lnr.getLineNumber());
                                return;
                            }
                        }
                       
                        try
                        {
                            LoginController.getInstance().addBanForAddress(address, duration);
                        }
                        catch (UnknownHostException e)
                        {
                            LOGGER.warn("Skipped: Invalid address (" + address + ") on (" + bannedFile.getName() + "). Line: " + lnr.getLineNumber());
                        }
                    });
                //@formatter:on
            }
            catch (IOException e)
            {
                LOGGER.warn("Error while reading the bans file (" + bannedFile.getName() + "). Details: " + e.getMessage(), e);
            }
            LOGGER.info("Loaded " + LoginController.getInstance().getBannedIps().size() + " IP Bans.");
        }
        else
        {
            LOGGER.warn("IP Bans file (" + bannedFile.getName() + ") is missing or is a directory, skipped.");
        }
       
        if (LoginServerConfig.LOGIN_SERVER_SCHEDULE_RESTART)
        {
            LOGGER.info("Scheduled LS restart after " + LoginServerConfig.LOGIN_SERVER_SCHEDULE_RESTART_TIME + " hours");
            _restartLoginServer = new LoginServerRestart();
            _restartLoginServer.setDaemon(true);
            _restartLoginServer.start();
        }
    }
   
    class LoginServerRestart extends Thread
    {
        public LoginServerRestart()
        {
            setName("LoginServerRestart");
        }
       
        @Override
        public void run()
        {
            while (!isInterrupted())
            {
                try
                {
                    Thread.sleep(LoginServerConfig.LOGIN_SERVER_SCHEDULE_RESTART_TIME * 3600000);
                }
                catch (InterruptedException e)
                {
                    return;
                }
                shutdown(true);
            }
        }
    }
   
    public void shutdown(boolean restart)
    {
        Runtime.getRuntime().exit(restart ? 2 : 0);
    }
}
Инфо:
screen.webp

screen.webp

Логин: screen.webp
 
protected DatabaseFactory()
{
this.init();
}
Подтянет конфигурацию и коннект пойдёт правильный.(если остальной код правильный конечно)
Со второй ошибкой видимо нет манифест файла , хотя я с телефона строки не умею считать. Почему он не билдится в архив когда должен - другой вопрос )
 
protected DatabaseFactory()
{
this.init();
}
Подтянет конфигурацию и коннект пойдёт правильный.(если остальной код правильный конечно)
Со второй ошибкой видимо нет манифест файла , хотя я с телефона строки не умею считать. Почему он не билдится в архив когда должен - другой вопрос )
Да, добавил манифест, и всё отлично запускается через батник. Как поправить, чтобы и через idea запускалось, не подскажешь? А то как-то не удобно постоянно артефакты билдить и запускать батником для проверки.
Java:
Starting L2J Login Server.

[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------=[ Configuration
]
[main] WARN l2j.commons.config.ConfigPropertiesLoader - Property key 'Driver' is
missing, using default value!
[main] INFO l2j.commons.config.ConfigManager - Loaded 3 config file(s).
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------=[ Shutdown Hook
]
[main] INFO l2j.commons.lang.management.ShutdownManager - Initialized.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
------------------------------------------------------------=[ Deadlock Detector
]
[main] INFO l2j.commons.lang.management.DeadlockDetector - Disabled.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
---------------------------------------------------------------=[ Thread Pool(s)
]
[main] INFO l2j.commons.util.concurrent.ThreadPool - Initialized with
[main] INFO l2j.commons.util.concurrent.ThreadPool -    ... 4/4 scheduled thread
(s).
[main] INFO l2j.commons.util.concurrent.ThreadPool -    ... 4/4 thread(s).
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
---------------------------------------------------------------------=[ Database
]
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.

[main] INFO l2j.commons.sql.DatabaseFactory - Initialized DB 'jdbc:mysql://local
host/l2j?useSSL=false&serverTimezone=Europe/Moscow' as user 'root'.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
------------------------------------------------------------------=[ Application
]
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------------=[ Manager
]
[main] INFO l2j.loginserver.LoginController - Loading LoginController...
[main] INFO l2j.loginserver.LoginController - Cached 10 KeyPairs for RSA communi
cation
[main] INFO l2j.loginserver.LoginController - Stored 20 keys for Blowfish commun
ication
[main] INFO l2j.loginserver.GameServerTable - Loaded 1 registered Game Servers
[main] INFO l2j.loginserver.GameServerTable - Cached 10 RSA keys for Game Server
communication.
[main] INFO l2j.loginserver.GameServerTable - Loaded 126 server names
[main] INFO l2j.loginserver.L2LoginServer - Loaded 2 IP Bans.
[main] INFO l2j.loginserver.L2LoginServer - Listening for GameServers on 127.0.0
.1:9014
[main] INFO l2j.loginserver.L2LoginServer - L2LoginServer: is now listening on:
*:2106
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
-------------------------------------------------------------------------=[ UPnP
]
[main] INFO l2j.commons.network.UPnPService - UPnP is disabled.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
--------------------------------------------------------=[ Execution Environment
]
[main] INFO l2j.commons.util.AppInit - server: Version Info - IDE Mode., Version
Info - IDE Mode., Version Info - IDE Mode. [ Version Info - IDE Mode. ]
[main] INFO l2j.commons.util.AppInit - server: Version Info - IDE Mode., Version
Info - IDE Mode., Version Info - IDE Mode. [ Version Info - IDE Mode. ]
[main] INFO l2j.commons.util.AppInit - server: Version Info - IDE Mode., Version
Info - IDE Mode., Version Info - IDE Mode. [ Version Info - IDE Mode. ]
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------=[ Memory (Heap)
]
[main] INFO l2j.commons.util.AppInit - GC done in 71 milliseconds, 690 microseco
nds, 508 nanoseconds.
[main] INFO l2j.commons.util.AppInit - +----
[main] INFO l2j.commons.util.AppInit - | Global Memory Information at 12:20:59:
[main] INFO l2j.commons.util.AppInit - |    |
[main] INFO l2j.commons.util.AppInit - | Allowed Memory: 981,5 MB
[main] INFO l2j.commons.util.AppInit - |    |= Allocated Memory: 981,5 MB (100,0
0%)
[main] INFO l2j.commons.util.AppInit - |    |= Non-Allocated Memory: 0.0 B (0,00
%)
[main] INFO l2j.commons.util.AppInit - | Allocated Memory: 981,5 MB
[main] INFO l2j.commons.util.AppInit - |    |= Used Memory: 15,5 MB (1,57%)
[main] INFO l2j.commons.util.AppInit - |    |= Unused (cached) Memory: 966,0 MB
(98,43%)
[main] INFO l2j.commons.util.AppInit - | Useable Memory: 966,0 MB (98,43%)
[main] INFO l2j.commons.util.AppInit - +----
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
----------------------------------------------------------------------=[ Summary
]
[main] INFO l2j.commons.util.AppInit - Initialized in 2 seconds, 66 milliseconds
.
[main] INFO l2j.commons.util.CommonUtil - --------------------------------------
---------------------------------------------------------------=[ ApplicationLog
]
 
Последнее редактирование:
Просто перед строкой
final Attributes attributes = jarFile.getManifest().getMainAttributes();

Добавь проверку if(jarFile.getManifest == null) return;

В коде уже есть обход для этого случая и вместо версии будет подчтавлять значение поля IDE_MODE
 
  • Мне нравится
Реакции: kick

    kick

    Баллов: 75
    00845
Просто перед строкой
final Attributes attributes = jarFile.getManifest().getMainAttributes();

Добавь проверку if(jarFile.getManifest == null) return;

В коде уже есть обход для этого случая и вместо версии будет подчтавлять значение поля IDE_MODE
Добавил, но эффект тот же:
Java:
            try (final JarFile jarFile = new JarFile(file);)
        {

            if(jarFile.getManifest() == null) return;
            final Attributes attributes = jarFile.getManifest().getMainAttributes();
            attributes.entrySet().forEach((entry) -> _manifestAttributes.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())));
        }
Получаю:
Код:
[main] INFO l2j.commons.util.CommonUtil - -----------------------------------------------------------------------------------------------------------=[ Database ]
[main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[main] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization.
java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:232)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:165)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1199)
    at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:560)
    at org.mariadb.jdbc.MariaDbConnection.newConnection(MariaDbConnection.java:174)
    at org.mariadb.jdbc.Driver.connect(Driver.java:92)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
    at l2j.commons.sql.DatabaseFactory.init(DatabaseFactory.java:53)
    at l2j.commons.util.AppInit.defaultInit(AppInit.java:115)
    at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:58)
    at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:934)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:850)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:507)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1195)
    ... 14 more
[main] ERROR l2j.commons.util.AppInit - Could not initialize database!
java.sql.SQLInvalidAuthorizationSpecException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.get(ExceptionMapper.java:232)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionMapper.getException(ExceptionMapper.java:165)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1199)
    at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:560)
    at org.mariadb.jdbc.MariaDbConnection.newConnection(MariaDbConnection.java:174)
    at org.mariadb.jdbc.Driver.connect(Driver.java:92)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
    at l2j.commons.sql.DatabaseFactory.init(DatabaseFactory.java:53)
    at l2j.commons.util.AppInit.defaultInit(AppInit.java:115)
    at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:58)
    at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
Caused by: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:934)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:850)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:507)
    at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:1195)
    ... 14 more
[main] INFO l2j.commons.lang.management.ShutdownManager - A shutdown command was issued: missing critical functionality!
[CumulativeShutdownHook] INFO l2j.commons.util.CommonUtil - ---------------------------------------------------------------------------------------------------=[ Shutdown Hook(s) ]
[CumulativeShutdownHook] INFO l2j.commons.sql.DatabaseFactory - Shutting down.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool - Shutting down.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... executing 1 scheduled tasks.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... executing 0 tasks.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... success: true in 0 ms.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... 0 scheduled tasks left.
[CumulativeShutdownHook] INFO l2j.commons.util.concurrent.ThreadPool -     ... 0 tasks left.
 
А инициализацию то в DatabaseFactory,что я выше писал тоже?
 
А инициализацию то в DatabaseFactory,что я выше писал тоже?
IDE ее за ошибку считает:
screen.webp

А если делаю так, то бьет еррор другой:
Java:
public static DatabaseFactory getInstance() throws SQLException {
        synchronized (DatabaseFactory.class)
        {
            if (_instance == null)
            {
                _instance = new DatabaseFactory();
            }
        }
        return _instance;
    }
Java:
protected DatabaseFactory() throws SQLException {
        this.init();
    }
Код:
[main] INFO l2j.commons.util.CommonUtil - -----------------------------------------------------------------------------------------------------------=[ Database ]
[main] ERROR l2j.commons.util.AppInit - Could not initialize database!
java.lang.NullPointerException: Database Config is not specified!
    at l2j.commons.sql.DatabaseFactory.init(DatabaseFactory.java:38)
    at l2j.commons.sql.DatabaseFactory.<init>(DatabaseFactory.java:26)
    at l2j.commons.sql.DatabaseFactory.getInstance(DatabaseFactory.java:109)
    at l2j.commons.util.AppInit.defaultInit(AppInit.java:114)
    at l2j.loginserver.L2LoginServer.<init>(L2LoginServer.java:58)
    at l2j.loginserver.L2LoginServer.main(L2LoginServer.java:46)
[main] INFO l2j.commons.lang.management.ShutdownManager - A shutdown command was issued: missing critical functionality!

Что происходит в голове, когда собираешь сурсы юнити.
 
В конструктор конечно не круто бросок ексепшна засовывать(гавнокод), лучше б ты в идее выбрал замену на try catch, но там надо обработку его какую нибудь делать и вообще это проблему не решает)
Сейчас проблема в том, что конфигурация не подтянута. Она подсовывается в setDatabaseConfig откуда то из вне. Тогда все таки конструктор оставляй пустой, и ищи где этот метод вызывается и почему он передаёт root и localhost(вероятно файл параметров дб не находит, потому что в идее запускаешь)

Из идеи изначально вообще запуск работал?
Там же нельзя просто сбилдить, там нужно весь датапак и конфиги подсовывать(на другом форуме есть инструкция)
 
Последнее редактирование модератором:
Назад
Сверху Снизу