记录:因为JDK编译版本问题,遇到的Base64的坑

今天遇到了一个BASE64Decoder的问题,记录一下。

报错异常信息:

  • Caused by: java.lang.NoClassDefFoundError: sun/misc/BASE64Decoder

一顿百度之后,发现根本原因是JDK版本从1.8之后就不再支持sun.misc.BASE64Encoder。那么解决方法很简单,找到一个合适的包,换掉import 引用。

难点:

引用BASE64Encoder的这个方法是源码级别的方法,没有办法直接修改引用。

再一顿百度。。发现使用Javassist 可以直接创建 .class文件,那么只要用这个工具创建出.class 进行包的替换,重新打包就可以解决。

首先用反编译工具打开需要编译的包,找到具体调用BASE64Decoder的方法

记录:因为JDK编译版本问题,遇到的Base64的坑

找到具体方法,这就是需要替换的类

记录:因为JDK编译版本问题,遇到的Base64的坑

用Javassist编写,执行main方法,代码编译版本会变成现有指定版本。

ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.timevale.esign.sdk.file.LocalFileServiceImpl");
        Base64.Encoder b64encoder = Base64.getEncoder();
        CtMethod method = cc.getDeclaredMethod("signPdf"
                ,new CtClass[]{pool.get("com.tsign.tgpdfsign.signature.Signature"),pool.get("java.lang.String"),pool.get("java.lang.String"),pool.get("java.lang.String"),pool.get("[B")}
                );
        method.setBody(" {/n" +
                "        try {/n" +
                "            if (!esign.util.StringUtil.isNull($4) && this.signImpl.setReader($4, /"/") > 0) {/n" +
                "                return new com.timevale.esign.result.file.SignPDFResult(1045, esign.constant.ErrorConstant.getErrMsg(1045));/n" +
                "            } else if (this.signImpl.GetPageNum() > 300) {/n" +
                "                return new com.timevale.esign.result.file.SignPDFResult(1052, esign.constant.ErrorConstant.getErrMsg(1052));/n" +
                "            } else if (esign.util.StringUtil.isNull($4) && this.signImpl.setReaderByte($5) > 0) {/n" +
                "                return new com.timevale.esign.result.file.SignPDFResult(1046, esign.constant.ErrorConstant.getErrMsg(1046));/n" +
                "            } else if (this.signImpl.SetSignatureInfo($1.ToSignXMLString()) > 0) {/n" +
                "                return new com.timevale.esign.result.file.SignPDFResult(1047, esign.constant.ErrorConstant.getErrMsg(1047));/n" +
                "            } else if (this.signImpl.CreateSignStamper() > 0) {/n" +
                "                return new com.timevale.esign.result.file.SignPDFResult(1048, esign.constant.ErrorConstant.getErrMsg(1048));/n" +
                "            } else {/n" +
                "                byte[] fileContentBytes = this.signImpl.GetFileContentBytes();/n" +
                "                byte[] result = null;/n" +
                "                java.security.MessageDigest md = java.security.MessageDigest.getInstance(DEFAULT_DIGEST.name());/n" +
                "                md.update(fileContentBytes);/n" +
                "                byte[] result = md.digest();/n" +
                "                java.util.Base64.Encoder b64encoder = java.util.Base64.getEncoder();/n" +
                "                String hashB64 = b64encoder.encodeToString(result);/n" +
                "                $1.setHashB64(hashB64);/n" +
                "                esign.model.File file = new esign.model.File();/n" +
                "                if (!esign.util.StringUtil.isNull(this.code)) {/n" +
                "                    file.setLoginCode(this.code);/n" +
                "                }/n" +
                "/n" +
                "                com.timevale.esign.result.sign.CountersignResult countersign;/n" +
                "                  $1.setSignatureAlgorithm(com.tsign.tgpdfsign.config.SystemConfig.SignatureAlgorithm.SGD_SM3_SM2);/n" +
                "                                   countersign = this.signHashByZJCA($2, $3, $1.getHashB64());/n" +
                "                                   if (countersign.getErrCode() != 0) {/n" +
                "                                       $1.setSignatureAlgorithm(com.tsign.tgpdfsign.config.SystemConfig.SYSTEM_SIGN_ALGORITHM);/n" +
                "                                       countersign = this.signHash($2, $3, $1.getHashB64());/n" +
                "                                       if (countersign.getErrCode() != 0) {/n" +
                "                                           return new com.timevale.esign.result.file.SignPDFResult(countersign.getErrCode(), esign.constant.ErrorConstant.getErrMsg(countersign.getErrCode()));/n" +
                "                                       }/n" +
                "/n" +
                "                                       $1.setSignResult(countersign.getSignResult());/n" +
                "                                   } else {/n" +
                "                                       $1.setSignResult(countersign.getSignResult());/n" +
                "                                   }/n" +
                "/n" +
                "                if (org.apache.commons.lang.StringUtils.isNotBlank(esign.util.Oauth2Config.tsa_url)) {/n" +
                "                    if (this.signImpl.AddSignData($1.getSignResult(), $1.getHashB64(), esign.util.Oauth2Config.tsa_url) > 0) {/n" +
                "                        return new com.timevale.esign.result.file.SignPDFResult(1050, esign.constant.ErrorConstant.getErrMsg(1050));/n" +
                "                    }/n" +
                "                } else if (this.signImpl.AddSignData($1.getSignResult(), $1.getHashB64()) > 0) {/n" +
                "                    return new com.timevale.esign.result.file.SignPDFResult(1050, esign.constant.ErrorConstant.getErrMsg(1050));/n" +
                "                }/n" +
                "/n" +
                "                $1.setSignDate(this.signImpl.GetSignDate());/n" +
                "                this.outByte = this.signImpl.GetOutputByte();/n" +
                "                esign.bean.SignLogBean bean = new esign.bean.SignLogBean();/n" +
                "                String docName = this.signImpl.getFieldName();/n" +
                "                bean.setDocName(docName);/n" +
                "                bean.setSid($1.getSid());/n" +
                "                bean.setSignInfo($1.getSignResult());/n" +
                "                bean.setTimestamp($1.getSignDate());/n" +
                "                com.timevale.esign.sdk.sign.SignLogService signLogService = new com.timevale.esign.sdk.sign.SignLogServiceImpl();/n" +
                "                if (org.apache.commons.lang.StringUtils.isNotBlank(this.code)) {/n" +
                "                    signLogService.setLoginCode(this.code);/n" +
                "                }/n" +
                "/n" +
                "                com.timevale.esign.result.BaseResult signLogResult = signLogService.save($2, bean);/n" +
                "                return signLogResult != null && signLogResult.getErrCode() <= 0 ? new com.timevale.esign.result.file.SignPDFResult(0, esign.constant.ErrorConstant.getErrMsg(0)) : new com.timevale.esign.result.file.SignPDFResult(1054, esign.constant.ErrorConstant.getErrMsg(1054));/n" +
                "            }/n" +
                "        } catch (Exception var16) {/n" +
                "            var16.printStackTrace();/n" +
                "            return null;/n" +
                "        }/n" +
                "    }");

        cc.writeFile("C://输出文件路径");复制代码

代码比对:

记录:因为JDK编译版本问题,遇到的Base64的坑

这只是其中一个报错的方法,前前后后修改了好几个类好几个方法才把这个问题改好。。

附上参考的Javassist 教程:

javassist使用全解析 – rickiyang – 博客

原文 

https://juejin.im/post/5ea83c506fb9a0435902813b

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 记录:因为JDK编译版本问题,遇到的Base64的坑

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址