ClientSymmetricEngine 3.12.7 - 无法编译 IAcknowledgeEventListener Java 扩展点

ClientSymmetricEngine 3.12.7 - Unable to compile IAcknowledgeEventListener Java extension point

让 SymmetricDS java 扩展点工作真是太糟糕了。

这是我试过的:

1.创建了这个 class:


package com.gourmet.listener;

import org.jumpmind.symmetric.ISymmetricEngine;
import org.jumpmind.symmetric.ext.ISymmetricEngineAware;
import org.jumpmind.symmetric.model.BatchAck;
import org.jumpmind.symmetric.transport.IAcknowledgeEventListener;

public class AcknowledgeListener implements IAcknowledgeEventListener, ISymmetricEngineAware {
    ISymmetricEngine _engine;


    @Override
    public void onAcknowledgeEvent(BatchAck batchInfo) {
        if (!batchInfo.isOk()) {
            System.out.println("bachInfo is not OK " + batchInfo);
            return;
        }
        System.out.println("received event!!!!!!! {}" + batchInfo);
    }

    @Override
    public void setSymmetricEngine(ISymmetricEngine engine) {
        _engine = engine;

    }
}

2。将 `Manifest.txt 放在与 AcknowledgeListener.java

相同的包位置
Class-Path: symmetric-core-3.12.7.jar symmetric-util-3.12.7.jar

3。使用 AcknowledgeListener 生成的 jar 文件并将其放置在 WEB-INF/lib

cd /gourmet3/mobile-webpage/src/main/java

javac -cp ".:/gourmet3/mobile-webpage/target/gourmet/WEB-INF/lib/symmetric-util-3.12.7.jar:/gourmet3/mobile-webpage/target/gourmet/WEB-INF/lib/symmetric-core-3.12.7.jar" com/gourmet/listener/AcknowledgeListener.java

jar cfm com/gourmet/listener/AcknowledgeListener.jar com/gourmet/listener/Manifest.txt com/gourmet/listener/*.class

mv com/gourmet/listener/AcknowledgeListener.jar /gourmet3/mobile-webpage/src/main/webapp/WEB-INF/lib

rm com/gourmet/listener/AcknowledgeListener.*

这是结果:

MANIFEST.MF:

Manifest-Version: 1.0
Class-Path: symmetric-core-3.12.7.jar symmetric-util-3.12.7.jar
Created-By: 1.8.0_272 (Azul Systems, Inc.)

SymmetricDS 3.2 documentation 所述,我创建了 conf/symmetric-extensions。xml 所以 spring 找到豆子。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="acknowledgeListener" class="com.gourmet.listener.AcknowledgeListener"/>
</beans>

在服务器和客户端数据库中创建了 sym_extension 条目 SQL

insert into sym_extension (extension_id, extension_type, interface_name, node_group_id, enabled, extension_order,
                           extension_text, create_time, last_update_by, last_update_time)
values ('acknowledge batch', 'java', 'org.jumpmind.symmetric.transport.IAcknowledgeEventListener','sucursal', 1, 1,
        '
import org.jumpmind.symmetric.ISymmetricEngine;
import org.jumpmind.symmetric.ext.ISymmetricEngineAware;
import org.jumpmind.symmetric.model.BatchAck;
import org.jumpmind.symmetric.transport.IAcknowledgeEventListener;

public class AcknowledgeListener implements IAcknowledgeEventListener, ISymmetricEngineAware {
    ISymmetricEngine _engine;


    @Override
    public void onAcknowledgeEvent(BatchAck batchInfo) {
        if (!batchInfo.isOk()) {
            System.out.println("bachInfo is not OK " + batchInfo);
            return;
        }
        System.out.println("received event!!!!!!! {}" + batchInfo);
    }

    @Override
    public void setSymmetricEngine(ISymmetricEngine engine) {
        _engine = engine;

    }
}
', current_timestamp, 'some user', current_timestamp);

当我尝试 运行 Sym 客户端时,我总是遇到异常。

20 Mar 2021 20:17:10 ERROR [org.jumpmind.symmetric.service.impl.ExtensionService] - <Error while compiling Java extension acknowledge batch>
org.jumpmind.util.SimpleClassCompilerException: Compilation of 'AcknowledgeListener' failed.
AcknowledgeListener at line 2, column 30: package org.jumpmind.symmetric does not exist
AcknowledgeListener at line 3, column 34: package org.jumpmind.symmetric.ext does not exist
AcknowledgeListener at line 4, column 36: package org.jumpmind.symmetric.model does not exist
AcknowledgeListener at line 5, column 40: package org.jumpmind.symmetric.transport does not exist
AcknowledgeListener at line 7, column 46: cannot find symbol
  symbol: class IAcknowledgeEventListener
AcknowledgeListener at line 7, column 73: cannot find symbol
  symbol: class ISymmetricEngineAware
AcknowledgeListener at line 8, column 5: cannot find symbol
  symbol:   class ISymmetricEngine
  location: class SimpleClassCompiler0
AcknowledgeListener at line 12, column 36: cannot find symbol
  symbol:   class BatchAck
  location: class SimpleClassCompiler0
AcknowledgeListener at line 21, column 36: cannot find symbol
  symbol:   class ISymmetricEngine
  location: class SimpleClassCompiler0
AcknowledgeListener at line 11, column 5: method does not override or implement a method from a supertype
AcknowledgeListener at line 20, column 5: method does not override or implement a method from a supertype

    at org.jumpmind.util.SimpleClassCompiler.getCompiledClass(SimpleClassCompiler.java:119)
    at org.jumpmind.symmetric.service.impl.ExtensionService.registerExtension(ExtensionService.java:110)
    at org.jumpmind.symmetric.service.impl.ExtensionService.refresh(ExtensionService.java:101)
    at org.jumpmind.symmetric.service.impl.ClientExtensionService.refresh(ClientExtensionService.java:46)
    at org.jumpmind.symmetric.AbstractSymmetricEngine.init(AbstractSymmetricEngine.java:348)
    at org.jumpmind.symmetric.ClientSymmetricEngine.init(ClientSymmetricEngine.java:205)
    at org.jumpmind.symmetric.ClientSymmetricEngine.<init>(ClientSymmetricEngine.java:148)
    at org.jumpmind.symmetric.ClientSymmetricEngine.<init>(ClientSymmetricEngine.java:152)
    at com.gourmet.symmetricds.SymDSStarter.postConstruct(SymDSStarter.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:346)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:299)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:132)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1448)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:609)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4705)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5171)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1663)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:286)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:482)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:431)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:286)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:468)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
    at javax.management.remote.rmi.RMIConnectionImpl.access0(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1408)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
    at sun.rmi.transport.Transport.run(Transport.java:200)
    at sun.rmi.transport.Transport.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=17=](TCPTransport.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

备注:

  1. 我已经尝试在 SQL 脚本中使用和不使用 package com.gourmet.listener; 路径。
  2. 我从 com.gourmet.listener 包中删除了 java 并编译了 .class 文件。
  3. symmetric-core-3.12.7.jar, symmetric-util-3.12.7.jarAcknowledgeListener.jar存在于WEB-INF/lib.

所以,不确定我错过了什么?

哈哈!

编辑

这太奇怪了,我注释掉了插入 sym_extension 的脚本并删除了所有 table 行(来自服务器和客户端数据库),.jar 文件留在 WEB-INF\lib 和我编译它的包中的 java 文件,突然它起作用了,我什至可以调试了。为什么 symmetricDS 甚至在 sym_extension table 中没有行时调用它??

扩展基本功能的 class 不应放在自定义包中。掉线:

package com.gourmet.listener;

然后添加包含以下内容的文件 conf/symmetric-extensions.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to JumpMind Inc under one or more contributor
    license agreements.  See the NOTICE file distributed
    with this work for additional information regarding
    copyright ownership.  JumpMind Inc licenses this file
    to you under the GNU General Public License, version 3.0 (GPLv3)
    (the "License"); you may not use this file except in compliance
    with the License.

    You should have received a copy of the GNU General Public License,
    version 3.0 (GPLv3) along with this library; if not, see
    <http://www.gnu.org/licenses/>.

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
       default-lazy-init="true">

    <bean id="acknowledgeListener" class="AcknowledgeListener" />
</beans>

如果您使用 sym_extension table 作为您的扩展代码,那么就没有什么可做的了。优点是您的扩展成为配置的一部分。您将 SymmetricDS 部署到 Tomcat,看起来它的类加载器层次结构正在阻止编译。如果您使用独立的 SymmetricDS 服务器,它会工作。

如果将代码编译为 JAR,可以将 Spring XML 文件放入名为 symmetric-extensions.xml 的 JAR 中的“conf”子目录中将您的扩展程序注册为 Spring bean。或者您可以编辑作为 SymmetricDS 安装一部分的文件 conf/symmetric-extensions.xml。我更喜欢将文件放在 JAR 中,这样它是独立的。