flowable适配达梦数据库

news2025/2/22 11:55:20

文章目录

  • 适配相关问题
    • 无法从数据库产品名称“DM DBMS”中推断数据库类型
      • 分析
      • 解决
    • 构建ibatis SqlSessionFactory时出错:inStream参数为null
      • 分析
      • 解决
    • liquibase相关问题
      • 问题一:不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访问表达式[CURRENT_SCHEMA]
        • 分析
        • 解决
      • 问题二:找不到 setRemarksReporting 方法
        • 解决
      • 问题三:存储过程问题问题,Cannot read from DBMS_UTILITY.DB_VERSION: 无效的方法名[DB_VERSION]
        • 分析
        • 解决
      • 问题四: 更新事件注册表引擎表时出错、初始化事件注册表数据模型时出错
        • 解决
      • 问题五:验证事件注册表引擎架构时出错
        • 解决
    • 数据库版本问题version mismatch: library version is '7.0.1.1', db version is 7.0.0.0
      • 解决
    • 启动流程相关问题
      • 解决
    • 服务启动成功日志

网上flowable7新版本适配文档较少,以下使用部署flowable7源码方式说明相关适配问题。

适配相关问题

无法从数据库产品名称“DM DBMS”中推断数据库类型

分析

先查看较为完整的堆栈信息调用流程看一下怎么个事

实例化bean 类型为class com.xxxx.workflow.service.impl.ProcessServiceImp
在这里插入图片描述

通过反射实例化后,填充属性,依赖注入

主要看注入flowable内置的Service
在这里插入图片描述
解析taskService字段

解析依赖关系

根据beanName(taskServiceBean)和type(org.flowable.engine.TaskService)得到要注入的实例

给taskService属性赋值

以上执行完就给taskSerive字段属性赋值了,报错是在执行
org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate方法时,也就是实例化taskService的时候

实例化taskService

从bena定义信息中可以看出有工厂方法 返回的是taskService

所以通过工厂方法实例化

得到候选实例的参数

解析注入参数processEngine

根据beanName(processEngine)和type(org.flowable.engine.ProcessEngine)得到要注入的实例

实例化processEngine

从bean定义信息中可以看出是通过 ProcessEngineFactoryBean 定制化创建的ProcessEngine,在ProcessEngineFactoryBean的getOject方法中会构建流程引擎

public class ProcessEngineFactoryBean implements FactoryBean<ProcessEngine>, DisposableBean, ApplicationContextAware {

    protected ProcessEngineConfigurationImpl processEngineConfiguration;

    protected ApplicationContext applicationContext;
    protected ProcessEngine processEngine;

    @Override
    public void destroy() throws Exception {
        if (processEngine != null) {
            processEngine.close();
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public ProcessEngine getObject() throws Exception {
        configureExternallyManagedTransactions();

        if (processEngineConfiguration.getBeans() == null) {
            processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(applicationContext));
        }
        // 构建流程引擎
        this.processEngine = processEngineConfiguration.buildProcessEngine();
        return this.processEngine;
    }

    protected void configureExternallyManagedTransactions() {
        if (processEngineConfiguration instanceof SpringProcessEngineConfiguration) { // remark: any config can be injected, so we cannot have SpringConfiguration as member
            SpringProcessEngineConfiguration engineConfiguration = (SpringProcessEngineConfiguration) processEngineConfiguration;
            if (engineConfiguration.getTransactionManager() != null) {
                processEngineConfiguration.setTransactionsExternallyManaged(true);
            }
        }
    }

    @Override
    public Class<ProcessEngine> getObjectType() {
        return ProcessEngine.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    public ProcessEngineConfigurationImpl getProcessEngineConfiguration() {
        return processEngineConfiguration;
    }

    public void setProcessEngineConfiguration(ProcessEngineConfigurationImpl processEngineConfiguration) {
        this.processEngineConfiguration = processEngineConfiguration;
    }
}

通过ProcessEngineFactoryBean的getOject获取processEngine实例的对象

重点在这里

org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#buildProcessEngine 构建流程引擎

org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#init 初始化

org.flowable.common.engine.impl.AbstractEngineConfiguration#initDataSource 初始化数据源

org.flowable.common.engine.impl.AbstractEngineConfiguration#initDatabaseType 初始化数据源类型 databaseProductName为DM DBMS

从org.flowable.common.engine.impl.AbstractEngineConfiguration#getDefaultDatabaseTypeMappings 从数据库类型映射中获取DM DBMS看看有没有,没有则抛出异常

    public void initDatabaseType() {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            //databaseProductName为DM DBMS
            String databaseProductName = databaseMetaData.getDatabaseProductName(); 
            logger.debug("database product name: '{}'", databaseProductName);

            // 如果是PostgreSQL,做一下处理...
            if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {
                try (PreparedStatement preparedStatement = connection.prepareStatement("select version() as version;");
                        ResultSet resultSet = preparedStatement.executeQuery()) {
                    String version = null;
                    if (resultSet.next()) {
                        version = resultSet.getString("version");
                    }

                    if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {
                        databaseProductName = PRODUCT_NAME_CRDB;
                        logger.info("CockroachDB version '{}' detected", version);
                    }
                }
            }

            //从org.flowable.common.engine.impl.AbstractEngineConfiguration#getDefaultDatabaseTypeMappings获取DM DBMS看看有没有
            databaseType = databaseTypeMappings.getProperty(databaseProductName);
            if (databaseType == null) {
                throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
            }
            logger.debug("using database type: {}", databaseType);

        } catch (SQLException e) {
            throw new RuntimeException("Exception while initializing Database connection", e);
        } finally {
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                logger.error("Exception while closing the Database connection", e);
            }
        }
        if (DATABASE_TYPE_MSSQL.equals(databaseType)) {
            maxNrOfStatementsInBulkInsert = DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER;
        }
    }
    public static Properties getDefaultDatabaseTypeMappings() {
        Properties databaseTypeMappings = new Properties();
        databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
        databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
        databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
        databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
        databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
        databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES);
        databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
        databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXPPC64LE", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB);
        return databaseTypeMappings;
    }

解决

添加达梦数据库类型映射

org.flowable.common.engine.impl.AbstractEngineConfiguration

构建ibatis SqlSessionFactory时出错:inStream参数为null

分析

定位

上面流程初始化了数据源,数据源类型等

在org.flowable.common.engine.impl.AbstractEngineConfiguration#initSqlSessionFactory初始化SqlSessionFactory,会根据数据源类型读取配置org/flowable/common/db/properties/dm.properties,没有dm的配置(mybatis分页相关配置),报InputStream为null

 public void initSqlSessionFactory() {
        if (sqlSessionFactory == null) {
            InputStream inputStream = null;
            try {
                //  读取org/flowable/db/mapping/mappings.xml
                inputStream = getMyBatisXmlConfigurationStream();

                Environment environment = new Environment("default", transactionFactory, dataSource);
                Reader reader = new InputStreamReader(inputStream);
                Properties properties = new Properties();
                properties.put("prefix", databaseTablePrefix);

                String wildcardEscapeClause = "";
                if ((databaseWildcardEscapeCharacter != null) && (databaseWildcardEscapeCharacter.length() != 0)) {
                    wildcardEscapeClause = " escape '" + databaseWildcardEscapeCharacter + "'";
                }
                properties.put("wildcardEscapeClause", wildcardEscapeClause);

                // set default properties
                properties.put("limitBefore", "");
                properties.put("limitAfter", "");
                properties.put("limitBetween", "");
                properties.put("limitBeforeNativeQuery", "");
                properties.put("limitAfterNativeQuery", "");
                properties.put("blobType", "BLOB");
                properties.put("boolValue", "TRUE");

                if (databaseType != null) {
                    // 读取org/flowable/common/db/properties/dm.properties 设置properties
                    properties.load(getResourceAsStream(pathToEngineDbProperties()));
                }
                // 
                Configuration configuration = initMybatisConfiguration(environment, reader, properties);
                sqlSessionFactory = new DefaultSqlSessionFactory(configuration);

            } catch (Exception e) {
                throw new FlowableException("Error while building ibatis SqlSessionFactory: " + e.getMessage(), e);
            } finally {
                IoUtil.closeSilently(inputStream);
            }
        } else {
            applyCustomMybatisCustomizations(sqlSessionFactory.getConfiguration());
        }
    }

解决

添加dm.properties 参考oracle

limitBefore=select RES.* from ( select RES.*, rownum as rnum from (
limitAfter= ) RES where ROWNUM < #{lastRow} ) RES where rnum >= #{firstRow}
boolValue=1

liquibase相关问题

liquibase版本为4.20.0

问题一:不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访问表达式[CURRENT_SCHEMA]

liquibase.exception.DatabaseException: Error executing SQL call current_schema: 第1 行附近出现错误:

无法解析的成员访问表达式[CURRENT_SCHEMA]

分析

定位

org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#buildProcessEngine

org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl#init

org.flowable.common.engine.impl.AbstractEngineConfiguration#configuratorsAfterInit

org.flowable.eventregistry.impl.EventRegistryEngineConfiguration#buildEventRegistryEngine

org.flowable.eventregistry.impl.EventRegistryEngineConfiguration#init

org.flowable.eventregistry.impl.EventRegistryEngineImpl 实例化

org.flowable.eventregistry.impl.db.EventDbSchemaManager#initSchema

org.flowable.common.engine.impl.db.LiquibaseBasedSchemaManager#createLiquibaseInstance 创建Liquibase实例

    protected Liquibase createLiquibaseInstance(LiquibaseDatabaseConfiguration databaseConfiguration) throws SQLException {
        Connection jdbcConnection = null;
        boolean closeConnection = false;
        try {
            CommandContext commandContext = Context.getCommandContext();
            if (commandContext == null) {
                jdbcConnection = databaseConfiguration.getDataSource().getConnection();
                closeConnection = true;
            } else {
                jdbcConnection = commandContext.getSession(DbSqlSession.class).getSqlSession().getConnection();
            }

            if (!jdbcConnection.getAutoCommit()) {
                jdbcConnection.commit();
            }
            // 创建jdbc连接
            DatabaseConnection connection = new JdbcConnection(jdbcConnection);
            // 创建数据库实例
            Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
            // 设置数据库更改日志表名称  FLW_EV_DATABASECHANGELOG
            database.setDatabaseChangeLogTableName(changeLogPrefix + database.getDatabaseChangeLogTableName());
            // 设置数据库更改日志锁定表名称  FLW_EV_DATABASECHANGELOGLOCK
            database.setDatabaseChangeLogLockTableName(changeLogPrefix + database.getDatabaseChangeLogLockTableName());
            String databaseSchema = databaseConfiguration.getDatabaseSchema();
            if (StringUtils.isNotEmpty(databaseSchema)) {
                database.setDefaultSchemaName(databaseSchema);
                database.setLiquibaseSchemaName(databaseSchema);
            }

            String databaseCatalog = databaseConfiguration.getDatabaseCatalog();
            if (StringUtils.isNotEmpty(databaseCatalog)) {
                database.setDefaultCatalogName(databaseCatalog);
                database.setLiquibaseCatalogName(databaseCatalog);
            }

            return new Liquibase(changeLogFile, new ClassLoaderResourceAccessor(), database);

        } catch (Exception e) {
            // We only close the connection if an exception occurred, otherwise the Liquibase instance cannot be used
            if (jdbcConnection != null && closeConnection) {
                jdbcConnection.close();
            }
            throw new FlowableException("Error creating " + context + " liquibase instance", e);
        }
    }

liquibase.database.DatabaseFactory#findCorrectDatabaseImplementation 实例化所有实现了AbstractJdbcDatabase的Database,根据数据库连接获取数据库实现

    public Database findCorrectDatabaseImplementation(DatabaseConnection connection) throws DatabaseException {
        // 实例化所有实现了AbstractJdbcDatabase的Database
        SortedSet<Database> foundDatabases = new TreeSet(new DatabaseComparator());
        Iterator var3 = this.getImplementedDatabases().iterator();

        while(var3.hasNext()) {
            Database implementedDatabase = (Database)var3.next();
            if (connection instanceof OfflineConnection) {
                if (((OfflineConnection)connection).isCorrectDatabaseImplementation(implementedDatabase)) {
                    foundDatabases.add(implementedDatabase);
                }
                // 通过连接的数据库产品名判断 return "DM DBMS".equalsIgnoreCase(conn.getDatabaseProductName());
            } else if (implementedDatabase.isCorrectDatabaseImplementation(connection)) {
                foundDatabases.add(implementedDatabase);
            }
        }
        // 没有找到实现
        if (foundDatabases.isEmpty()) {
            LOG.warning("Unknown database: " + connection.getDatabaseProductName());
            // 返回一个不支持的数据库
            UnsupportedDatabase unsupportedDB = new UnsupportedDatabase();
            // 设置连接
            unsupportedDB.setConnection(connection);
            return unsupportedDB;
        } else {
            Database returnDatabase;
            try {
                returnDatabase = (Database)((Database)foundDatabases.iterator().next()).getClass().getConstructor().newInstance();
            } catch (Exception var5) {
                throw new UnexpectedLiquibaseException(var5);
            }

            returnDatabase.setConnection(connection);
            return returnDatabase;
        }
    }

没有达梦数据库实现,返回一个不支持的数据库实例

设置连接时,执行报错

解决

liquibase.database.DatabaseFactory 查看实例化Database方式

liquibase.servicelocator.StandardServiceLocator#findInstances 通过Java SPI机制实现

所以根据SPI实现方式 创建达梦数据库实现 (暂且放在业务工程中,后面可以搞一个单独的集成工程 或 直接添加到flowable源码中)

创建AbstractJdbcDatabase实现类DMDatabase 参考liquibase.database.core.OracleDatabase实现修改

package com.xxxx.workflow.database;

/**
 * @Author Chow
 * @Date 2024/12/27 17:44
 * @Version 1.0
 * @description
 **/
public class DMDatabase extends AbstractJdbcDatabase {
    public static final Pattern PROXY_USER = Pattern.compile(".*(?:thin|oci)\\:(.+)/@.*");

    /**
     * 产品名称
     */
    public static final String PRODUCT_NAME = "DM DBMS";
    private static ResourceBundle coreBundle = ResourceBundle.getBundle("liquibase/i18n/liquibase-core");
    protected final int SHORT_IDENTIFIERS_LENGTH = 30;
    protected final int LONG_IDENTIFIERS_LEGNTH = 128;
    public static final int ORACLE_12C_MAJOR_VERSION = 12;
    private Set<String> reservedWords = new HashSet();
    private Set<String> userDefinedTypes;
    private Map<String, String> savedSessionNlsSettings;
    private Boolean canAccessDbaRecycleBin;
    private Integer databaseMajorVersion;
    private Integer databaseMinorVersion;

    public DMDatabase() {
        super.unquotedObjectsAreUppercased = true;
        super.setCurrentDateTimeFunction("SYSTIMESTAMP");
        this.dateFunctions.add(new DatabaseFunction("SYSDATE"));
        this.dateFunctions.add(new DatabaseFunction("SYSTIMESTAMP"));
        this.dateFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP"));
        super.sequenceNextValueFunction = "%s.nextval";
        super.sequenceCurrentValueFunction = "%s.currval";
    }

    @Override
    public int getPriority() {
        return 1;
    }

    private void tryProxySession(String url, Connection con) {
        Matcher m = PROXY_USER.matcher(url);
        if (m.matches()) {
            Properties props = new Properties();
            props.put("PROXY_USER_NAME", m.group(1));

            Method method;
            try {
                method = con.getClass().getMethod("openProxySession", Integer.TYPE, Properties.class);
                method.setAccessible(true);
                method.invoke(con, 1, props);
            } catch (Exception var8) {
                Scope.getCurrentScope().getLog(this.getClass()).info("Could not open proxy session on DMDatabase: " + var8.getCause().getMessage());
                return;
            }

            try {
                method = con.getClass().getMethod("isProxySession");
                method.setAccessible(true);
                boolean b = (Boolean) method.invoke(con);
                if (!b) {
                    Scope.getCurrentScope().getLog(this.getClass()).info("Proxy session not established on DMDatabase: ");
                }
            } catch (Exception var7) {
                Scope.getCurrentScope().getLog(this.getClass()).info("Could not open proxy session on DMDatabase: " + var7.getCause().getMessage());
            }
        }

    }

    @Override
    public void setConnection(DatabaseConnection conn) {
        this.reservedWords.addAll(Arrays.asList("GROUP", "USER", "SESSION", "PASSWORD", "RESOURCE", "START", "SIZE", "UID", "DESC", "ORDER"));
        Connection sqlConn = null;
        if (!(conn instanceof OfflineConnection)) {
            try {
                if (conn instanceof JdbcConnection) {
                    sqlConn = ((JdbcConnection) conn).getWrappedConnection();
                }
            } catch (Exception var29) {
                throw new UnexpectedLiquibaseException(var29);
            }

            if (sqlConn != null) {
                this.tryProxySession(conn.getURL(), sqlConn);

                try {
                    this.reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(",\\s*")));
                } catch (SQLException var28) {
                    Scope.getCurrentScope().getLog(this.getClass()).info("Could get sql keywords on DMDatabase: " + var28.getMessage());
                }

                /**
                 * 在Oracle数据库中,setRemarksReporting是一个用于设置数据库对象(如表、视图、列等)注释或描述的方法。这通常用于生成数据库文档。
                 */
                try {
                    Method method = sqlConn.getClass().getMethod("setRemarksReporting", Boolean.TYPE);
                    method.setAccessible(true);
                    method.invoke(sqlConn, true);
                } catch (Exception var27) {
                    Scope.getCurrentScope().getLog(this.getClass()).info("Could not set remarks reporting on DMDatabase: " + var27.getMessage());
                }

                CallableStatement statement = null;

                // 基于oracle的实现修改  存储过程问题,无效的方法名[DB_VERSION]  这里直接写死
                String sql;
                try {
                    DatabaseMetaData metaData = sqlConn.getMetaData();
                    Connection connection = metaData.getConnection();
                    Connection connection1 = connection.getMetaData().getConnection();

                    //String compatibleVersion = "11.2.0.4.0"; //这个是oracleDatabase 当前使用的数据库版本
                    String compatibleVersion = "8.1.3.100";
                    Matcher majorVersionMatcher = Pattern.compile("(\\d+)\\.(\\d+)\\..*").matcher(compatibleVersion);
                    if (majorVersionMatcher.matches()) {
                        this.databaseMajorVersion = Integer.valueOf(majorVersionMatcher.group(1));
                        this.databaseMinorVersion = Integer.valueOf(majorVersionMatcher.group(2));
                    }
                } catch (SQLException var25) {
                    sql = "Cannot read from DBMS_UTILITY.DB_VERSION: " + var25.getMessage();
                    Scope.getCurrentScope().getLog(this.getClass()).info("Could not set check compatibility mode on DMDatabase, assuming not running in any sort of compatibility mode: " + sql);
                } finally {
                    JdbcUtil.closeStatement(statement);
                }

                if (GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue() != null) {
                    int timeoutValue = (Integer) GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue();
                    Scope.getCurrentScope().getLog(this.getClass()).fine("Setting DDL_LOCK_TIMEOUT value to " + timeoutValue);
                    sql = "ALTER SESSION SET DDL_LOCK_TIMEOUT=" + timeoutValue;
                    PreparedStatement ddlLockTimeoutStatement = null;

                    try {
                        ddlLockTimeoutStatement = sqlConn.prepareStatement(sql);
                        ddlLockTimeoutStatement.execute();
                    } catch (SQLException var23) {
                        Scope.getCurrentScope().getUI().sendErrorMessage("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + var23.getMessage(), var23);
                        Scope.getCurrentScope().getLog(this.getClass()).warning("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + var23.getMessage(), var23);
                    } finally {
                        JdbcUtil.closeStatement(ddlLockTimeoutStatement);
                    }
                }
            }
        }

        super.setConnection(conn);
    }

    /**
     * 简称
     * @return
     */
    @Override
    public String getShortName() {
        return "dm";
    }

    /**
     * 默认数据库产品名称
     * @return
     */
    @Override
    protected String getDefaultDatabaseProductName() {
        return "DM DBMS";
    }

    @Override
    public int getDatabaseMajorVersion() throws DatabaseException {
        return this.databaseMajorVersion == null ? super.getDatabaseMajorVersion() : this.databaseMajorVersion;
    }

    @Override
    public int getDatabaseMinorVersion() throws DatabaseException {
        return this.databaseMinorVersion == null ? super.getDatabaseMinorVersion() : this.databaseMinorVersion;
    }


    /**
     * 端口
     * @return
     */
    @Override
    public Integer getDefaultPort() {
        return 5236;
    }

    @Override
    public String getJdbcCatalogName(CatalogAndSchema schema) {
        return null;
    }

    @Override
    public String getJdbcSchemaName(CatalogAndSchema schema) {
        return this.correctObjectName(schema.getCatalogName() == null ? schema.getSchemaName() : schema.getCatalogName(), Schema.class);
    }

    @Override
    protected String getAutoIncrementClause(String generationType, Boolean defaultOnNull) {
        if (StringUtil.isEmpty(generationType)) {
            return super.getAutoIncrementClause();
        } else {
            String autoIncrementClause = "GENERATED %s AS IDENTITY";
            String generationStrategy = generationType;
            if (Boolean.TRUE.equals(defaultOnNull) && generationType.toUpperCase().equals("BY DEFAULT")) {
                generationStrategy = generationType + " ON NULL";
            }

            return String.format(autoIncrementClause, generationStrategy);
        }
    }

    @Override
    public String generatePrimaryKeyName(String tableName) {
        return tableName.length() > 27 ? "PK_" + tableName.toUpperCase(Locale.US).substring(0, 27) : "PK_" + tableName.toUpperCase(Locale.US);
    }

    @Override
    public boolean supportsInitiallyDeferrableColumns() {
        return true;
    }

    @Override
    public boolean isReservedWord(String objectName) {
        return this.reservedWords.contains(objectName.toUpperCase());
    }

    @Override
    public boolean supportsSequences() {
        return true;
    }

    @Override
    public boolean supportsSchemas() {
        return false;
    }

    @Override
    protected String getConnectionCatalogName() throws DatabaseException {
        if (this.getConnection() instanceof OfflineConnection) {
            return this.getConnection().getCatalog();
        } else if (!(this.getConnection() instanceof JdbcConnection)) {
            return this.defaultCatalogName;
        } else {
            try {
                return (String) ((ExecutorService) Scope.getCurrentScope().getSingleton(ExecutorService.class)).getExecutor("jdbc", this).queryForObject(new RawCallStatement("select sys_context( 'userenv', 'current_schema' ) from dual"), String.class);
            } catch (Exception var2) {
                Scope.getCurrentScope().getLog(this.getClass()).info("Error getting default schema", var2);
                return null;
            }
        }
    }

    /**
     * 根据数据库连接判断是否是该数据库实现
     * {@link liquibase.database.DatabaseFactory#findCorrectDatabaseImplementation(liquibase.database.DatabaseConnection)}
     * {@link Database#isCorrectDatabaseImplementation(DatabaseConnection)}
     * @param conn
     * @return
     * @throws DatabaseException
     */
    @Override
    public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
        return "DM DBMS".equalsIgnoreCase(conn.getDatabaseProductName());
    }

    /**
     * jdbc 驱动
     * @param url
     * @return
     */
    @Override
    public String getDefaultDriver(String url) {
        return url.startsWith("jdbc:dm") ? "dm.jdbc.driver.DmDriver" : null;
    }

    @Override
    public String getDefaultCatalogName() {
        String defaultCatalogName = super.getDefaultCatalogName();
        if (Boolean.TRUE.equals(GlobalConfiguration.PRESERVE_SCHEMA_CASE.getCurrentValue())) {
            return defaultCatalogName;
        } else {
            return defaultCatalogName == null ? null : defaultCatalogName.toUpperCase(Locale.US);
        }
    }

    @Override
    public String getDateLiteral(String isoDate) {
        String normalLiteral = super.getDateLiteral(isoDate);
        if (this.isDateOnly(isoDate)) {
            return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD')";
        } else if (this.isTimeOnly(isoDate)) {
            return "TO_DATE(" + normalLiteral + ", 'HH24:MI:SS')";
        } else if (this.isTimestamp(isoDate)) {
            return "TO_TIMESTAMP(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS.FF')";
        } else if (this.isDateTime(isoDate)) {
            int seppos = normalLiteral.lastIndexOf(46);
            if (seppos != -1) {
                normalLiteral = normalLiteral.substring(0, seppos) + "'";
            }

            return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS')";
        } else {
            return "UNSUPPORTED:" + isoDate;
        }
    }

    @Override
    public boolean isSystemObject(DatabaseObject example) {
        if (example == null) {
            return false;
        } else if (this.isLiquibaseObject(example)) {
            return false;
        } else {
            if (example instanceof Schema) {
                label131:
                {
                    if (!"SYSTEM".equals(example.getName()) && !"SYS".equals(example.getName()) && !"CTXSYS".equals(example.getName()) && !"XDB".equals(example.getName())) {
                        if (!"SYSTEM".equals(example.getSchema().getCatalogName()) && !"SYS".equals(example.getSchema().getCatalogName()) && !"CTXSYS".equals(example.getSchema().getCatalogName()) && !"XDB".equals(example.getSchema().getCatalogName())) {
                            break label131;
                        }

                        return true;
                    }

                    return true;
                }
            } else if (this.isSystemObject(example.getSchema())) {
                return true;
            }

            if (example instanceof Catalog) {
                if ("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName())) {
                    return true;
                }
            } else if (example.getName() != null) {
                if (example.getName().startsWith("BIN$")) {
                    boolean filteredInOriginalQuery = this.canAccessDbaRecycleBin();
                    if (!filteredInOriginalQuery) {
                        filteredInOriginalQuery = StringUtil.trimToEmpty(example.getSchema().getName()).equalsIgnoreCase(this.getConnection().getConnectionUserName());
                    }

                    if (!filteredInOriginalQuery) {
                        return true;
                    }

                    return !(example instanceof PrimaryKey) && !(example instanceof Index) && !(example instanceof UniqueConstraint);
                }

                if (example.getName().startsWith("AQ$")) {
                    return true;
                }

                if (example.getName().startsWith("DR$")) {
                    return true;
                }

                if (example.getName().startsWith("SYS_IOT_OVER")) {
                    return true;
                }

                if ((example.getName().startsWith("MDRT_") || example.getName().startsWith("MDRS_")) && example.getName().endsWith("$")) {
                    return true;
                }

                if (example.getName().startsWith("MLOG$_")) {
                    return true;
                }

                if (example.getName().startsWith("RUPD$_")) {
                    return true;
                }

                if (example.getName().startsWith("WM$_")) {
                    return true;
                }

                if ("CREATE$JAVA$LOB$TABLE".equals(example.getName())) {
                    return true;
                }

                if ("JAVA$CLASS$MD5$TABLE".equals(example.getName())) {
                    return true;
                }

                if (example.getName().startsWith("ISEQ$$_")) {
                    return true;
                }

                if (example.getName().startsWith("USLOG$")) {
                    return true;
                }

                if (example.getName().startsWith("SYS_FBA")) {
                    return true;
                }
            }

            return super.isSystemObject(example);
        }
    }

    @Override
    public boolean supportsTablespaces() {
        return true;
    }

    @Override
    public boolean supportsAutoIncrement() {
        boolean isAutoIncrementSupported = false;

        try {
            if (this.getDatabaseMajorVersion() >= 12) {
                isAutoIncrementSupported = true;
            }
        } catch (DatabaseException var3) {
            isAutoIncrementSupported = false;
        }

        return isAutoIncrementSupported;
    }

    @Override
    public boolean supportsRestrictForeignKeys() {
        return false;
    }

    @Override
    public int getDataTypeMaxParameters(String dataTypeName) {
        if ("BINARY_FLOAT".equals(dataTypeName.toUpperCase())) {
            return 0;
        } else {
            return "BINARY_DOUBLE".equals(dataTypeName.toUpperCase()) ? 0 : super.getDataTypeMaxParameters(dataTypeName);
        }
    }

    public String getSystemTableWhereClause(String tableNameColumn) {
        List<String> clauses = new ArrayList(Arrays.asList("BIN$", "AQ$", "DR$", "SYS_IOT_OVER", "MLOG$_", "RUPD$_", "WM$_", "ISEQ$$_", "USLOG$", "SYS_FBA"));

        for (int i = 0; i < clauses.size(); ++i) {
            clauses.set(i, tableNameColumn + " NOT LIKE '" + (String) clauses.get(i) + "%'");
        }

        return "(" + StringUtil.join(clauses, " AND ") + ")";
    }

    @Override
    public boolean jdbcCallsCatalogsSchemas() {
        return true;
    }

    public Set<String> getUserDefinedTypes() {
        if (this.userDefinedTypes == null) {
            this.userDefinedTypes = new HashSet();
            if (this.getConnection() != null && !(this.getConnection() instanceof OfflineConnection)) {
                try {
                    try {
                        this.userDefinedTypes.addAll(((ExecutorService) Scope.getCurrentScope().getSingleton(ExecutorService.class)).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT DISTINCT TYPE_NAME FROM ALL_TYPES"), String.class));
                    } catch (DatabaseException var2) {
                        this.userDefinedTypes.addAll(((ExecutorService) Scope.getCurrentScope().getSingleton(ExecutorService.class)).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT TYPE_NAME FROM USER_TYPES"), String.class));
                    }
                } catch (DatabaseException var3) {
                }
            }
        }

        return this.userDefinedTypes;
    }

    @Override
    public String generateDatabaseFunctionValue(DatabaseFunction databaseFunction) {
        if (databaseFunction != null && "current_timestamp".equalsIgnoreCase(databaseFunction.toString())) {
            return databaseFunction.toString();
        } else if (!(databaseFunction instanceof SequenceNextValueFunction) && !(databaseFunction instanceof SequenceCurrentValueFunction)) {
            return super.generateDatabaseFunctionValue(databaseFunction);
        } else {
            String quotedSeq = super.generateDatabaseFunctionValue(databaseFunction);
            return quotedSeq.replaceFirst("\"([^.\"]+)\\.([^.\"]+)\"", "\"$1\".\"$2\"");
        }
    }

    @Override
    public ValidationErrors validate() {
        ValidationErrors errors = super.validate();
        DatabaseConnection connection = this.getConnection();
        if (connection != null && !(connection instanceof OfflineConnection)) {
            if (!this.canAccessDbaRecycleBin()) {
                errors.addWarning(this.getDbaRecycleBinWarning());
            }

            return errors;
        } else {
            Scope.getCurrentScope().getLog(this.getClass()).info("Cannot validate offline database");
            return errors;
        }
    }

    public String getDbaRecycleBinWarning() {
        return "Liquibase needs to access the DBA_RECYCLEBIN table so we can automatically handle the case where constraints are deleted and restored. Since Oracle doesn't properly restore the original table names referenced in the constraint, we use the information from the DBA_RECYCLEBIN to automatically correct this issue.\n\nThe user you used to connect to the database (" + this.getConnection().getConnectionUserName() + ") needs to have \"SELECT ON SYS.DBA_RECYCLEBIN\" permissions set before we can perform this operation. Please run the following SQL to set the appropriate permissions, and try running the command again.\n\n     GRANT SELECT ON SYS.DBA_RECYCLEBIN TO " + this.getConnection().getConnectionUserName() + ";";
    }

    public boolean canAccessDbaRecycleBin() {
        if (this.canAccessDbaRecycleBin == null) {
            DatabaseConnection connection = this.getConnection();
            if (connection == null || connection instanceof OfflineConnection) {
                return false;
            }

            Statement statement = null;

            try {
                statement = ((JdbcConnection) connection).createStatement();
                ResultSet resultSet = statement.executeQuery("select 1 from dba_recyclebin where 0=1");
                resultSet.close();
                this.canAccessDbaRecycleBin = true;
            } catch (Exception var7) {
                if (var7 instanceof SQLException && var7.getMessage().startsWith("ORA-00942")) {
                    this.canAccessDbaRecycleBin = false;
                } else {
                    Scope.getCurrentScope().getLog(this.getClass()).warning("Cannot check dba_recyclebin access", var7);
                    this.canAccessDbaRecycleBin = false;
                }
            } finally {
                JdbcUtil.close((ResultSet) null, statement);
            }
        }

        return this.canAccessDbaRecycleBin;
    }

    @Override
    public boolean supportsNotNullConstraintNames() {
        return true;
    }

    public boolean isValidOracleIdentifier(String identifier, Class<? extends DatabaseObject> type) {
        if (identifier != null && identifier.length() >= 1) {
            if (!identifier.matches("^(i?)[A-Z][A-Z0-9\\$\\_\\#]*$")) {
                return false;
            } else {
                return identifier.length() <= 128;
            }
        } else {
            return false;
        }
    }

    public int getIdentifierMaximumLength() {
        try {
            if (this.getDatabaseMajorVersion() < 12) {
                return 30;
            } else {
                return this.getDatabaseMajorVersion() == 12 && this.getDatabaseMinorVersion() <= 1 ? 30 : 128;
            }
        } catch (DatabaseException var2) {
            throw new UnexpectedLiquibaseException("Cannot determine the DM database version number", var2);
        }
    }
}


新建META-INF/services/liquibase.database.Database文件,添加DMDatabase全路径名

在这里插入图片描述

再次运行可以找到dm数据库实现

进入else

问题二:找不到 setRemarksReporting 方法

Could not set remarks reporting on OracleDatabase: jdk.proxy2.$Proxy147.setRemarksReporting(boolean)

Method threw ‘java.lang.NoSuchMethodException’ exception. 找不到 setRemarksReporting 方法

定位

com.xxxx.workflow.database.DMDatabase#setConnection

解决

反射调用了 JDBC 连接对象setRemarksReporting 方法

Oracle数据库中 setRemarksReporting用于设置数据库对象注释的方法,用来生成数据库文档。

这个dm的数据库实现可以直接注释

问题三:存储过程问题问题,Cannot read from DBMS_UTILITY.DB_VERSION: 无效的方法名[DB_VERSION]

Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: Cannot read from DBMS_UTILITY.DB_VERSION: 第1 行附近出现错误:无效的方法名[DB_VERSION]

分析

定位

com.xxxx.workflow.database.DMDatabase#setConnection

调用了存储过程

解决

达梦没有这个存储过程 这些把值写死

   @Override
   public void setConnection(DatabaseConnection conn) {
       this.reservedWords.addAll(Arrays.asList("GROUP", "USER", "SESSION", "PASSWORD", "RESOURCE", "START", "SIZE", "UID", "DESC", "ORDER"));
       Connection sqlConn = null;
       if (!(conn instanceof OfflineConnection)) {
           try {
               if (conn instanceof JdbcConnection) {
                   sqlConn = ((JdbcConnection) conn).getWrappedConnection();
               }
           } catch (Exception var29) {
               throw new UnexpectedLiquibaseException(var29);
           }
           if (sqlConn != null) {
               this.tryProxySession(conn.getURL(), sqlConn);
               try {
                   this.reservedWords.addAll(Arrays.asList(sqlConn.getMetaData().getSQLKeywords().toUpperCase().split(",\\s*")));
               } catch (SQLException var28) {
                   Scope.getCurrentScope().getLog(this.getClass()).info("Could get sql keywords on OracleDatabase: " + var28.getMessage());
               }
               try {
                   Method method = sqlConn.getClass().getMethod("setRemarksReporting", Boolean.TYPE);
                   method.setAccessible(true);
                   method.invoke(sqlConn, true);
               } catch (Exception var27) {
                   Scope.getCurrentScope().getLog(this.getClass()).info("Could not set remarks reporting on OracleDatabase: " + var27.getMessage());
               }
               CallableStatement statement = null;
               String sql;
               try {
                   DatabaseMetaData metaData = sqlConn.getMetaData();
                   Connection connection = metaData.getConnection();
                   Connection connection1 = connection.getMetaData().getConnection();
                   //String compatibleVersion = "11.2.0.4.0";  //这个是oracleDatabase 当前使用的数据库版本
                   String compatibleVersion = "8.1.3.100";
                   Matcher majorVersionMatcher = Pattern.compile("(\\d+)\\.(\\d+)\\..*").matcher(compatibleVersion);
                   if (majorVersionMatcher.matches()) {
                       this.databaseMajorVersion = Integer.valueOf(majorVersionMatcher.group(1));
                       this.databaseMinorVersion = Integer.valueOf(majorVersionMatcher.group(2));
                   }
               } catch (SQLException var25) {
                   sql = "Cannot read from DBMS_UTILITY.DB_VERSION: " + var25.getMessage();
                   Scope.getCurrentScope().getLog(this.getClass()).info("Could not set check compatibility mode on OracleDatabase, assuming not running in any sort of compatibility mode: " + sql);
               } finally {
                   JdbcUtil.closeStatement(statement);
               }
               if (GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue() != null) {
                   int timeoutValue = (Integer) GlobalConfiguration.DDL_LOCK_TIMEOUT.getCurrentValue();
                   Scope.getCurrentScope().getLog(this.getClass()).fine("Setting DDL_LOCK_TIMEOUT value to " + timeoutValue);
                   sql = "ALTER SESSION SET DDL_LOCK_TIMEOUT=" + timeoutValue;
                   PreparedStatement ddlLockTimeoutStatement = null;
                   try {
                       ddlLockTimeoutStatement = sqlConn.prepareStatement(sql);
                       ddlLockTimeoutStatement.execute();
                   } catch (SQLException var23) {
                       Scope.getCurrentScope().getUI().sendErrorMessage("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + var23.getMessage(), var23);
                       Scope.getCurrentScope().getLog(this.getClass()).warning("Unable to set the DDL_LOCK_TIMEOUT_VALUE: " + var23.getMessage(), var23);
                   } finally {
                       JdbcUtil.closeStatement(ddlLockTimeoutStatement);
                   }
               }
           }
       }
       super.setConnection(conn);
   }

参考:https://blog.csdn.net/zhangdaiscott/article/details/134547342

问题四: 更新事件注册表引擎表时出错、初始化事件注册表数据模型时出错

解决

将flowable.database-schema-update设置为false

应用启动时不会更新数据库模式,如果数据库模式和 Flowable 版本不匹配,会抛出异常阻止应用启动。

问题五:验证事件注册表引擎架构时出错

liquibase.Liquibase#validate

liquibase.executor.jvm.JdbcExecutor#execute(liquibase.statement.SqlStatement, java.util.List<liquibase.sql.visitor.SqlVisitor>)

解决

liquibase.Liquibase#validate 验证数据库模式与变更日志文件一致性,这里直接注释掉。

数据库版本问题version mismatch: library version is ‘7.0.1.1’, db version is 7.0.0.0

解决

参考flowable源码当前版 修改为对应版本

也可以数据源先使用mysql,再做迁移

启动流程相关问题

由于flowable.database-schema-update设置为false,如果数据表结构等和 Flowable 版本不匹配,不会进行自动更新,当前表直接迁移的是原7.0.0版本的表结构,源码部署的是GA版本的7.0.0分支(实际版本为7.0.0.39),两个版本的初始化表数量一样,但表结构字段有不同。

列找不到

解决

表结构可以先使用mysql生成,迁移到dm

7.0.0.39新增字段

服务启动成功日志

解决以上问题可以启动服务

Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1750724866 wrapping dm.jdbc.driver.DmdbConnection@657f1fc3]]
2024-12-30 17:12:19.969 [main] INFO  o.f.i.e.i.IdmEngineImpl -
				[<init>,52] - IdmEngine default created
2024-12-30 17:12:19.986 [main] INFO  o.f.s.SpringProcessEngineConfiguration -
				[configuratorsAfterInit,1157] - Executing configure() of class org.flowable.dmn.spring.configurator.SpringDmnEngineConfigurator (priority:200000)
Opening JDBC Connection
2024-12-30 17:12:30.646 [main] INFO  liquibase.database -
				[log,37] - Could not set remarks reporting on OracleDatabase: jdk.proxy2.$Proxy147.setRemarksReporting(boolean)
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1026432280 wrapping dm.jdbc.driver.DmdbConnection@657f1fc3]]
2024-12-30 17:12:35.406 [main] INFO  o.f.d.e.i.DmnEngineImpl -
				[<init>,55] - DmnEngine default created
2024-12-30 17:12:35.415 [main] INFO  o.f.s.SpringProcessEngineConfiguration -
				[configuratorsAfterInit,1157] - Executing configure() of class org.flowable.cmmn.spring.configurator.SpringCmmnEngineConfigurator (priority:500000)
Opening JDBC Connection
2024-12-30 17:12:45.684 [main] INFO  liquibase.database -
				[log,37] - Could not set remarks reporting on OracleDatabase: jdk.proxy2.$Proxy147.setRemarksReporting(boolean)
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@8603972 wrapping dm.jdbc.driver.DmdbConnection@657f1fc3]]
2024-12-30 17:12:52.094 [main] INFO  o.f.c.e.i.CmmnEngineImpl -
				[<init>,72] - CmmnEngine default created
Opening JDBC Connection
==>  Preparing: select VALUE_ from ACT_GE_PROPERTY where NAME_ = 'schema.version'
==> Parameters: 
<==    Columns: VALUE_
<==        Row: 7.0.1.1
<==      Total: 1
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@530287651 wrapping dm.jdbc.driver.DmdbConnection@657f1fc3]]
2024-12-30 17:12:52.443 [main] INFO  o.f.e.i.ProcessEngineImpl -
				[<init>,89] - ProcessEngine default created
Opening JDBC Connection
==>  Preparing: select count(RES.ID_) from ACT_RE_DEPLOYMENT RES WHERE RES.ENGINE_VERSION_ = ?
==> Parameters: v5(String)
<==    Columns: COUNT(RES.ID_)
<==        Row: 0
<==      Total: 1
2024-12-30 17:12:52.937 [main] INFO  o.f.e.i.c.ValidateV5EntitiesCmd -
				[execute,43] - Total of v5 deployments found: 0
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@871541777 wrapping dm.jdbc.driver.DmdbConnection@657f1fc3]]
Opening JDBC Connection
==>  Preparing: select * from ACT_GE_PROPERTY where NAME_ = ?
==> Parameters: cfg.execution-related-entities-count(String)
<==    Columns: NAME_, VALUE_, REV_
<==        Row: cfg.execution-related-entities-count, true, 1
<==      Total: 1
Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1059563867 wrapping dm.jdbc.driver.DmdbConnection@657f1fc3]]
Opening JDBC Connection
==>  Preparing: select * from ACT_GE_PROPERTY where NAME_ = ?
==> Parameters: cfg.task-related-entities-count(String)
<==    Columns: NAME_, VALUE_, REV_
<==        Row: cfg.task-related-entities-count, true, 1
<==      Total: 1

....

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2303397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins整合Jmeter实现接口自动化测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、安装jmeter 下载&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 这里我用了一台Windows安装jmeter用来写接口测试的脚本&#xff0c;启动前修改j…

高级推理的多样化推理与验证

25年2月来自波士顿大学、NotBadMath.AI、谷歌、哥伦比亚大学、MIT、Intuit公司和斯坦福大学的论文“Diverse Inference and Verification for Advanced Reasoning”。 OpenAI o1、o3 和 DeepSeek R1 等推理 LLM 在数学和编码方面取得重大进展&#xff0c;但仍发现 IMO 组合问题…

清华大学:DeepSeek与AI幻觉(31页PDF)

PDF深入探讨了AI幻觉的概念、原因、评测方法及其实用应用&#xff0c;特别是在金融领域的具体案例。首先介绍了AI幻觉的定义&#xff0c;主要包括数据偏差、泛化困境、知识固化和意图误解四种情况&#xff0c;以及这些因素导致AI产出不合理结果的原因。随后&#xff0c;通过音乐…

AWS云从业者认证题库 AWS Cloud Practitioner(2.21)

题库持续更新&#xff0c;上方二维码查看完整题库&#xff01; 公司希望减少开发人员用于运行代码的物理计算资源,通过启用无服务器架构&#xff0c;哪种服务可以满足该需求? A&#xff1a; Amazon Elastic Compute Cloud (Amazon EC2) B&#xff1a; AWS Lambda C&#xff1a…

网络工程师 (43)IP数据报

前言 IP数据报是互联网传输控制协议&#xff08;Internet Protocol&#xff0c;IP&#xff09;的数据报格式&#xff0c;由首部和数据两部分组成。 一、首部 IP数据报的首部是控制部分&#xff0c;包含了数据报传输和处理所需的各种信息。首部可以分为固定部分和可变部分。 固定…

京准电钟:水利控制系统网络时间同步设计与应用

京准电钟&#xff1a;水利控制系统网络时间同步设计与应用 京准电钟&#xff1a;水利控制系统网络时间同步设计与应用 引言 在水利工程中&#xff0c;控制系统的高效运行依赖于精准的时间同步。水电站、泵站、闸门控制、水文监测等子系统的协同作业需要毫秒甚至微秒级的时间…

QML 实现一个动态的启动界面

QML 实现一个动态的启动界面 一、效果查看二、源码分享三、所用到的资源下载 一、效果查看 二、源码分享 工程结构 main.qml import QtQuick import QtQuick.Controls import QtQuick.Dialogs import Qt.labs.platformWindow {id:windowwidth: 640height: 400visible: truetit…

【论文阅读】SAM-CP:将SAM与组合提示结合起来的多功能分割

导言 近年来&#xff0c;视觉基础模型的快速发展推动了多模态理解的进步&#xff0c;尤其是在图像分割任务中。例如&#xff0c;Segment Anything模型&#xff08;SAM&#xff09;在图像Mask分割上表现出色&#xff0c;但在语义及实例分割方面仍存在局限。本文提出的SAM-CP&am…

逻辑架构与软件架构在PREEvision中的设计关系

1 Introduction 在如今汽车电子系统的开发过程中&#xff0c;系统架构设计是至关重要的环节。无论是汽车控制系统、信息娱乐系统&#xff0c;还是电动驱动系统&#xff0c;架构设计都决定了整个系统的功能、性能以及后期的可维护性和可扩展性。 在往期文章中&#xff0c;我们…

武汉火影数字|VR沉浸式空间制作 VR大空间打造

VR沉浸式空间制作是指通过虚拟现实技术创建一个逼真的三维环境&#xff0c;让用户能够沉浸在这个环境中&#xff0c;彷佛置身于一个全新的世界。 也许你会好奇&#xff0c;VR 沉浸式空间究竟是如何将我们带入那奇妙的虚拟世界的呢&#xff1f;这背后&#xff0c;离不开一系列关…

大数据学习之任务流调度系统Azkaban、Superset可视化系统

一.任务流调度系统Azkaban 1.课程介绍 2.为什么需要工作流调度系统 3.AZKABAN是什么 4.AZKABAN下载 5.制作安装包 6.tar包准备 7.MYSQL配置AZKABAN 8.配置EXECUTOR SERVER 9.配置WEBSERVER 10.单作业实战_yaml语言(今天稍晚更新) 11.单作业实战 12.多作业依赖实战 13.失败自动重…

在VS-qt的程序中,后期增加PCH预编译功能,提高编译速度

由于前期创建qt程序的时候未勾选pch功能,导致没有启动预编译的功能. 这种情况下需要增加pch功能应该怎么做? 在项目中增加2个文件 stdafx.h和stdafx.cpp文件 stdafx.h增加qt常用头文件 #pragma once //windows #include <windows.h>//qt常用 #include <QObject&g…

蓝桥云客 路径之谜

11.路径之谜 - 蓝桥云课 路径之谜 题目描述 小明冒充X星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是nn个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&…

【Python项目】基于Python的语音数据及标注核对审核系统

【Python项目】基于Python的语音数据及标注核对审核系统 技术简介&#xff1a; 采用Python技术、MySQL数据库、Django框架等实现。 系统简介&#xff1a; 语音数据及标注核对审核系统是一个基于B/S架构的语音数据处理平台&#xff0c;旨在通过自动化的方式对语音数据进行标…

深入解析BFS算法:C++实现无权图最短路径的高效解决方案

在无权图中&#xff0c;广度优先搜索&#xff08;BFS&#xff09;是解决最短路径问题的高效算法。接下来博主从专业角度深入探讨其实现细节&#xff0c;并给出C代码示例&#xff1a; 目录 一、核心原理 二、算法步骤 三、C实现关键点 1. 数据结构 2. 边界检查 3. 路径回溯…

LeetCode刷题---二分查找---441

排列硬币 441. 排列硬币 - 力扣&#xff08;LeetCode&#xff09; 题目 你总共有 n 枚硬币&#xff0c;并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯&#xff0c;其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。 给你一个数字 n &#xff0c;计算…

Unity结合Vuforia虚拟按键实现AR机械仿真动画效果

零、最终效果 待上传 一、资源准备 1、Vuforia Vuforia版本不能高于10.17.4&#xff08;往上的版本虚拟按键功能被删除&#xff09; 2、Unity Unity版本必须要高于2022.3.x&#xff0c;不然使用Vuforia插件时会出现bug 二、主要内容 1、添加虚拟按钮 2、为虚拟按钮设置…

网络安全 linux学习计划 linux网络安全精要

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 2.使用命令行 文件系统层次标准&#xff08;FHS&#xff09;是一个文件和目录在Unix和Linux操作系统上面应该如何存储的定义。 /bin 重要的二进制可执行程序/bo…

为AI聊天工具添加一个知识系统 之115 详细设计之56 知识表征 之2

本文要点 要点 知识表征的顶级范畴中最好是先将九个原语primitive T, ⊥, Independent, Relative, Mediating, Physical, Abstract, Continuant,和 Occurrent 进行分组&#xff08;分成2大组 和 4个小组&#xff09;并写出它们的满足公司&#xff0c;然后将它们和三种设计&am…

C#初级教程(1)——C# 与.NET 框架:探索微软平台编程的强大组合

图片来源&#xff1a; https://www.lvhang.site/docs/dotnettimeline 即梦AI - 一站式AI创作平台 一、历史发展脉络 在早期的微软平台编程中&#xff0c;常用的编程语言有 Visual Basic、C、C。到了 20 世纪 90 年代末&#xff0c;Win32 API、MFC&#xff08;Microsoft Found…