精华内容
下载资源
问答
  • 使用URLClassLoader加载不同Jar包中的相同包名相同类名的类 开发中会遇到这种情况,使用一项功能需要依赖jar,然而一段时间后这些包升级,包名和类名均不变的情况下功能发生变化。旧的jar依然需要使用,而新功能却...

    使用URLClassLoader加载不同Jar包中的相同包名相同类名的类

    开发中会遇到这种情况,使用一项功能需要依赖jar,然而一段时间后这些包升级,包名和类名均不变的情况下功能发生变化。旧的jar依然需要使用,而新功能却需要使用新升级的jar。这时如果依赖两个包,使用时会造成冲突。因此需要进行jar隔离。有很多的隔离框架可以使用,如jarlinks。本文将演示通过URLClassLoader加载器来进行隔离的基本方法,而实应用中的的一些隔离框架中也会看到此种方式的使用。

    首先原有系统内部依赖version782.jar包,并用到该包中的RequestHead类。而此时又希望用到version713.jar包中的RequestHead类。直接增加maven依赖会产生冲突,这里通过URLClassLoader进行加载。

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import xxx.RequestHead;
    import org.apache.commons.codec.binary.Hex;
    
    import java.io.File;
    import java.lang.reflect.Method;
    import java.net.URL;
    import java.net.URLClassLoader;
    
    public class ClassLoadTest {
    
        public static void main(String[] args) throws Exception {
            URL url = new File("/version713.jar").toURI().toURL();
            // 创建URLClassLoader,并设置父加载器为null,这样通过加载器加载
            // 类时就不会通过父加载器去通过classpath中加载version782.jar
            // 中的RequestHead
            URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url}, null);
    
            // 加载version713.jar包中的RequestHead类
            Class<?> clz = urlClassLoader.loadClass("xxx.RequestHead");
            // 加载序列化工具类,由于要通过反射调用ProtoBufferCore中的方法
            // 而且需要指定Class参数,这个参数需要与ProtoBufferCore使用相同
            // 的类加载器,因此后续加载参数CtripBusinessBean
            Class<?> pb = urlClassLoader.loadClass("xxx.ProtoBufferCore");
            // 加载参数CtripBusinessBean,调用ProtoBufferCore方法时使用
            Class<?> ctripBizBean = urlClassLoader.loadClass("xxx.CtripBusinessBean");
    
            RequestHead head782 = new RequestHead();
            Object head713 = clz.newInstance();
    
            Object pbObject = pb.newInstance();
    
            System.out.println(pbObject);
            System.out.println(JSON.toJSONString(head713, SerializerFeature.WriteNullStringAsEmpty));
            System.out.println(JSON.toJSONString(head782, SerializerFeature.WriteNullStringAsEmpty));
    
            clz.getField("appId").set(head713,"999111");
            // 这里进行方法调用时,执行参数上文中加载的ctripBizBean,
            // 这样才能保证正确调用
            Method toByteArrayMethod = pb.getMethod("toByteArray",ctripBizBean);
            String hex = Hex.encodeHexString((byte[]) toByteArrayMethod.invoke(pbObject,head713));
            System.out.println(hex);
        }
    }

    参考

    java虚拟机规范5.3节

    展开全文
  • 类的加载与jar的导入顺序有关。只会加载第一个。

    类的加载与jar的导入顺序有关。只会加载第一个。

    展开全文
  • 两个不同jar包下相同文件的获取: 1、创建3个工程(test,test2 ,testDemo)  test和test2 资源目录下有相同的配置文件(/META/prop.properties)  testDemo 为获取配置文件的工程; testDemo代码: ...

    两个不同jar包下相同文件的获取:

    1、创建3个工程(test,test2 ,testDemo)

       test和test2 资源目录下有相同的配置文件(/META/prop.properties)

      testDemo 为获取配置文件的工程;

    testDemo代码:

    import java.io.*;
    import java.net.URL;
    import java.util.Enumeration;
    
    public class DemoApplication {
    
        public static void main(String... arg) {
            readProp();
            System.out.println("-------------");
            scanProps();
        }
    
        public static void readProp() {
            InputStream is = DemoApplication.class.getResourceAsStream("/META-INF/prop.properties");
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String s = "";
            try {
                while ((s = br.readLine()) != null){
                    System.out.println(s);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void scanProps(){
            Enumeration<URL> urls = null;
            URL url = null;
            try {
                urls = Thread.currentThread().getContextClassLoader().getResources("META-INF/prop.properties");
                System.out.println("是否发现有文件?" + urls.hasMoreElements());
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            while(urls.hasMoreElements()) {
                InputStream in = null;
                try {
                    in = urls.nextElement().openStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(in));
                    String s = "";
                    while ((s = br.readLine()) != null){
                        System.out.println(s);
                    }
                } catch (Exception e){
                    e.printStackTrace();
                }finally {
                    if(in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    

    输出:

    name=test
    -------------
    是否发现有文件?true
    name=test
    name=test2
    

    注:我们能通过

    InputStream is = DemoApplication.class.getResourceAsStream("/META-INF/prop.properties"); 

    只能获取的第一个jar包的配置文件,

    通过

     urls = Thread.currentThread().getContextClassLoader().getResources("META-INF/prop.properties");

    我们能获取到所有jar包下的文件

    通过getResourceAsStream获取需要需要在路径中添加根路径符号'/'

    而通过classLoader.getResource 获取则不能添加根路径符号'/'

    展开全文
  • 修改jar包中class文件

    千次阅读 2020-04-02 00:29:22
    需求:银行跑批任务执行时要调用行方自己的短信平台给科技部人员发送短信,行方提供一个jar文件,通过shell脚本传参调用即可。 问题点:shell脚本调用jar包没太大问题,关键在于,需要在jar...替换class文件—&g...

    需求:银行跑批任务执行时要调用行方自己的短信平台给科技部人员发送短信,行方提供一个jar文件,通过shell脚本传参调用即可。

    问题点:shell脚本调用jar包没太大问题,关键在于,需要在jar包中的某个类中配置短信平台的用户名、密码。

    解决方案:将jar反编译—>保存为.java文件—>修改文件内容—>重新编译—>将原来jar包解压—>替换class文件—>压缩为jar包。


    是时候表演真正的技术啦!


    首先,看一下我的msg.jar包的结构,直接解压是这样式的~

    我要修改的代码就是这个T.class,但是class文件没办法直接修改

    所以我们需要反编译工具,我使用的是jd-gui。

    链接:https://pan.baidu.com/s/1qP4N8Uvss8lRbWp_1h91Fg 
    提取码:i6mk

    打开后:

    反编译还是没办法直接修改的,Ctrl+S将其保存为.java文件

    保存之后就可以通过编辑工具进行修改了,因为我的这个类是依赖了其他很多类的,修改完直接javac编译该文件会报错

    所以,我们要建一个项目,为这个java文件配置相同的目录结构,把这个类所依赖的jar包(其实就是本jar包,但是要先解压,然后把该类的class文件删掉,再压缩为jar文件即可,压缩为jar包的方式见后边)导入,将项目打成jar包,再将jar包解压,将修改的类的class文件拿出来就可以了。

    为了简便,我用idea直接建了一个spring boot项目,

    因为我要改的class文件就在jar包根目录下,所以我直接保存后的java文件放到启动类同目录就行了,如果不是的话,根据class文件所在jar包的目录结构在项目中创建对应目录结构即可。

    这时候,其实是会报错的,因为依赖的很多类都没有,但我已经引入jar包了,所以不会报错。

    引入剔除该class文件的jar包

     

    还有修改一下jdk之类的操作不细说了,pom文件加一下本地jar包依赖、jdk版本、和编译打包的一些依赖配置。

    <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>com.jugan.util</groupId>
                <artifactId>com.jugan.util</artifactId>
                <version>1.0</version>
                <scope>system</scope>
                <systemPath>${project.basedir}/lib/msg.jar</systemPath>
            </dependency>
        </dependencies>
    
        <build>
    
            <resources>
                <resource>
                    <directory>lib</directory>
    <!--                <targetPath>BOOT-INF/lib/</targetPath>-->
                    <includes>
                        <include>F:/workspace/msg/lib/msg.jar</include>
                    </includes>
                </resource>
            </resources>
    
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>

    然后,修改代码

    maven 编译打包

    编译打包成功,去把打好的jar包中的class文件拿出来,替换掉原始jar包中的class文件,

    然后将其压缩为jar包。

    注意,在解压缩的jar包的文件夹里边选中所有文件进行压缩,直接压缩文件夹的话,会多出一层。

    大功告成。

     

     

    展开全文
  • 以下是代码实验public class Test { public static void main(String[] args) throws Exception{ //当前Test类所在目录(包)的a.txt System.out.println(Test.class.getResource("a.txt")); //当前项目的根目录的a....
  • 之前碰到一个疑虑,客户生产环境里面jar包里面的class文件和src 路径下 编译出来的class 相同(包名,类名,里面的逻辑不同), 但偏偏在客户那里正常跑了3个月(tomcat),于是自己写了个demo public class ...
  • 今天在做项目的时候遇到了一个很有意思的问题...找啊找啊找原因,查看引用的包,才发现我所引用的包名和同事引用的包名是相同的,不同的是我两引用的包不是一个jar。也就是说不同jar里包含了相同的包名和类名。 ...
  • 替换jar包中的class文件并重新打包

    千次阅读 2020-04-16 14:57:24
    适用于无源码jar或涉及切换环境参数及不确定影响的情况下,减少对原jar的修改 一定要备份,一定要备份,一定要备份 1.将原jar包下载到本地目录 /Users/user/fsdownload/aa.jar 2.将原jar包解压缩–原解压文件 /Users/...
  • Jar包中Class文件替换

    千次阅读 2020-08-05 15:09:58
    说明:本文是已经对java文件进行编译了之后,已经形成了class文件,在这里只涉及用class文件直接替换jar包里面的class文件 Ps: 至于如何拿出jar包的class文件,反编译修改改文件后又重新编译,再放入原文件重新打jar...
  • 如:Program type already present: org.apache....class ->查询 2 双击寻找重复jar包位置 然后通过以下方式处理: (1)删除重复jar包问题 Or (2)用exclude解决,大概意思就是去掉 你不需要的类 如: ...
  • 【转】java class生成jar

    千次阅读 2017-10-19 22:41:33
    进入dos操作符窗口cd进入要打成jar包的class文件所有文件夹目录jar cvf [生成jar的名称.jar] [列出class文件] //若多个,以空隔隔开如:一。操作零散的单个或几个class文件jar cvf ibstool.jar ...
  • ■前言 使用Jenkins自动打包,生成jar... (只有一个class文件是不同的,其余的class文件都相同) ■原因 JDK的小版本不同 ■详细 使用的JDK都是java 8, 大版本是相同的,小版本不同 ・①Jenkins所...
  • java -jar 报错,classnotfound

    千次阅读 2015-06-15 16:18:07
    打包可执行jar包时,MANIFEST.MF总是个让人头疼的东西,经常出现这种那种问题。  一个例子:  ================================================================================  Manifest-Version: 1.0  ...
  • java class文件生成jar

    千次阅读 2014-06-20 14:35:44
    java class文件生成jar包  2008-08-12 10:28:01| 分类: java技术文档|举报|字号 订阅 ...jar cvf [生成jar的名称.jar] [列出class文件] //若多个,以空隔隔开 如: 一。操作零散的单个或几个
  • java class生成jar

    万次阅读 2012-11-29 21:11:52
    jar cvf [生成jar的名称.jar] [列出class文件] //若多个,以空隔隔开 如: 一。操作零散的单个或几个class文件 jar cvf ibstool.jar com/cn/ibs/TurnD.class com/cn/ibs/TurnB.class   二。
  • 检测多个Jar包冲突的class

    千次阅读 2014-10-10 17:16:41
    为了提前找到存在相同classjar包,我准备写一个小程序,由于是操作jar包等,需要用Java代码来处理,但写出来一般是一个class文件,使用者可能需要用命令行执行的方式来调用它,java的桌面程序我不擅长,于是想到了...
  • 这里所说的冲突,是指类的包名和类型完全相同的时候希望同时使用相同类的不同版本)。 参考地址:https://baijiahao.baidu.com/s?id=1636309817155065432&wfr=spider&for=pc 处理思路:见上图,使用...
  • 需求产生的原因,时候我们接入三方包的时候,会出现类冲突,这个时候我们就想能不能把三方包中的冲突类过滤掉,不参与编译。...AAR库的Class和SO文件过滤 将aar库导入项目的方式2种: 1, android{ ...
  • linux下替换jar包里面的class文件

    千次阅读 2020-05-29 16:08:29
    linux相应目录下:zcsfastDFSTest-0.0.1-SNAPSHOT.jar 步骤如下: 如果要替换的文件在jar包的二级及以下目录下,则需要以下步骤: (1)使用jar tvf jar名称 | grep 目标文件名 查询出目标文件在war包中的目录 ...
  • IDEA 对java指定的class打包jar

    千次阅读 2019-04-30 14:44:49
    1、对项目进行编译,生成class文件 2、File——>...3、对jar包进行命名,并设置输出路径(可选),通过点击2,创建与class类路径相同的目录。 4、点击绿色加号——>File,选取需要打包的...
  • 【Java】jar包中 类名相同

    千次阅读 2018-12-09 19:08:39
    如果类路径下两个全限定名完全相同的类,而且另一个类import了这个全限定名,会怎么样? 下面验证下: import com.liyao.lib.Util; public class Main{ public static void main(String args[]){ System.out...
  • 如何将.class文件打成jar

    万次阅读 2011-01-10 17:31:00
    网上的例子不是太清楚,自己写一下过程并加几个图,免得今后又得看半天资料 1、 把两个.class文件打成jar包 (1)打开cmd ...如:jar cvf chart.jar ExampleService.class Examples.class (4)OK,标红框的是
  • 如何将class文件打jar

    千次阅读 2013-07-15 12:04:26
    jar cvf [生成jar的名称.jar] [列出class文件] //若多个,以空隔隔开 如: 一。操作零散的单个或几个class文件 jar cvf ibstool.jar com/cn/ibs/TurnD.classcom/cn/ibs/TurnB.class   二。把一个文件夹下面...
  • 命令行执行class文件和jar文件

    千次阅读 2015-01-20 14:27:40
    在d:/test/lib目录下,一个Mains.java文件 使用命令javac编译,执行成功: D:\test\lib>javac Mains.java此时使用java命名行运行编译后的class文件,则报NoClassDefFoundError错误: D:\test\lib>java Mains ...
  • Java把class文件打包成jar

    千次阅读 2015-01-07 18:08:39
     转载自:... 怎么样把自己经常用到的类文件打包成jar文件,以方便自己在开发项目的时候引用。下面就总结一下打包的步骤:  1、把需要打包成jar包的文件,先产生成.class文件如下:  1》、在dos
  • 如下图所示,httpclient与httpcore存在不同的版本,导致用到该jar的功能模块报错,主要的错误是,不能够识别到底该用哪一版本的class的方法 图1 解决方案 【解决方案1】 删除httpclient-4.2.3.jar 删除...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 152,677
精华内容 61,070
关键字:

不同jar有相同class