xjar icon indicating copy to clipboard operation
xjar copied to clipboard

使用xjar启动器启动集成了seata-all-1.3.0.jar的加密后的Spring Cloud项目时发生异常

Open HerveyHall opened this issue 3 years ago • 1 comments

我在项目中加入了xjar的Maven插件依赖,即在pom.xml中的project->build->plugins加入如下代码

             <plugin>
                 <groupId>com.github.core-lib</groupId>
                 <artifactId>xjar-maven-plugin</artifactId>
                 <version>4.0.2</version>
                 <executions>
                     <execution>
                         <goals>
                             <goal>build</goal>
                         </goals>
                         <phase>package</phase>
                         <configuration>
                             <password>pswd</password>
                         </configuration>
                     </execution>
                 </executions>
             </plugin>

并在project->pluginRepositories加入如下代码:

 		<pluginRepository>
 		    <id>jitpack.io</id>
 		    <url>https://jitpack.io</url>
 		</pluginRepository>

完成编译后,启动时打印了以下异常堆栈:

 2022-10-18 21:09:01.574 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
 io.seata.common.loader.EnhancedServiceNotFoundException: not found service provider for : io.seata.sqlparser.util.DbTypeParser caused by java.lang.IllegalStateException: Extension instance(definition: io.seata.common.loader.ExtensionDefinition@e625a923, class: interface io.seata.sqlparser.util.DbTypeParser)  could not be instantiated: Incompatible magic value 1873398948 in class file io/seata/sqlparser/druid/DruidDbTypeParserImpl
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.createNewExtension(EnhancedServiceLoader.java:406)
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.getExtensionInstance(EnhancedServiceLoader.java:388)
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.loadExtension(EnhancedServiceLoader.java:360)
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.load(EnhancedServiceLoader.java:249)
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.access$200(EnhancedServiceLoader.java:190)
         at io.seata.common.loader.EnhancedServiceLoader.load(EnhancedServiceLoader.java:82)
         at io.seata.rm.datasource.util.JdbcUtils.getDbTypeParser(JdbcUtils.java:46)
         at io.seata.rm.datasource.util.JdbcUtils.getDbType(JdbcUtils.java:57)
         at io.seata.rm.datasource.DataSourceProxy.init(DataSourceProxy.java:92)
         at io.seata.rm.datasource.DataSourceProxy.<init>(DataSourceProxy.java:85)
         at io.seata.rm.datasource.DataSourceProxy.<init>(DataSourceProxy.java:74)
         at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
         at io.seata.spring.annotation.datasource.DataSourceProxyHolder.putDataSource(DataSourceProxyHolder.java:64)
         at io.seata.spring.annotation.datasource.SeataAutoDataSourceProxyAdvice.invoke(SeataAutoDataSourceProxyAdvice.java:34)
         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
         at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
         at com.alibaba.druid.pool.DruidDataSource$$EnhancerBySpringCGLIB$$6febe76.toString(<generated>)
         at java.lang.String.valueOf(String.java:2994)
         at java.lang.StringBuilder.append(StringBuilder.java:131)
         at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:626)
         at org.springframework.jmx.export.MBeanExporter.lambda$registerBeans$2(MBeanExporter.java:552)
         at java.util.HashMap.forEach(HashMap.java:1289)
         at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:552)
         at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:435)
         at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:864)
         at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
         at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
         at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
         at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
         at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
         at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
         at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
         at xxx.xx.x.Application.main(Application.java:30)
         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.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
         at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
         at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
         at io.xjar.boot.XJarLauncher.launch(XJarLauncher.java:26)
         at io.xjar.boot.XJarLauncher.main(XJarLauncher.java:22)
 Caused by: java.lang.ClassFormatError: Incompatible magic value 1873398948 in class file io/seata/sqlparser/druid/DruidDbTypeParserImpl
         at java.lang.ClassLoader.defineClass1(Native Method)
         at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
         at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
         at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
         at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
         at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
         at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
         at java.security.AccessController.doPrivileged(Native Method)
         at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
         at io.seata.sqlparser.druid.DruidIsolationClassLoader.loadInternalClass(DruidIsolationClassLoader.java:53)
         at io.seata.sqlparser.druid.DruidIsolationClassLoader.loadClass(DruidIsolationClassLoader.java:42)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
         at io.seata.sqlparser.druid.DruidDelegatingDbTypeParser.setClassLoader(DruidDelegatingDbTypeParser.java:42)
         at io.seata.sqlparser.druid.DruidDelegatingDbTypeParser.<init>(DruidDelegatingDbTypeParser.java:32)
         at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
         at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
         at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
         at java.lang.Class.newInstance(Class.java:442)
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.initInstance(EnhancedServiceLoader.java:573)
         at io.seata.common.loader.EnhancedServiceLoader$InnerEnhancedServiceLoader.createNewExtension(EnhancedServiceLoader.java:402)
         ... 41 more

经过排查,发现抛出异常的方法代码如下:

        /**
         * init instance
         *
         * @param implClazz the impl clazz
         * @param argTypes  the arg types
         * @param args      the args
         * @return s s
         * @throws IllegalAccessException    the illegal access exception
         * @throws InstantiationException    the instantiation exception
         * @throws NoSuchMethodException     the no such method exception
         * @throws InvocationTargetException the invocation target exception
         */
        private S initInstance(Class implClazz, Class[] argTypes, Object[] args)
                throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
            S s = null;
            if (argTypes != null && args != null) {
                // Constructor with arguments
                Constructor<S> constructor = implClazz.getDeclaredConstructor(argTypes);
                s = type.cast(constructor.newInstance(args));
            } else {
                // default Constructor
                s = type.cast(implClazz.newInstance());
            }
            if (s instanceof Initialize) {
                ((Initialize)s).init();
            }
            return s;
        }

其中s = type.cast(implClazz.newInstance());这里调用Class#newInstance()方法抛出了异常,异常中所述无法被实例化的接口代码如下:

 /*
  *  Copyright 1999-2019 Seata.io Group.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  *  You may obtain a copy of the License at
  * 
  *       http://www.apache.org/licenses/LICENSE-2.0
  * 
  *  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.
  */
 package io.seata.sqlparser.util;
 
 /**
  * @author ggndnn
  */
 public interface DbTypeParser {
     String parseFromJdbcUrl(String jdbcUrl);
 }

提示魔数不兼容的类代码如下:

 /*
  *  Copyright 1999-2019 Seata.io Group.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  *  You may obtain a copy of the License at
  *
  *       http://www.apache.org/licenses/LICENSE-2.0
  *
  *  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.
  */
 package io.seata.sqlparser.druid;
 
 import com.alibaba.druid.util.JdbcUtils;
 import io.seata.sqlparser.util.DbTypeParser;
 
 /**
  * @author ggndnn
  */
 class DruidDbTypeParserImpl implements DbTypeParser {
     @Override
     public String parseFromJdbcUrl(String jdbcUrl) {
         return JdbcUtils.getDbType(jdbcUrl, null);
     }
 }

这两个Java文件都在seata-all-1.3.0.jar这个包中,这个包的MANIFEST.MF文件内容如下:

 Manifest-Version: 1.0
 Implementation-Title: Seata All-in-one 1.3.0
 Implementation-Version: 1.3.0
 Built-By: min.ji
 Specification-Vendor: Seata
 Specification-Title: Seata All-in-one 1.3.0
 Implementation-Vendor-Id: io.seata
 Implementation-Vendor: Seata
 Implementation-Build: 2020-07-15T17:30:56Z
 Created-By: Apache Maven 3.6.0
 Build-Jdk: 1.8.0_181
 Specification-Version: 1.3
 Implementation-URL: http://seata.io

以上是排查过程以及全部的相关信息,希望能够对定位问题有所帮助,非常感谢!

HerveyHall avatar Oct 19 '22 03:10 HerveyHall

seata 是基于蚂蚁SOFAboot的吧,它里面为了做模块隔离和类隔离,自定义了Classloader。xjar应该是不能直接用了,需要根据SOFAboot ark的相关原理修改xjar

kevinconan avatar Oct 31 '23 09:10 kevinconan

seata 是基于蚂蚁SOFAboot的吧,它里面为了做模块隔离和类隔离,自定义了Classloader。xjar应该是不能直接用了,需要根据SOFAboot ark的相关原理修改xjar

非常感谢。

HerveyHall avatar Apr 21 '24 12:04 HerveyHall

seata可以用,排掉就行了

<exclude>META-INF/**/*</exclude>
<exclude>io/seata/**</exclude>
 <exclude>LICENSE</exclude>
<exclude>lib/sqlparser/*</exclude>

wayne-89 avatar May 09 '24 14:05 wayne-89