@@ -123,11 +123,11 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer | |||||
return; | return; | ||||
} | } | ||||
protected void initConfig(int id, String systemConfig, String hostsConfig) { | |||||
this.tomConfig = new TOMConfiguration(id, systemConfig, hostsConfig); | |||||
} | |||||
// protected void initConfig(int id, String systemConfig, String hostsConfig) { | |||||
// | |||||
// this.tomConfig = new TOMConfiguration(id, systemConfig, hostsConfig); | |||||
// | |||||
// } | |||||
protected void initConfig(int id, Properties systemsConfig, HostsConfig hostConfig) { | protected void initConfig(int id, Properties systemsConfig, HostsConfig hostConfig) { | ||||
this.tomConfig = new TOMConfiguration(id, systemsConfig, hostConfig); | this.tomConfig = new TOMConfiguration(id, systemsConfig, hostConfig); | ||||
@@ -309,6 +309,7 @@ public class BftsmartNodeServer extends DefaultRecoverable implements NodeServer | |||||
try { | try { | ||||
LOGGER.debug("Start replica...[ID=" + getId() + "]"); | LOGGER.debug("Start replica...[ID=" + getId() + "]"); | ||||
// 调整绑定Host | |||||
this.replica = new ServiceReplica(tomConfig, this, this); | this.replica = new ServiceReplica(tomConfig, this, this); | ||||
this.topology = new BftsmartTopology(replica.getReplicaContext().getCurrentView()); | this.topology = new BftsmartTopology(replica.getReplicaContext().getCurrentView()); | ||||
status = Status.RUNNING; | status = Status.RUNNING; | ||||
@@ -1,128 +1,128 @@ | |||||
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.NodeList; | |||||
import com.github.javaparser.ast.PackageDeclaration; | |||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; | |||||
import com.github.javaparser.ast.body.MethodDeclaration; | |||||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | |||||
import com.jd.blockchain.contract.ContractType; | |||||
import com.jd.blockchain.utils.IllegalDataException; | |||||
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.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.net.URL; | |||||
import java.net.URLClassLoader; | |||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import java.util.List; | |||||
import java.util.Properties; | |||||
import java.util.jar.Attributes; | |||||
import java.util.jar.JarFile; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* 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 = "checkImports") | |||||
public class CheckImportsMojo extends AbstractMojo { | |||||
Logger logger = LoggerFactory.getLogger(CheckImportsMojo.class); | |||||
@Parameter(defaultValue = "${project}", required = true, readonly = true) | |||||
private MavenProject project; | |||||
/** | |||||
* jar's name; | |||||
*/ | |||||
@Parameter | |||||
private String finalName; | |||||
@Override | |||||
public void execute() throws MojoFailureException { | |||||
List<Path> sources; | |||||
try { | |||||
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config.properties"); | |||||
Properties properties = new Properties(); | |||||
properties.load(inputStream); | |||||
String[] packageBlackList = properties.getProperty("blacklist").split(","); | |||||
Path baseDirPath = project.getBasedir().toPath(); | |||||
sources = Files.find(baseDirPath, Integer.MAX_VALUE, (file, attrs) -> (file.toString().endsWith(".java"))).collect(Collectors.toList()); | |||||
for (Path path : sources) { | |||||
CompilationUnit compilationUnit = JavaParser.parse(path); | |||||
compilationUnit.accept(new MethodVisitor(), null); | |||||
NodeList<ImportDeclaration> imports = compilationUnit.getImports(); | |||||
for (ImportDeclaration imp : imports) { | |||||
String importName = imp.getName().asString(); | |||||
for (String item : packageBlackList) { | |||||
if (importName.startsWith(item)) { | |||||
throw new MojoFailureException("在源码中不允许包含此引入包:" + importName); | |||||
} | |||||
} | |||||
} | |||||
//now we parse the jar; | |||||
String jarPath = project.getBuild().getDirectory()+ File.separator+finalName+".jar"; | |||||
File jarFile = new File(jarPath); | |||||
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); | |||||
try { | |||||
Class mainClass = classLoader.loadClass(contractMainClass); | |||||
ContractType.resolve(mainClass); | |||||
} catch (ClassNotFoundException e) { | |||||
throw new IllegalDataException(e.getMessage()); | |||||
} | |||||
} | |||||
} catch (IOException exception) { | |||||
logger.error(exception.getMessage()); | |||||
throw new MojoFailureException("IO ERROR"); | |||||
} catch (NullPointerException e) { | |||||
logger.error(e.getMessage()); | |||||
} | |||||
} | |||||
private class MethodVisitor extends VoidVisitorAdapter<Void> { | |||||
@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 */ | |||||
logger.info("method:"+n.getName()); | |||||
super.visit(n, arg); | |||||
} | |||||
@Override | |||||
public void visit(ClassOrInterfaceDeclaration n, Void arg) { | |||||
logger.info("class:"+n.getName()+" extends:"+n.getExtendedTypes()+" implements:"+n.getImplementedTypes()); | |||||
super.visit(n, arg); | |||||
} | |||||
@Override | |||||
public void visit(PackageDeclaration n, Void arg) { | |||||
logger.info("package:"+n.getName()); | |||||
super.visit(n, arg); | |||||
} | |||||
} | |||||
} | |||||
//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.NodeList; | |||||
//import com.github.javaparser.ast.PackageDeclaration; | |||||
//import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; | |||||
//import com.github.javaparser.ast.body.MethodDeclaration; | |||||
//import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | |||||
//import com.jd.blockchain.contract.ContractType; | |||||
//import com.jd.blockchain.utils.IllegalDataException; | |||||
//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.slf4j.Logger; | |||||
//import org.slf4j.LoggerFactory; | |||||
// | |||||
//import java.io.File; | |||||
//import java.io.IOException; | |||||
//import java.io.InputStream; | |||||
//import java.net.URL; | |||||
//import java.net.URLClassLoader; | |||||
//import java.nio.file.Files; | |||||
//import java.nio.file.Path; | |||||
//import java.util.List; | |||||
//import java.util.Properties; | |||||
//import java.util.jar.Attributes; | |||||
//import java.util.jar.JarFile; | |||||
//import java.util.stream.Collectors; | |||||
// | |||||
///** | |||||
// * 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 = "checkImports") | |||||
//public class CheckImportsMojo extends AbstractMojo { | |||||
// | |||||
// Logger logger = LoggerFactory.getLogger(CheckImportsMojo.class); | |||||
// | |||||
// @Parameter(defaultValue = "${project}", required = true, readonly = true) | |||||
// private MavenProject project; | |||||
// | |||||
// /** | |||||
// * jar's name; | |||||
// */ | |||||
// @Parameter | |||||
// private String finalName; | |||||
// | |||||
// @Override | |||||
// public void execute() throws MojoFailureException { | |||||
// List<Path> sources; | |||||
// try { | |||||
// InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config.properties"); | |||||
// Properties properties = new Properties(); | |||||
// properties.load(inputStream); | |||||
// String[] packageBlackList = properties.getProperty("blacklist").split(","); | |||||
// Path baseDirPath = project.getBasedir().toPath(); | |||||
// sources = Files.find(baseDirPath, Integer.MAX_VALUE, (file, attrs) -> (file.toString().endsWith(".java"))).collect(Collectors.toList()); | |||||
// for (Path path : sources) { | |||||
// CompilationUnit compilationUnit = JavaParser.parse(path); | |||||
// | |||||
// compilationUnit.accept(new MethodVisitor(), null); | |||||
// | |||||
// NodeList<ImportDeclaration> imports = compilationUnit.getImports(); | |||||
// for (ImportDeclaration imp : imports) { | |||||
// String importName = imp.getName().asString(); | |||||
// for (String item : packageBlackList) { | |||||
// if (importName.startsWith(item)) { | |||||
// throw new MojoFailureException("在源码中不允许包含此引入包:" + importName); | |||||
// } | |||||
// } | |||||
// } | |||||
// | |||||
// //now we parse the jar; | |||||
// String jarPath = project.getBuild().getDirectory()+ File.separator+finalName+".jar"; | |||||
// File jarFile = new File(jarPath); | |||||
// 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); | |||||
// try { | |||||
// Class mainClass = classLoader.loadClass(contractMainClass); | |||||
// ContractType.resolve(mainClass); | |||||
// } catch (ClassNotFoundException e) { | |||||
// throw new IllegalDataException(e.getMessage()); | |||||
// } | |||||
// } | |||||
// } catch (IOException exception) { | |||||
// logger.error(exception.getMessage()); | |||||
// throw new MojoFailureException("IO ERROR"); | |||||
// } catch (NullPointerException e) { | |||||
// logger.error(e.getMessage()); | |||||
// } | |||||
// } | |||||
// | |||||
// private class MethodVisitor extends VoidVisitorAdapter<Void> { | |||||
// @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 */ | |||||
// logger.info("method:"+n.getName()); | |||||
// super.visit(n, arg); | |||||
// } | |||||
// | |||||
// @Override | |||||
// public void visit(ClassOrInterfaceDeclaration n, Void arg) { | |||||
// logger.info("class:"+n.getName()+" extends:"+n.getExtendedTypes()+" implements:"+n.getImplementedTypes()); | |||||
// | |||||
// super.visit(n, arg); | |||||
// } | |||||
// | |||||
// @Override | |||||
// public void visit(PackageDeclaration n, Void arg) { | |||||
// logger.info("package:"+n.getName()); | |||||
// super.visit(n, arg); | |||||
// } | |||||
// | |||||
// } | |||||
//} |
@@ -1,6 +1,7 @@ | |||||
package com.jd.blockchain; | package com.jd.blockchain; | ||||
import com.jd.blockchain.utils.ConsoleUtils; | |||||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||||
import org.apache.commons.io.FileUtils; | |||||
import org.apache.maven.model.Model; | import org.apache.maven.model.Model; | ||||
import org.apache.maven.model.Plugin; | import org.apache.maven.model.Plugin; | ||||
import org.apache.maven.model.PluginExecution; | import org.apache.maven.model.PluginExecution; | ||||
@@ -12,7 +13,6 @@ import org.apache.maven.plugins.annotations.Parameter; | |||||
import org.apache.maven.project.MavenProject; | import org.apache.maven.project.MavenProject; | ||||
import org.apache.maven.shared.invoker.*; | import org.apache.maven.shared.invoker.*; | ||||
import org.codehaus.plexus.util.xml.Xpp3Dom; | import org.codehaus.plexus.util.xml.Xpp3Dom; | ||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
@@ -22,9 +22,25 @@ import java.util.Collections; | |||||
import java.util.List; | import java.util.List; | ||||
@Mojo(name = "contractCheck") | |||||
@Mojo(name = "Contract.Check") | |||||
public class ContractCheckMojo extends AbstractMojo { | public class ContractCheckMojo extends AbstractMojo { | ||||
Logger logger = LoggerFactory.getLogger(ContractCheckMojo.class); | |||||
Logger LOG = LoggerFactory.getLogger(ContractCheckMojo.class); | |||||
public static final String CONTRACT_VERIFY = "Contract.Verify"; | |||||
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 = "verify"; | |||||
private static final String GOALS_PACKAGE = "package"; | |||||
private static final String OUT_POM_XML = "OutPom.xml"; | |||||
@Parameter(defaultValue = "${project}", required = true, readonly = true) | @Parameter(defaultValue = "${project}", required = true, readonly = true) | ||||
private MavenProject project; | private MavenProject project; | ||||
@@ -58,27 +74,21 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
*/ | */ | ||||
@Override | @Override | ||||
public void execute() { | public void execute() { | ||||
this.compileFiles(); | |||||
compileFiles(); | |||||
} | } | ||||
private void compileFiles(){ | private void compileFiles(){ | ||||
// 获取当前项目pom.xml文件所在路径 | |||||
// URL targetClasses = this.getClass().getClassLoader().getResource(""); | |||||
// File file = new File(targetClasses.getPath()); | |||||
// String pomXmlPath = file.getParentFile().getParent() + File.separator + "pom.xml"; | |||||
try (FileInputStream fis = new FileInputStream(project.getFile())) { | |||||
FileInputStream fis = null; | |||||
try { | |||||
// fis = new FileInputStream(new File(pomXmlPath)); | |||||
fis = new FileInputStream(project.getFile()); | |||||
MavenXpp3Reader reader = new MavenXpp3Reader(); | MavenXpp3Reader reader = new MavenXpp3Reader(); | ||||
Model model = reader.read(fis); | Model model = reader.read(fis); | ||||
//delete this plugin(contractCheck) from destination pom.xml;then add the proper plugins; | //delete this plugin(contractCheck) from destination pom.xml;then add the proper plugins; | ||||
Plugin plugin = model.getBuild().getPluginsAsMap().get("com.jd.blockchain:contract-maven-plugin"); | |||||
Plugin plugin = model.getBuild().getPluginsAsMap() | |||||
.get(JDCHAIN_PACKAGE + ":" + CONTRACT_MAVEN_PLUGIN); | |||||
if(plugin == null){ | if(plugin == null){ | ||||
plugin = model.getBuild().getPluginsAsMap().get("org.apache.maven.plugins:contract-maven-plugin"); | |||||
plugin = model.getBuild().getPluginsAsMap() | |||||
.get(APACHE_MAVEN_PLUGINS + ":" + CONTRACT_MAVEN_PLUGIN); | |||||
} | } | ||||
if(plugin == null) { | if(plugin == null) { | ||||
@@ -86,26 +96,18 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
} | } | ||||
model.getBuild().removePlugin(plugin); | model.getBuild().removePlugin(plugin); | ||||
// model.getBuild().setPlugins(null); | |||||
// ConsoleUtils.info("----- 不携带Plugin -----"); | |||||
// print(model); | |||||
List<Plugin> plugins = new ArrayList<>(); | List<Plugin> plugins = new ArrayList<>(); | ||||
plugins.add(createAssembly()); | plugins.add(createAssembly()); | ||||
plugins.add(createCheckImports()); | |||||
plugins.add(createContractVerify()); | |||||
model.getBuild().setPlugins(plugins); | model.getBuild().setPlugins(plugins); | ||||
ConsoleUtils.info("----- add Plugin -----"); | |||||
handle(model); | handle(model); | ||||
} catch (FileNotFoundException e) { | |||||
e.printStackTrace(); | |||||
} catch (XmlPullParserException e) { | |||||
e.printStackTrace(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} catch (Exception e) { | |||||
LOG.error(e.getMessage()); | |||||
throw new IllegalStateException(e); | |||||
} | } | ||||
} | } | ||||
@@ -116,43 +118,35 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
try { | try { | ||||
request.setPomFile(file); | request.setPomFile(file); | ||||
request.setGoals( Collections.singletonList( "verify" ) ); | |||||
// request.setMavenOpts("-DmainClass="+mainClass); | |||||
request.setGoals(Collections.singletonList(GOALS_VERIFY)); | |||||
invoker.setMavenHome(new File(mvnHome)); | invoker.setMavenHome(new File(mvnHome)); | ||||
invoker.execute(request); | invoker.execute(request); | ||||
} catch (MavenInvocationException e) { | } catch (MavenInvocationException e) { | ||||
e.printStackTrace(); | |||||
LOG.error(e.getMessage()); | |||||
throw new IllegalStateException(e); | |||||
} | } | ||||
} | } | ||||
private Plugin createCheckImports() { | |||||
private Plugin createContractVerify() { | |||||
Plugin plugin = new Plugin(); | Plugin plugin = new Plugin(); | ||||
plugin.setGroupId("com.jd.blockchain"); | |||||
plugin.setArtifactId("contract-maven-plugin"); | |||||
plugin.setGroupId(JDCHAIN_PACKAGE); | |||||
plugin.setArtifactId(CONTRACT_MAVEN_PLUGIN); | |||||
plugin.setVersion(ledgerVersion); | plugin.setVersion(ledgerVersion); | ||||
Xpp3Dom finalNameNode = new Xpp3Dom("finalName"); | Xpp3Dom finalNameNode = new Xpp3Dom("finalName"); | ||||
finalNameNode.setValue(finalName); | finalNameNode.setValue(finalName); | ||||
Xpp3Dom configuration = new Xpp3Dom("configuration"); | Xpp3Dom configuration = new Xpp3Dom("configuration"); | ||||
configuration.addChild(finalNameNode); | configuration.addChild(finalNameNode); | ||||
plugin.setConfiguration(configuration); | |||||
PluginExecution pluginExecution = new PluginExecution(); | |||||
pluginExecution.setId("make-assembly"); | |||||
pluginExecution.setPhase("verify"); | |||||
List <String> goals = new ArrayList<>(); | |||||
goals.add("JDChain.Verify"); | |||||
pluginExecution.setGoals(goals); | |||||
List<PluginExecution> pluginExecutions = new ArrayList<>(); | |||||
pluginExecutions.add(pluginExecution); | |||||
plugin.setExecutions(pluginExecutions); | |||||
plugin.setConfiguration(configuration); | |||||
plugin.setExecutions(pluginExecution("make-assembly", GOALS_VERIFY, CONTRACT_VERIFY)); | |||||
return plugin; | return plugin; | ||||
} | } | ||||
private Plugin createAssembly() { | private Plugin createAssembly() { | ||||
Plugin plugin = new Plugin(); | Plugin plugin = new Plugin(); | ||||
plugin.setArtifactId("maven-assembly-plugin"); | |||||
plugin.setArtifactId(MAVEN_ASSEMBLY_PLUGIN); | |||||
Xpp3Dom configuration = new Xpp3Dom("configuration"); | Xpp3Dom configuration = new Xpp3Dom("configuration"); | ||||
@@ -180,21 +174,28 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
configuration.addChild(appendAssemblyId); | configuration.addChild(appendAssemblyId); | ||||
configuration.addChild(archive); | configuration.addChild(archive); | ||||
configuration.addChild(descriptorRefs); | configuration.addChild(descriptorRefs); | ||||
plugin.setConfiguration(configuration); | plugin.setConfiguration(configuration); | ||||
plugin.setExecutions(pluginExecution("make-assembly", GOALS_PACKAGE, "single")); | |||||
return plugin; | |||||
} | |||||
private List<PluginExecution> pluginExecution(String id, String phase, String goal) { | |||||
PluginExecution pluginExecution = new PluginExecution(); | PluginExecution pluginExecution = new PluginExecution(); | ||||
pluginExecution.setId("make-assembly"); | |||||
pluginExecution.setPhase("package"); | |||||
pluginExecution.setId(id); | |||||
pluginExecution.setPhase(phase); | |||||
List <String> goals = new ArrayList<>(); | List <String> goals = new ArrayList<>(); | ||||
goals.add("single"); | |||||
goals.add(goal); | |||||
pluginExecution.setGoals(goals); | pluginExecution.setGoals(goals); | ||||
List<PluginExecution> pluginExecutions = new ArrayList<>(); | List<PluginExecution> pluginExecutions = new ArrayList<>(); | ||||
pluginExecutions.add(pluginExecution); | pluginExecutions.add(pluginExecution); | ||||
plugin.setExecutions(pluginExecutions); | |||||
return plugin; | |||||
return pluginExecutions; | |||||
} | } | ||||
private void handle(Model model) throws IOException { | private void handle(Model model) throws IOException { | ||||
MavenXpp3Writer mavenXpp3Writer = new MavenXpp3Writer(); | MavenXpp3Writer mavenXpp3Writer = new MavenXpp3Writer(); | ||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ||||
@@ -203,20 +204,10 @@ public class ContractCheckMojo extends AbstractMojo { | |||||
byte[] buffer = outputStream.toByteArray(); | byte[] buffer = outputStream.toByteArray(); | ||||
//输出文件 | |||||
// File fileOutput = new File("fileOut.xml"); | |||||
// File fileOutput = File.createTempFile("fileOut",".xml"); | |||||
File fileOutput = new File(project.getBasedir().getPath(),"fileOut.xml"); | |||||
fileOutput.createNewFile(); | |||||
ConsoleUtils.info("fileOutput's path="+fileOutput.getPath()); | |||||
//创建文件输出流对象 | |||||
FileOutputStream fos = new FileOutputStream(fileOutput); | |||||
//将字节数组fileInput中的内容输出到文件fileOut.xml中; | |||||
ConsoleUtils.info(new String(buffer)); | |||||
fos.write(buffer); | |||||
fos.flush(); | |||||
fos.close(); | |||||
invokeCompile(fileOutput); | |||||
File outPom = new File(project.getBasedir().getPath(), OUT_POM_XML); | |||||
FileUtils.writeByteArrayToFile(outPom, buffer); | |||||
invokeCompile(outPom); | |||||
} | } | ||||
} | } |
@@ -20,6 +20,7 @@ import org.apache.maven.plugins.annotations.Parameter; | |||||
import org.apache.maven.project.MavenProject; | import org.apache.maven.project.MavenProject; | ||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import org.springframework.util.ResourceUtils; | |||||
import java.io.*; | import java.io.*; | ||||
import java.net.URL; | import java.net.URL; | ||||
@@ -27,15 +28,15 @@ import java.net.URLClassLoader; | |||||
import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||
import java.nio.file.Files; | import java.nio.file.Files; | ||||
import java.nio.file.Path; | import java.nio.file.Path; | ||||
import java.util.Enumeration; | |||||
import java.util.List; | |||||
import java.util.Properties; | |||||
import java.util.*; | |||||
import java.util.jar.Attributes; | import java.util.jar.Attributes; | ||||
import java.util.jar.JarEntry; | import java.util.jar.JarEntry; | ||||
import java.util.jar.JarFile; | import java.util.jar.JarFile; | ||||
import java.util.jar.JarOutputStream; | import java.util.jar.JarOutputStream; | ||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
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.*; | import static com.jd.blockchain.utils.jar.ContractJarUtils.*; | ||||
/** | /** | ||||
@@ -47,10 +48,10 @@ import static com.jd.blockchain.utils.jar.ContractJarUtils.*; | |||||
* by zhaogw | * by zhaogw | ||||
* date 2019-06-05 16:17 | * date 2019-06-05 16:17 | ||||
*/ | */ | ||||
@Mojo(name = "JDChain.Verify") | |||||
@Mojo(name = CONTRACT_VERIFY) | |||||
public class ContractVerifyMojo extends AbstractMojo { | public class ContractVerifyMojo extends AbstractMojo { | ||||
Logger logger = LoggerFactory.getLogger(ContractVerifyMojo.class); | |||||
Logger LOG = LoggerFactory.getLogger(ContractVerifyMojo.class); | |||||
@Parameter(defaultValue = "${project}", required = true, readonly = true) | @Parameter(defaultValue = "${project}", required = true, readonly = true) | ||||
private MavenProject project; | private MavenProject project; | ||||
@@ -61,53 +62,249 @@ public class ContractVerifyMojo extends AbstractMojo { | |||||
@Parameter | @Parameter | ||||
private String finalName; | 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 | @Override | ||||
public void execute() throws MojoFailureException { | public void execute() throws MojoFailureException { | ||||
List<Path> sources; | |||||
try { | try { | ||||
File jarFile = copyAndManage(); | File jarFile = copyAndManage(); | ||||
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config.properties"); | |||||
Properties properties = new Properties(); | |||||
properties.load(inputStream); | |||||
String[] packageBlackList = properties.getProperty("blacklist").split(","); | |||||
Path baseDirPath = project.getBasedir().toPath(); | |||||
sources = Files.find(baseDirPath, Integer.MAX_VALUE, (file, attrs) -> (file.toString().endsWith(".java"))).collect(Collectors.toList()); | |||||
for (Path path : sources) { | |||||
CompilationUnit compilationUnit = JavaParser.parse(path); | |||||
compilationUnit.accept(new MethodVisitor(), null); | |||||
NodeList<ImportDeclaration> imports = compilationUnit.getImports(); | |||||
for (ImportDeclaration imp : imports) { | |||||
String importName = imp.getName().asString(); | |||||
for (String item : packageBlackList) { | |||||
if (importName.startsWith(item)) { | |||||
throw new MojoFailureException("在源码中不允许包含此引入包:" + importName); | |||||
Properties config = loadConfig(); | |||||
List<ContractPackage> blackNameList = blackNameList(config); | |||||
List<ContractPackage> blackPackageList = blackPackageList(config); | |||||
Set<String> blackClassSet = blackClassSet(config); | |||||
LinkedList<String> 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<String> 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 !!!"); | |||||
} | } | ||||
//now we parse the jar; | |||||
// 加载main-class,开始校验类型 | |||||
URL jarURL = jarFile.toURI().toURL(); | URL jarURL = jarFile.toURI().toURL(); | ||||
ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL},this.getClass().getClassLoader()); | |||||
ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL}, this.getClass().getClassLoader()); | |||||
Attributes m = new JarFile(jarFile).getManifest().getMainAttributes(); | Attributes m = new JarFile(jarFile).getManifest().getMainAttributes(); | ||||
String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS); | String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS); | ||||
try { | |||||
Class mainClass = classLoader.loadClass(contractMainClass); | |||||
ContractType.resolve(mainClass); | |||||
} catch (ClassNotFoundException e) { | |||||
throw new IllegalDataException(e.getMessage()); | |||||
} | |||||
Class mainClass = classLoader.loadClass(contractMainClass); | |||||
ContractType.resolve(mainClass); | |||||
} else { | |||||
throw new IllegalStateException("There is none class !!!"); | |||||
} | |||||
} catch (Exception e) { | |||||
LOG.error(e.getMessage()); | |||||
throw new MojoFailureException(e.getMessage()); | |||||
} | |||||
} | |||||
private List<ContractPackage> blackNameList(Properties config) { | |||||
return blackList(config, BLACK_NAME_LIST); | |||||
} | |||||
private Set<String> blackClassSet(Properties config) { | |||||
Set<String> 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<ContractPackage> blackPackageList(Properties config) { | |||||
return blackList(config, BLACK_PACKAGE_LIST); | |||||
} | |||||
private List<ContractPackage> blackList(Properties config, String attrName) { | |||||
List<ContractPackage> 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; | |||||
} | } | ||||
} catch (IOException exception) { | |||||
logger.error(exception.getMessage()); | |||||
throw new MojoFailureException("IO ERROR"); | |||||
} catch (NullPointerException e) { | |||||
logger.error(e.getMessage()); | |||||
} | } | ||||
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 { | private File copyAndManage() throws IOException { | ||||
@@ -138,30 +335,104 @@ public class ContractVerifyMojo extends AbstractMojo { | |||||
return finalJar; | return finalJar; | ||||
} | } | ||||
private Properties loadConfig() throws Exception { | |||||
Properties properties = new Properties(); | |||||
properties.load(this.getClass().getClassLoader().getResourceAsStream(CONFIG)); | |||||
return properties; | |||||
} | |||||
private LinkedList<String> loadAllClass(File file) throws Exception { | |||||
JarFile jarFile = new JarFile(file); | |||||
LinkedList<String> allClass = new LinkedList<>(); | |||||
Enumeration<JarEntry> 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<Void> { | |||||
private List<String> 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); | |||||
// } | |||||
private class MethodVisitor extends VoidVisitorAdapter<Void> { | |||||
@Override | @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 */ | |||||
logger.info("method:"+n.getName()); | |||||
public void visit(ImportDeclaration n, Void arg) { | |||||
importClasses.add(parseClass(n.toString())); | |||||
super.visit(n, arg); | super.visit(n, arg); | ||||
} | } | ||||
@Override | |||||
public void visit(ClassOrInterfaceDeclaration n, Void arg) { | |||||
logger.info("class:"+n.getName()+" extends:"+n.getExtendedTypes()+" implements:"+n.getImplementedTypes()); | |||||
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; | |||||
} | |||||
} | |||||
super.visit(n, arg); | |||||
private static class ContractPackage { | |||||
private String packageName; | |||||
private boolean isTotal = false; | |||||
public ContractPackage() { | |||||
} | } | ||||
@Override | |||||
public void visit(PackageDeclaration n, Void arg) { | |||||
logger.info("package:"+n.getName()); | |||||
super.visit(n, arg); | |||||
public ContractPackage(String totalPackage) { | |||||
if (totalPackage.endsWith("*")) { | |||||
this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim(); | |||||
this.isTotal = true; | |||||
} | |||||
this.packageName = totalPackage; | |||||
} | } | ||||
public String getPackageName() { | |||||
return packageName; | |||||
} | |||||
public boolean isTotal() { | |||||
return isTotal; | |||||
} | |||||
} | } | ||||
} | } |
@@ -1 +1,8 @@ | |||||
blacklist=java.io,java.net,java.util.Random | |||||
#black.name.list:打包为合约Jar后,每个Class文件不允许使用的名称,默认不允许使用com.jd.blockchain.* | |||||
black.name.list=com.jd.blockchain.* | |||||
#black.package.list:打包为合约中的每个Class都不允许使用的包列表,某个包下面的所有包通过.*表示 | |||||
black.package.list=java.io.*, java.net.*, org.apache.commons.io.* | |||||
#black.class.list:打包为合约中的每个Class都不允许使用的类列表 | |||||
black.class.list=java.util.Random, com.jd.blockchain.ledger.BlockchainKeyGenerator |
@@ -1,28 +0,0 @@ | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.CheckImportsMojo; | |||||
import org.apache.maven.plugin.testing.AbstractMojoTestCase; | |||||
import org.junit.Test; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.io.File; | |||||
/** | |||||
* @Author zhaogw | |||||
* @Date 2019/3/1 21:27 | |||||
*/ | |||||
public class CheckImportsMojoTest extends AbstractMojoTestCase { | |||||
Logger logger = LoggerFactory.getLogger(CheckImportsMojoTest.class); | |||||
@Test | |||||
public void test1() throws Exception { | |||||
File pom = getTestFile( "src/test/resources/project-to-test/pom.xml" ); | |||||
assertNotNull( pom ); | |||||
assertTrue( pom.exists() ); | |||||
CheckImportsMojo myMojo = (CheckImportsMojo) lookupMojo( "checkImports", pom ); | |||||
assertNotNull( myMojo ); | |||||
myMojo.execute(); | |||||
} | |||||
} |
@@ -0,0 +1,50 @@ | |||||
package com.jd.blockchain.ledger; | |||||
import org.apache.maven.model.Build; | |||||
import org.apache.maven.project.MavenProject; | |||||
import org.junit.Test; | |||||
import org.springframework.core.io.ClassPathResource; | |||||
import java.io.File; | |||||
public class ContractTestBase { | |||||
public static MavenProject mavenProjectInit() { | |||||
MavenProject mavenProject = new MavenProject(); | |||||
mavenProject.setBuild(buildInit()); | |||||
mavenProject.setFile(file()); | |||||
return mavenProject; | |||||
} | |||||
public static File file() { | |||||
String resDir = resourceDir(); | |||||
File file = new File(resDir); | |||||
String path = file.getParentFile().getParentFile().getPath(); | |||||
return new File(path + File.separator + "src"); | |||||
} | |||||
public static Build buildInit() { | |||||
Build build = new Build(); | |||||
build.setDirectory(resourceDir()); | |||||
return build; | |||||
} | |||||
public static String resourceDir() { | |||||
try { | |||||
ClassPathResource classPathResource = new ClassPathResource("complex.jar"); | |||||
return classPathResource.getFile().getParentFile().getPath(); | |||||
} catch (Exception e) { | |||||
throw new IllegalStateException(e); | |||||
} | |||||
} | |||||
@Test | |||||
public void testResourceDir() { | |||||
System.out.println(resourceDir()); | |||||
} | |||||
@Test | |||||
public void testFile() { | |||||
System.out.println(file().getPath()); | |||||
} | |||||
} |
@@ -1,6 +1,5 @@ | |||||
package com.jd.blockchain.ledger; | package com.jd.blockchain.ledger; | ||||
import com.jd.blockchain.CheckImportsMojo; | |||||
import com.jd.blockchain.ContractVerifyMojo; | import com.jd.blockchain.ContractVerifyMojo; | ||||
import org.apache.maven.plugin.testing.AbstractMojoTestCase; | import org.apache.maven.plugin.testing.AbstractMojoTestCase; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
@@ -22,7 +21,7 @@ public class ContractVerifyMojoTest extends AbstractMojoTestCase { | |||||
assertNotNull( pom ); | assertNotNull( pom ); | ||||
assertTrue( pom.exists() ); | assertTrue( pom.exists() ); | ||||
ContractVerifyMojo myMojo = (ContractVerifyMojo) lookupMojo( "JDChain.Verify", pom ); | |||||
ContractVerifyMojo myMojo = (ContractVerifyMojo) lookupMojo( "Contract.Verify", pom ); | |||||
assertNotNull( myMojo ); | assertNotNull( myMojo ); | ||||
myMojo.execute(); | myMojo.execute(); | ||||
} | } | ||||
@@ -0,0 +1,47 @@ | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.ContractVerifyMojo; | |||||
import org.apache.maven.project.MavenProject; | |||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
import java.lang.reflect.Field; | |||||
import static com.jd.blockchain.ledger.ContractTestBase.mavenProjectInit; | |||||
public class ContractVerifyTest { | |||||
private MavenProject project; | |||||
private String finalName; | |||||
@Before | |||||
public void testInit() { | |||||
project = mavenProjectInit(); | |||||
finalName = "complex.jar"; | |||||
} | |||||
@Test | |||||
public void test() throws Exception { | |||||
ContractVerifyMojo contractVerifyMojo = contractVerifyMojoConf(); | |||||
contractVerifyMojo.execute(); | |||||
} | |||||
private ContractVerifyMojo contractVerifyMojoConf() throws Exception { | |||||
ContractVerifyMojo contractVerifyMojo = new ContractVerifyMojo(); | |||||
// 为不影响其内部结构,通过反射进行私有变量赋值 | |||||
Class<?> clazz = contractVerifyMojo.getClass(); | |||||
Field projectField = clazz.getDeclaredField("project"); | |||||
Field finalNameField = clazz.getDeclaredField("finalName"); | |||||
// 更新权限 | |||||
projectField.setAccessible(true); | |||||
finalNameField.setAccessible(true); | |||||
// 设置具体值 | |||||
projectField.set(contractVerifyMojo, project); | |||||
finalNameField.set(contractVerifyMojo, finalName); | |||||
return contractVerifyMojo; | |||||
} | |||||
} |
@@ -78,22 +78,7 @@ | |||||
<version>${commons-io.version}</version> | <version>${commons-io.version}</version> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-core</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-expressions</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-reflection</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-compilertools</artifactId> | |||||
</dependency> | |||||
<dependency> | <dependency> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
@@ -3,11 +3,8 @@ package com.jd.blockchain.gateway.service; | |||||
import com.jd.blockchain.consensus.ConsensusProvider; | import com.jd.blockchain.consensus.ConsensusProvider; | ||||
import com.jd.blockchain.consensus.ConsensusProviders; | import com.jd.blockchain.consensus.ConsensusProviders; | ||||
import com.jd.blockchain.consensus.ConsensusSettings; | import com.jd.blockchain.consensus.ConsensusSettings; | ||||
import com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider; | |||||
import com.jd.blockchain.consensus.mq.MsgQueueConsensusProvider; | |||||
import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
import com.jd.blockchain.gateway.PeerService; | import com.jd.blockchain.gateway.PeerService; | ||||
import com.jd.blockchain.gateway.decompiler.utils.DecompilerUtils; | |||||
import com.jd.blockchain.ledger.ContractInfo; | import com.jd.blockchain.ledger.ContractInfo; | ||||
import com.jd.blockchain.ledger.LedgerMetadata; | import com.jd.blockchain.ledger.LedgerMetadata; | ||||
import com.jd.blockchain.ledger.ParticipantNode; | import com.jd.blockchain.ledger.ParticipantNode; | ||||
@@ -15,6 +12,7 @@ import com.jd.blockchain.sdk.ContractSettings; | |||||
import com.jd.blockchain.sdk.LedgerInitSettings; | import com.jd.blockchain.sdk.LedgerInitSettings; | ||||
import com.jd.blockchain.utils.QueryUtil; | import com.jd.blockchain.utils.QueryUtil; | ||||
import com.jd.blockchain.utils.codec.HexUtils; | import com.jd.blockchain.utils.codec.HexUtils; | ||||
import com.jd.blockchain.utils.decompiler.utils.DecompilerUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
@@ -43,6 +43,23 @@ | |||||
<artifactId>spring-beans</artifactId> | <artifactId>spring-beans</artifactId> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-core</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-expressions</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-reflection</artifactId> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.bitbucket.mstrobel</groupId> | |||||
<artifactId>procyon-compilertools</artifactId> | |||||
</dependency> | |||||
<!--<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> | <!--<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> | ||||
</dependency> --> | </dependency> --> | ||||
@@ -1,4 +1,4 @@ | |||||
package com.jd.blockchain.gateway.decompiler.loads; | |||||
package com.jd.blockchain.utils.decompiler.loads; | |||||
import com.strobel.assembler.ir.ConstantPool; | import com.strobel.assembler.ir.ConstantPool; | ||||
import com.strobel.assembler.metadata.Buffer; | import com.strobel.assembler.metadata.Buffer; |
@@ -1,6 +1,6 @@ | |||||
package com.jd.blockchain.gateway.decompiler.utils; | |||||
package com.jd.blockchain.utils.decompiler.utils; | |||||
import com.jd.blockchain.gateway.decompiler.loads.BytesTypeLoader; | |||||
import com.jd.blockchain.utils.decompiler.loads.BytesTypeLoader; | |||||
import com.strobel.assembler.metadata.JarTypeLoader; | import com.strobel.assembler.metadata.JarTypeLoader; | ||||
import com.strobel.decompiler.Decompiler; | import com.strobel.decompiler.Decompiler; | ||||
import com.strobel.decompiler.DecompilerSettings; | import com.strobel.decompiler.DecompilerSettings; |
@@ -15,7 +15,7 @@ import java.util.jar.JarOutputStream; | |||||
public class ContractJarUtils { | public class ContractJarUtils { | ||||
private static final String JDCHAIN_META = "META-INF/JDCHAIN.TXT"; | |||||
private static final String JDCHAIN_META = "META-INF/CONTRACT.MF"; | |||||
private static final int JDCHAIN_HASH_LENGTH = 69; | private static final int JDCHAIN_HASH_LENGTH = 69; | ||||