From c021cf48cacc9e4e639fdb0339767fa63ae5b306 Mon Sep 17 00:00:00 2001 From: shaozhuguang Date: Tue, 2 Jul 2019 19:43:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=88=E7=BA=A6=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=BC=82=E5=B8=B8=E5=88=A0=E9=99=A4=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jd/blockchain/ContractCheckMojo.java | 213 --------- .../jd/blockchain/ContractDeployExeUtil.java | 193 -------- .../com/jd/blockchain/ContractDeployMojo.java | 119 ----- .../com/jd/blockchain/ContractVerifyMojo.java | 432 ------------------ .../contract/maven/ContractVerifyMojo.java | 3 + 5 files changed, 3 insertions(+), 957 deletions(-) delete mode 100644 source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java delete mode 100644 source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployExeUtil.java delete mode 100644 source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java delete mode 100644 source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java deleted file mode 100644 index a57357e0..00000000 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.jd.blockchain; - -import org.apache.commons.io.FileUtils; -import org.apache.maven.model.Model; -import org.apache.maven.model.Plugin; -import org.apache.maven.model.PluginExecution; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.invoker.*; -import org.codehaus.plexus.util.xml.Xpp3Dom; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - - -@Mojo(name = "contractCheck") -public class ContractCheckMojo extends AbstractMojo { - - Logger LOG = LoggerFactory.getLogger(ContractCheckMojo.class); - - public static final String CONTRACT_VERIFY = "contractVerify"; - - private static final String CONTRACT_MAVEN_PLUGIN = "contract-maven-plugin"; - - private static final String MAVEN_ASSEMBLY_PLUGIN = "maven-assembly-plugin"; - - private static final String JDCHAIN_PACKAGE = "com.jd.blockchain"; - - private static final String APACHE_MAVEN_PLUGINS = "org.apache.maven.plugins"; - - private static final String GOALS_VERIFY = "package"; - - private static final String GOALS_PACKAGE = "package"; - - private static final String OUT_POM_XML = "ContractPom.xml"; - - @Parameter(defaultValue = "${project}", required = true, readonly = true) - private MavenProject project; - - /** - * jar's name; - */ - @Parameter - private String finalName; - - /** - * mainClass; - */ - @Parameter - private String mainClass; - /** - * ledgerVersion; - */ - @Parameter - private String ledgerVersion; - - /** - * mvnHome; - */ - @Parameter - private String mvnHome; - - /** - * first compile the class, then parse it; - */ - @Override - public void execute() throws MojoFailureException { - compileFiles(); - } - - private void compileFiles() throws MojoFailureException { - try (FileInputStream fis = new FileInputStream(project.getFile())) { - - MavenXpp3Reader reader = new MavenXpp3Reader(); - Model model = reader.read(fis); - - //delete this plugin(contractCheck) from destination pom.xml;then add the proper plugins; - Plugin plugin = model.getBuild().getPluginsAsMap() - .get(JDCHAIN_PACKAGE + ":" + CONTRACT_MAVEN_PLUGIN); - if(plugin == null){ - plugin = model.getBuild().getPluginsAsMap() - .get(APACHE_MAVEN_PLUGINS + ":" + CONTRACT_MAVEN_PLUGIN); - } - - if(plugin == null) { - return; - } - - model.getBuild().removePlugin(plugin); - - List plugins = new ArrayList<>(); - plugins.add(createAssembly()); - plugins.add(createContractVerify()); - - model.getBuild().setPlugins(plugins); - - handle(model); - - } catch (Exception e) { - LOG.error(e.getMessage()); - throw new MojoFailureException(e.getMessage()); - } - } - - private void invokeCompile(File file) { - InvocationRequest request = new DefaultInvocationRequest(); - - Invoker invoker = new DefaultInvoker(); - try { - request.setPomFile(file); - - request.setGoals(Collections.singletonList(GOALS_VERIFY)); - invoker.setMavenHome(new File(mvnHome)); - invoker.execute(request); - } catch (MavenInvocationException e) { - LOG.error(e.getMessage()); - throw new IllegalStateException(e); - } - } - - private Plugin createContractVerify() { - Plugin plugin = new Plugin(); - plugin.setGroupId(JDCHAIN_PACKAGE); - plugin.setArtifactId(CONTRACT_MAVEN_PLUGIN); - plugin.setVersion(ledgerVersion); - - Xpp3Dom finalNameNode = new Xpp3Dom("finalName"); - finalNameNode.setValue(finalName); - Xpp3Dom configuration = new Xpp3Dom("configuration"); - configuration.addChild(finalNameNode); - - plugin.setConfiguration(configuration); - plugin.setExecutions(pluginExecution("make-assembly", GOALS_VERIFY, CONTRACT_VERIFY)); - - return plugin; - } - - private Plugin createAssembly() { - Plugin plugin = new Plugin(); - plugin.setArtifactId(MAVEN_ASSEMBLY_PLUGIN); - - Xpp3Dom configuration = new Xpp3Dom("configuration"); - - Xpp3Dom mainClassNode = new Xpp3Dom("mainClass"); - mainClassNode.setValue(mainClass); - - Xpp3Dom manifest = new Xpp3Dom("manifest"); - manifest.addChild(mainClassNode); - - Xpp3Dom archive = new Xpp3Dom("archive"); - archive.addChild(manifest); - - Xpp3Dom finalNameNode = new Xpp3Dom("finalName"); - finalNameNode.setValue(finalName); - - Xpp3Dom appendAssemblyId = new Xpp3Dom("appendAssemblyId"); - appendAssemblyId.setValue("false"); - - Xpp3Dom descriptorRef = new Xpp3Dom("descriptorRef"); - descriptorRef.setValue("jar-with-dependencies"); - Xpp3Dom descriptorRefs = new Xpp3Dom("descriptorRefs"); - descriptorRefs.addChild(descriptorRef); - - configuration.addChild(finalNameNode); - configuration.addChild(appendAssemblyId); - configuration.addChild(archive); - configuration.addChild(descriptorRefs); - - plugin.setConfiguration(configuration); - plugin.setExecutions(pluginExecution("make-assembly", GOALS_PACKAGE, "single")); - - return plugin; - } - - private List pluginExecution(String id, String phase, String goal) { - PluginExecution pluginExecution = new PluginExecution(); - pluginExecution.setId(id); - pluginExecution.setPhase(phase); - List goals = new ArrayList<>(); - goals.add(goal); - pluginExecution.setGoals(goals); - List pluginExecutions = new ArrayList<>(); - pluginExecutions.add(pluginExecution); - - return pluginExecutions; - } - - private void handle(Model model) throws IOException { - - MavenXpp3Writer mavenXpp3Writer = new MavenXpp3Writer(); - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - - mavenXpp3Writer.write(outputStream, model); - - byte[] buffer = outputStream.toByteArray(); - - File outPom = new File(project.getBasedir().getPath(), OUT_POM_XML); - - FileUtils.writeByteArrayToFile(outPom, buffer); - - invokeCompile(outPom); - } -} diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployExeUtil.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployExeUtil.java deleted file mode 100644 index a206a854..00000000 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployExeUtil.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.jd.blockchain; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import com.jd.blockchain.binaryproto.DataContractRegistry; -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.crypto.PrivKey; -import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.BlockchainIdentity; -import com.jd.blockchain.ledger.BlockchainIdentityData; -import com.jd.blockchain.ledger.BlockchainKeyGenerator; -import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.ledger.ContractCodeDeployOperation; -import com.jd.blockchain.ledger.ContractEventSendOperation; -import com.jd.blockchain.ledger.DataAccountKVSetOperation; -import com.jd.blockchain.ledger.DataAccountRegisterOperation; -import com.jd.blockchain.ledger.EndpointRequest; -import com.jd.blockchain.ledger.NodeRequest; -import com.jd.blockchain.ledger.Operation; -import com.jd.blockchain.ledger.PreparedTransaction; -import com.jd.blockchain.ledger.TransactionContent; -import com.jd.blockchain.ledger.TransactionContentBody; -import com.jd.blockchain.ledger.TransactionRequest; -import com.jd.blockchain.ledger.TransactionResponse; -import com.jd.blockchain.ledger.TransactionTemplate; -import com.jd.blockchain.ledger.UserRegisterOperation; -import com.jd.blockchain.sdk.BlockchainService; -import com.jd.blockchain.sdk.client.GatewayServiceFactory; -import com.jd.blockchain.tools.keygen.KeyGenCommand; -import com.jd.blockchain.utils.Bytes; -import com.jd.blockchain.utils.codec.Base58Utils; -import com.jd.blockchain.utils.net.NetworkAddress; - -/** - * @Author zhaogw - * @Date 2018/11/2 10:18 - */ -public enum ContractDeployExeUtil { - instance; - private BlockchainService bcsrv; - private Bytes contractAddress; - - public BlockchainKeypair getKeyPair(String pubPath, String prvPath, String rawPassword){ - PubKey pub = null; - PrivKey prv = null; - try { - prv = KeyGenCommand.readPrivKey(prvPath, KeyGenCommand.encodePassword(rawPassword)); - pub = KeyGenCommand.readPubKey(pubPath); - - } catch (Exception e) { - e.printStackTrace(); - } - - return new BlockchainKeypair(pub, prv); - } - - public PubKey getPubKey(String pubPath){ - PubKey pub = null; - try { - if(pubPath == null){ - BlockchainKeypair contractKeyPair = BlockchainKeyGenerator.getInstance().generate(); - pub = contractKeyPair.getPubKey(); - }else { - pub = KeyGenCommand.readPubKey(pubPath); - } - - } catch (Exception e) { - e.printStackTrace(); - } - - return pub; - } - public byte[] getChainCode(String path){ - byte[] chainCode = null; - File file = null; - InputStream input = null; - try { - file = new File(path); - input = new FileInputStream(file); - chainCode = new byte[input.available()]; - input.read(chainCode); - - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - if(input!=null){ - input.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - return chainCode; - } - - private void register(){ - DataContractRegistry.register(TransactionContent.class); - DataContractRegistry.register(TransactionContentBody.class); - DataContractRegistry.register(TransactionRequest.class); - DataContractRegistry.register(NodeRequest.class); - DataContractRegistry.register(EndpointRequest.class); - DataContractRegistry.register(TransactionResponse.class); - DataContractRegistry.register(DataAccountKVSetOperation.class); - DataContractRegistry.register(DataAccountKVSetOperation.KVWriteEntry.class); - DataContractRegistry.register(Operation.class); - DataContractRegistry.register(ContractCodeDeployOperation.class); - DataContractRegistry.register(ContractEventSendOperation.class); - DataContractRegistry.register(DataAccountRegisterOperation.class); - DataContractRegistry.register(UserRegisterOperation.class); - } - - public BlockchainService initBcsrv(String host, int port) { - if(bcsrv!=null){ - return bcsrv; - } - NetworkAddress addr = new NetworkAddress(host, port); - GatewayServiceFactory gwsrvFact = GatewayServiceFactory.connect(addr); - bcsrv = gwsrvFact.getBlockchainService(); - return bcsrv; - } - - public boolean deploy(HashDigest ledgerHash, BlockchainIdentity contractIdentity, BlockchainKeypair ownerKey, byte[] chainCode){ - register(); - - TransactionTemplate txTpl = bcsrv.newTransaction(ledgerHash); - txTpl.contracts().deploy(contractIdentity, chainCode); - PreparedTransaction ptx = txTpl.prepare(); - ptx.sign(ownerKey); - // 提交并等待共识返回; - TransactionResponse txResp = ptx.commit(); - - // 验证结果; - contractAddress = contractIdentity.getAddress(); - this.setContractAddress(contractAddress); - System.out.println("contract's address="+contractAddress); - return txResp.isSuccess(); - } - public boolean deploy(String host, int port, HashDigest ledgerHash, BlockchainKeypair ownerKey, byte[] chainCode){ - register(); - - BlockchainIdentity contractIdentity = BlockchainKeyGenerator.getInstance().generate().getIdentity(); - initBcsrv(host,port); - return deploy(ledgerHash, contractIdentity, ownerKey, chainCode); - } - - // 根据用户指定的公钥生成合约地址 - public boolean deploy(String host, int port, String ledger,String ownerPubPath, String ownerPrvPath, - String ownerPassword, String chainCodePath,String pubPath){ - PubKey pubKey = getPubKey(pubPath); - BlockchainIdentity contractIdentity = new BlockchainIdentityData(pubKey); - byte[] chainCode = getChainCode(chainCodePath); - - BlockchainKeypair ownerKey = getKeyPair(ownerPubPath, ownerPrvPath, ownerPassword); - HashDigest ledgerHash = new HashDigest(Base58Utils.decode(ledger)); - initBcsrv(host,port); - return deploy(ledgerHash, contractIdentity, ownerKey, chainCode); - } - - -// 暂不支持从插件执行合约;此外,由于合约参数调用的格式发生变化,故此方法被废弃;by: huanghaiquan at 2019-04-30; - -// public boolean exeContract(String ledger,String ownerPubPath, String ownerPrvPath, -// String ownerPassword,String event,String contractArgs){ -// BlockchainKeypair ownerKey = getKeyPair(ownerPubPath, ownerPrvPath, ownerPassword); -// HashDigest ledgerHash = new HashDigest(Base58Utils.decode(ledger)); -// -// // 定义交易,传输最简单的数字、字符串、提取合约中的地址; -// TransactionTemplate txTpl = bcsrv.newTransaction(ledgerHash); -// txTpl.contractEvents().send(getContractAddress(),event,contractArgs.getBytes()); -// -// // 签名; -// PreparedTransaction ptx = txTpl.prepare(); -// ptx.sign(ownerKey); -// -// // 提交并等待共识返回; -// TransactionResponse txResp = ptx.commit(); -// -// // 验证结果; -// return txResp.isSuccess(); -// } - - public Bytes getContractAddress() { - return contractAddress; - } - - public void setContractAddress(Bytes contractAddress) { - this.contractAddress = contractAddress; - } -} diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java deleted file mode 100644 index 3eac13bb..00000000 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractDeployMojo.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.jd.blockchain; - -import com.jd.blockchain.crypto.HashDigest; -import com.jd.blockchain.crypto.PrivKey; -import com.jd.blockchain.crypto.PubKey; -import com.jd.blockchain.ledger.BlockchainKeypair; -import com.jd.blockchain.tools.keygen.KeyGenCommand; -import com.jd.blockchain.utils.StringUtils; -import com.jd.blockchain.utils.codec.Base58Utils; -import com.jd.blockchain.utils.io.FileUtils; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -/** - * for contract remote deploy; - * @goal contractDeploy - * @phase process-sources - * @Author zhaogw - * @Date 2018/10/18 10:12 - */ - -@Mojo(name = "deploy") -public class ContractDeployMojo extends AbstractMojo { - Logger logger = LoggerFactory.getLogger(ContractDeployMojo.class); - - @Parameter - private File config; - - @Override - public void execute()throws MojoFailureException { - Properties prop = new Properties(); - InputStream input = null; - - try { - input = new FileInputStream(config); - prop.load(input); - - } catch (IOException ex) { - logger.error(ex.getMessage()); - throw new MojoFailureException("io error"); - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException e) { - logger.error(e.getMessage()); - } - } - } - int port; - try { - port = Integer.parseInt(prop.getProperty("port")); - }catch (NumberFormatException e){ - logger.error(e.getMessage()); - throw new MojoFailureException("invalid port"); - } - String host = prop.getProperty("host"); - String ledger = prop.getProperty("ledger"); - String pubKey = prop.getProperty("pubKey"); - String prvKey = prop.getProperty("prvKey"); - String password = prop.getProperty("password"); - String contractPath = prop.getProperty("contractPath"); - - - if(StringUtils.isEmpty(host)){ - logger.info("host不能为空"); - return; - } - - if(StringUtils.isEmpty(ledger)){ - logger.info("ledger不能为空."); - return; - } - if(StringUtils.isEmpty(pubKey)){ - logger.info("pubKey不能为空."); - return; - } - if(StringUtils.isEmpty(prvKey)){ - logger.info("prvKey不能为空."); - return; - } - if(StringUtils.isEmpty(contractPath)){ - logger.info("contractPath不能为空."); - return; - } - - File contract = new File(contractPath); - if (!contract.isFile()){ - logger.info("文件"+contractPath+"不存在"); - return; - } - byte[] contractBytes = FileUtils.readBytes(contractPath); - - - PrivKey prv = KeyGenCommand.decodePrivKeyWithRawPassword(prvKey, password); - PubKey pub = KeyGenCommand.decodePubKey(pubKey); - BlockchainKeypair blockchainKeyPair = new BlockchainKeypair(pub, prv); - HashDigest ledgerHash = new HashDigest(Base58Utils.decode(ledger)); - - StringBuffer sb = new StringBuffer(); - sb.append("host:"+ host).append(",port:"+port).append(",ledgerHash:"+ledgerHash.toBase58()). - append(",pubKey:"+pubKey).append(",prvKey:"+prv).append(",contractPath:"+contractPath); - logger.info(sb.toString()); - ContractDeployExeUtil.instance.deploy(host,port,ledgerHash, blockchainKeyPair, contractBytes); - } - -} - - diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java deleted file mode 100644 index 950eb9bc..00000000 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java +++ /dev/null @@ -1,432 +0,0 @@ -package com.jd.blockchain; - -import com.github.javaparser.JavaParser; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.ImportDeclaration; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; -import com.jd.blockchain.contract.ContractType; -import org.apache.commons.io.FileUtils; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.jar.Attributes; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import static com.jd.blockchain.ContractCheckMojo.CONTRACT_VERIFY; -import static com.jd.blockchain.utils.decompiler.utils.DecompilerUtils.decompileJarFile; -import static com.jd.blockchain.utils.jar.ContractJarUtils.*; - -/** - * first step, we want to parse the source code by javaParse. But it's repeated and difficult to parse the source. - * This is a try of "from Initail to Abandoned". - * Since we are good at the class, why not? - * Now we change a way of thinking, first we pre-compile the source code, then parse the *.jar. - * - * by zhaogw - * date 2019-06-05 16:17 - */ -@Mojo(name = CONTRACT_VERIFY) -public class ContractVerifyMojo extends AbstractMojo { - - Logger LOG = LoggerFactory.getLogger(ContractVerifyMojo.class); - - @Parameter(defaultValue = "${project}", required = true, readonly = true) - private MavenProject project; - - /** - * jar's name; - */ - @Parameter - private String finalName; - - private static final String JAVA_SUFFIX = ".java"; - - private static final String PATH_DIRECT = - "src" + File.separator + - "main" + File.separator + - "java" + File.separator; - - private static final String CONFIG = "config.properties"; - - private static final String BLACK_PACKAGE_LIST = "black.package.list"; - - private static final String BLACK_CLASS_LIST = "black.class.list"; - - private static final String BLACK_NAME_LIST = "black.name.list"; - - @Override - public void execute() throws MojoExecutionException { - - try { - - File jarFile = copyAndManage(); - - // 首先校验MainClass - verifyMainClass(jarFile); - - Properties config = loadConfig(); - - List blackNameList = blackNameList(config); - - List blackPackageList = blackPackageList(config); - - Set blackClassSet = blackClassSet(config); - - LinkedList totalClassList = loadAllClass(jarFile); - // 该项目路径 - String projectDir = project.getBasedir().getPath(); - // 代码路径 - String codeBaseDir = projectDir + File.separator + PATH_DIRECT; - - if (!totalClassList.isEmpty()) { - - boolean isOK = true; - - for (String clazz : totalClassList) { - // 获取其包名 - String packageName = packageName(clazz); - - // 包的名字黑名单,不能打包该类进入Jar包中,或者合约不能命名这样的名字 - boolean isNameBlack = false; - for (ContractPackage blackName : blackNameList) { - isNameBlack = verifyPackage(packageName, blackName); - if (isNameBlack) { - break; - } - } - - // 假设是黑名单则打印日志 - if (isNameBlack) { - // 打印信息供检查 - LOG.error(String.format("Class[%s]'s Package-Name belong to BlackNameList !!!", clazz)); - isOK = false; - continue; - } - - // 获取该Class对应的Java文件 - File javaFile = new File(codeBaseDir + clazz + JAVA_SUFFIX); - - boolean isNeedDelete = false; - if (!javaFile.exists()) { - // 表明不是项目中的内容,需要通过反编译获取该文件 - String source = null; - try { - source = decompileJarFile(jarFile.getPath(), clazz, true, StandardCharsets.UTF_8.name()); - if (source == null || source.length() == 0) { - throw new IllegalStateException(); - } - } catch (Exception e) { - LOG.warn(String.format("Decompile Jar[%s]->Class[%s] Fail !!!", jarFile.getPath(), clazz)); - } - // 将source写入Java文件 - File sourceTempJavaFile = new File(tempPath(codeBaseDir, clazz)); - FileUtils.writeStringToFile(sourceTempJavaFile, source == null ? "" : source); - javaFile = sourceTempJavaFile; - isNeedDelete = true; - } - - // 解析文件中的内容 - CompilationUnit compilationUnit = JavaParser.parse(javaFile); - - MethodVisitor methodVisitor = new MethodVisitor(); - - compilationUnit.accept(methodVisitor, null); - - List imports = methodVisitor.importClasses; - - if (!imports.isEmpty()) { - for (String importClass : imports) { - if (importClass.endsWith("*")) { - // 导入的是包 - for (ContractPackage blackPackage : blackPackageList) { - String importPackageName = importClass.substring(0, importClass.length() - 2); - if (verifyPackage(importPackageName, blackPackage)) { - // 打印信息供检查 - LOG.error(String.format("Class[%s]'s import class [%s] belong to BlackPackageList !!!", clazz, importClass)); - isOK = false; - break; - } - } - } else { - // 导入的是具体的类,则判断类黑名单 + 包黑名单 - if (blackClassSet.contains(importClass)) { - // 包含导入类,该方式无法通过验证 - LOG.error(String.format("Class[%s]'s import class [%s] belong to BlackClassList !!!", clazz, importClass)); - isOK = false; - } else { - // 判断导入的该类与黑名单导入包的对应关系 - for (ContractPackage blackPackage : blackPackageList) { - if (verifyClass(importClass, blackPackage)) { - LOG.error(String.format("Class[%s]'s import class [%s] belong to BlackPackageList !!!", clazz, importClass)); - isOK = false; - break; - } - } - } - } - } - } - if (isNeedDelete) { - javaFile.delete(); - } - } - if (!isOK) { - throw new IllegalStateException("There are many Illegal information, please check !!!"); - } - } else { - throw new IllegalStateException("There is none class !!!"); - } - } catch (Exception e) { - LOG.error(e.getMessage()); - throw new MojoExecutionException(e.getMessage()); - } - } - - private void verifyMainClass(File jarFile) throws Exception { - // 加载main-class,开始校验类型 - URL jarURL = jarFile.toURI().toURL(); - ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL}, this.getClass().getClassLoader()); - Attributes m = new JarFile(jarFile).getManifest().getMainAttributes(); - String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS); - Class mainClass = classLoader.loadClass(contractMainClass); - ContractType.resolve(mainClass); - } - - private List blackNameList(Properties config) { - return blackList(config, BLACK_NAME_LIST); - } - - private Set blackClassSet(Properties config) { - Set blackClassSet = new HashSet<>(); - String attrProp = config.getProperty(BLACK_CLASS_LIST); - if (attrProp != null && attrProp.length() > 0) { - String[] attrPropArray = attrProp.split(","); - for (String attr : attrPropArray) { - blackClassSet.add(attr.trim()); - } - } - return blackClassSet; - } - - private List blackPackageList(Properties config) { - return blackList(config, BLACK_PACKAGE_LIST); - } - - private List blackList(Properties config, String attrName) { - List list = new ArrayList<>(); - String attrProp = config.getProperty(attrName); - if (attrProp != null || attrProp.length() > 0) { - String[] attrPropArray = attrProp.split(","); - for (String attr : attrPropArray) { - list.add(new ContractPackage(attr)); - } - } - return list; - } - - private boolean verifyPackage(String packageName, ContractPackage contractPackage) { - boolean verify = false; - if (packageName.equals(contractPackage.packageName)) { - // 完全相同 - verify = true; - } else if (packageName.startsWith(contractPackage.packageName) && - contractPackage.isTotal) { - // 以某个包开头 - verify = true; - } - return verify; - } - - private boolean verifyClass(String className, ContractPackage contractPackage) { - boolean verify = false; - - if (contractPackage.isTotal) { - // 表示该包下面的其他所有包都会受限制,此处需要判断起始 - if (className.startsWith(contractPackage.packageName)) { - verify = true; - } - } else { - // 表示该包必须完整匹配ClassName所在包 - // 获取ClassName所在包 - String packageName = packageNameByDot(className); - if (packageName.equals(contractPackage.packageName)) { - verify = true; - } - } - return verify; - } - - private String packageNameByDot(String className) { - String[] array = className.split("."); - if (Character.isLowerCase(array[array.length - 2].charAt(0))) { - // 如果是小写,表示非内部类 - // 获取完整包名 - return className.substring(0, className.lastIndexOf(".")); - } - // 表示为内部类,该包拼装组成 - StringBuilder buffer = new StringBuilder(); - for (String s : array) { - if (buffer.length() > 0) { - buffer.append("."); - } - if (Character.isUpperCase(s.charAt(0))) { - // 表明已经到具体类 - break; - } - buffer.append(s); - } - - if (buffer.length() == 0) { - throw new IllegalStateException(String.format("Import Class [%s] Illegal !!!", className)); - } - - return buffer.toString(); - } - - private String packageName(String clazz) { - int index = clazz.lastIndexOf("/"); - String packageName = clazz.substring(0, index); - return packageName.replaceAll("/", "."); - } - - private File copyAndManage() throws IOException { - // 首先将Jar包转换为指定的格式 - String srcJarPath = project.getBuild().getDirectory() + - File.separator + finalName + ".jar"; - - String dstJarPath = project.getBuild().getDirectory() + - File.separator + finalName + "-temp-" + System.currentTimeMillis() + ".jar"; - - File srcJar = new File(srcJarPath), dstJar = new File(dstJarPath); - - // 首先进行Copy处理 - copy(srcJar, dstJar); - - byte[] txtBytes = contractMF(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8); - - String finalJarPath = project.getBuild().getDirectory() + - File.separator + finalName + "-jdchain.jar"; - - File finalJar = new File(finalJarPath); - - copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null); - - // 删除临时文件 - FileUtils.forceDelete(dstJar); - - return finalJar; - } - - private Properties loadConfig() throws Exception { - - Properties properties = new Properties(); - - properties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG)); - - return properties; - } - - private LinkedList loadAllClass(File file) throws Exception { - JarFile jarFile = new JarFile(file); - LinkedList allClass = new LinkedList<>(); - Enumeration jarEntries = jarFile.entries(); - while (jarEntries.hasMoreElements()) { - JarEntry jarEntry = jarEntries.nextElement(); - String entryName = jarEntry.getName(); - if (entryName.endsWith(".class")) { - // 内部类,不需要处理 - if (!entryName.contains("$")) { - allClass.addLast(entryName.substring(0, entryName.length() - 6)); - } - } - } - return allClass; - } - - private String tempPath(String codeBaseDir, String clazz) { - // 获取最后的名称 - String[] classArray = clazz.split("/"); - String tempPath = codeBaseDir + classArray[classArray.length - 1] + "_" + - System.currentTimeMillis() + "_" + System.nanoTime() + JAVA_SUFFIX; - return tempPath; - } - - private static class MethodVisitor extends VoidVisitorAdapter { - - private List importClasses = new ArrayList<>(); - -// @Override -// public void visit(MethodDeclaration n, Void arg) { -// /* here you can access the attributes of the method. -// this method will be called for all methods in this -// CompilationUnit, including inner class methods */ -// super.visit(n, arg); -// } -// -// @Override -// public void visit(ClassOrInterfaceDeclaration n, Void arg) { -// super.visit(n, arg); -// } -// -// @Override -// public void visit(PackageDeclaration n, Void arg) { -// super.visit(n, arg); -// } - - @Override - public void visit(ImportDeclaration n, Void arg) { - importClasses.add(parseClass(n.toString())); - super.visit(n, arg); - } - - private String parseClass(String importInfo) { - String className = importInfo.substring(7, importInfo.length() - 2); - if (importInfo.startsWith("import static ")) { - // 获取静态方法的类信息 - className = importInfo.substring(14, importInfo.lastIndexOf(".")); - } - if (!className.contains(".")) { - throw new IllegalStateException(String.format("Import Class [%s] is Illegal !!", className)); - } - return className; - } - } - - private static class ContractPackage { - - private String packageName; - - private boolean isTotal = false; - - public ContractPackage() { - } - - public ContractPackage(String totalPackage) { - if (totalPackage.endsWith("*")) { - this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim(); - this.isTotal = true; - } else { - this.packageName = totalPackage; - } - } - - public String getPackageName() { - return packageName; - } - - public boolean isTotal() { - return isTotal; - } - } -} diff --git a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractVerifyMojo.java b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractVerifyMojo.java index 2cafd249..b0de7911 100644 --- a/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractVerifyMojo.java +++ b/source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/contract/maven/ContractVerifyMojo.java @@ -183,9 +183,12 @@ public class ContractVerifyMojo extends AbstractMojo { } } if (!isOK) { + // 需要将该Jar删除 + jarFile.delete(); throw new IllegalStateException("There are many Illegal information, please check !!!"); } } else { + jarFile.delete(); throw new IllegalStateException("There is none class !!!"); } } catch (Exception e) {