[ERROR]TransactionBuilder. – The transaction currently built is missing an attachment for :classnet/corda/core/contracts/CommandData

huangapple 未分类评论46阅读模式
英文:

[ERROR]TransactionBuilder. - The transaction currently built is missing an attachment for :classnet/corda/core/contracts/CommandData

问题

当尝试运行 Corda 测试时,给定的测试案例出现以下错误。我正在使用 JDK 1.8 和 Intellij IDEA。

MetalContract

package com.template.contracts;

import com.template.states.MetalState;
import net.corda.core.contracts.Command;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.Party;
import net.corda.core.transactions.LedgerTransaction;
import org.jetbrains.annotations.NotNull;

import java.security.PublicKey;
import java.util.List;

public class MetalContract implements Contract {
    public static final String CID = "com.template.contracts.MetalContract";

    @Override
    public void verify(@NotNull LedgerTransaction tx) throws IllegalArgumentException {
        // Contract verification logic
        // ...
    }

    public static class Issue implements CommandData {}
    public static class Transfer implements CommandData {}
}
package com.template.contracts;

import com.template.states.MetalState;
import com.template.contracts.MetalContract;
import net.corda.core.contracts.Contract;
import net.corda.core.identity.CordaX500Name;
import net.corda.testing.core.TestIdentity;
import net.corda.testing.node.MockServices;
import org.junit.Test;

import static net.corda.testing.node.NodeTestUtils.transaction;

public class ContractTests {
    private final TestIdentity Mint = new TestIdentity(new CordaX500Name("mint", "", "GB"));
    private final TestIdentity TraderA = new TestIdentity(new CordaX500Name("traderA", "", "GB"));
    private final TestIdentity TraderB = new TestIdentity(new CordaX500Name("traderB", "", "GB"));

    private final MockServices ledgerServices = new MockServices();

    private MetalState metalState = new MetalState("Gold", 10, Mint.getParty(), TraderA.getParty());
    private MetalState metalStateInput = new MetalState("Gold", 10, Mint.getParty(), TraderA.getParty());
    private MetalState metalStateOutput = new MetalState("Gold", 10, Mint.getParty(), TraderB.getParty());

    @Test
    public void metalContractImplementsContract() {
        assert (new MetalContract() instanceof Contract);
    }

    @Test
    public void MetalContractRequiresTheIssuerToBeARequiredSignerInTheTransaction() {
        // Test logic
        // ...
    }
}

错误信息如下:

[ERROR] 12:35:10,086 [main] transactions.TransactionBuilder. - The transaction currently built is missing an attachment for class: net/corda/core/contracts/CommandData.
Attempted to find a suitable attachment but could not find any in the storage.
Please contact the developer of the CorDapp for further instructions.

java.lang.NoClassDefFoundError: net/corda/core/contracts/CommandData
    ...
Caused by: java.lang.ClassNotFoundException: net.corda.core.contracts.CommandData
    ...

build.gradle(Contract 模块)

apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'

cordapp {
    targetPlatformVersion corda_platform_version
    minimumPlatformVersion corda_platform_version
    contract {
        name "Template CorDapp"
        vendor "Corda Open Source"
        licence "Apache License, Version 2.0"
        versionId 1
    }
}

sourceSets {
    main{
        java {
            srcDir 'src/main/java'
            java.outputDir = file('bin/main')
        }
    }
    test{
        java{
            srcDir 'src/test/java'
            java.outputDir = file('bin/test')
        }
    }
}

dependencies {
    cordaCompile "$corda_release_group:corda-core:$corda_release_version"
    cordaRuntime "$corda_release_group:corda:$corda_release_version"
    testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
}

(翻译结果仅包含代码部分,不包含额外内容。)

英文:

When trying to run test for CORDA the given Test case getting the following error. I am using JDK 1.8. Intellij IDEA.When trying to run test for CORDA the given Test case getting the following error. I am using JDK 1.8. Intellij IDEA.When trying to run test for CORDA the given Test case getting the following error. I am using JDK 1.8. Intellij IDEA.

MetalContract


import com.template.states.MetalState;
import net.corda.core.contracts.Command;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.Party;
import net.corda.core.transactions.LedgerTransaction;
import org.jetbrains.annotations.NotNull;

import java.security.PublicKey;
import java.util.List;

// ************
// * Contract *
// ************
public class MetalContract implements Contract {
    // This is used to identify our contract when building a transaction.
    public static final String CID = "com.template.contracts.MetalContract";

    // A transaction is valid if the verify() function of the contract of all the transaction's input and output states
    // does not throw an exception.
    @Override
    public void verify(@NotNull LedgerTransaction tx) throws IllegalArgumentException{

        if (tx.getCommands().size() != 1)
            throw new IllegalArgumentException("Transaction must have one Command.");

        Command command = tx.getCommand(0);
        CommandData commandType = command.getValue();

        List<PublicKey> requiredSigners = command.getSigners();


        // -------------------------------- Issue Command Contract Rules ------------------------------------------


     if (commandType instanceof Issue) {
         // Issue transaction logic

         // Shape Rules

         if (tx.getInputs().size() != 0)
             throw new IllegalArgumentException("Issue cannot have inputs");

         if (tx.getOutputs().size() != 1)
             throw new IllegalArgumentException("Issue can only have one output");

         // Content Rules

         ContractState outputState = tx.getOutput(0);

         if (!(outputState instanceof MetalState))
             throw new IllegalArgumentException("Output must be a metal State");

         MetalState metalState = (MetalState) outputState;

         if (!metalState.getMetalName().equals("Gold")&&!metalState.getMetalName().equals("Silver")){
             throw new IllegalArgumentException("Metal is not Gold or Silver");
         }

         // Signer Rules

         Party issuer = metalState.getIssuer();
         PublicKey issuersKey = issuer.getOwningKey();

         if (!(requiredSigners.contains(issuersKey)))
             throw new IllegalArgumentException("Issuer has to sign the issuance");

     }


        // -------------------------------- Transfer Command Contract Rules ------------------------------------------


       else if (commandType instanceof Transfer) {
            // Transfer transaction logic

            // Shape Rules

            if (tx.getInputs().size() != 1)
                throw new IllegalArgumentException("Transfer needs to have one input");

            if (tx.getOutputs().size() != 1)
                throw new IllegalArgumentException("Transfer can only have one output");

            // Content Rules

            ContractState inputState = tx.getInput(0);
            ContractState outputState = tx.getOutput(0);


            if (!(outputState instanceof MetalState))
                throw new IllegalArgumentException("Output must be a metal State");

            MetalState metalState = (MetalState) inputState;

            if (!metalState.getMetalName().equals("Gold")&&!metalState.getMetalName().equals("Silver")){
                throw new IllegalArgumentException("Metal is not Gold or Silver");
            }

            // Signer Rules

            Party owner = metalState.getOwner();
            PublicKey ownersKey = owner.getOwningKey();

            if (!(requiredSigners.contains(ownersKey)))
                throw new IllegalArgumentException("Owner has to sign the transfer");



        }

       else  throw new IllegalArgumentException("Unrecognised command.");




    }




    // Used to indicate the transaction's intent.
    public static class Issue implements CommandData {}
    public static class Transfer implements CommandData {}
}
package com.template.contracts;

import com.template.states.MetalState;
import com.template.contracts.MetalContract;
import net.corda.core.contracts.Contract;
import net.corda.core.identity.CordaX500Name;
import net.corda.testing.contracts.DummyState;
import net.corda.testing.core.DummyCommandData;
import net.corda.testing.core.TestIdentity;
import net.corda.testing.node.MockServices;
import org.junit.Test;

import static net.corda.testing.node.NodeTestUtils.transaction;

public class ContractTests {

    private final TestIdentity Mint = new TestIdentity (new CordaX500Name ("mint", "", "GB"));
    private final TestIdentity TraderA = new TestIdentity (new CordaX500Name ("traderA", "", "GB"));
    private final TestIdentity TraderB = new TestIdentity (new CordaX500Name ("traderB", "", "GB"));


    private final MockServices ledgerServices = new MockServices();

    private MetalState metalState = new MetalState("Gold", 10, Mint.getParty(), TraderA.getParty());
    private MetalState metalStateInput = new MetalState("Gold", 10, Mint.getParty(), TraderA.getParty());
    private MetalState metalStateOutput = new MetalState("Gold", 10, Mint.getParty(), TraderB.getParty());

    @Test
    public void metalContractImplementsContract() {
        assert (new MetalContract() instanceof Contract);
    }
    @Test
    public void MetalContractRequiresTheIssuerToBeARequiredSignerInTheTransaction() {

        transaction(ledgerServices, tx -> {
            // Issuer is not a required signer, will fail
            tx.output(MetalContract.CID, metalState);
            tx.command(TraderA.getPublicKey(), new MetalContract.Issue());
            tx.fails();
            return null;
        });

        transaction(ledgerServices, tx -> {
            // Issuer is a required, will verify
            tx.output(MetalContract.CID, metalState);
            tx.command(Mint.getPublicKey(), new MetalContract.Issue());
            tx.verifies();
            return null;
        });
    }
    }

The Error is as following .

[ERROR] 12:35:10,086 [main] transactions.TransactionBuilder. - The transaction currently built is missing an attachment for class: net/corda/core/contracts/CommandData.
                        Attempted to find a suitable attachment but could not find any in the storage.
                        Please contact the developer of the CorDapp for further instructions.

java.lang.NoClassDefFoundError: net/corda/core/contracts/CommandData

	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:405)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at net.corda.serialization.internal.model.TypeIdentifier$Unparameterised.getLocalType(TypeIdentifier.kt:151)
	at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1$1.apply(TypeLoader.kt:38)
	at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1$1.apply(TypeLoader.kt:25)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
	at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1.invoke(TypeLoader.kt:38)
	at net.corda.serialization.internal.model.ClassCarpentingTypeLoader$load$noCarpentryRequired$1.invoke(TypeLoader.kt:25)
	at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:149)
	at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:109)
	at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:133)
	at kotlin.collections.MapsKt__MapsKt.putAll(Maps.kt:339)
	at kotlin.collections.MapsKt__MapsKt.toMap(Maps.kt:504)
	at kotlin.collections.MapsKt__MapsKt.toMap(Maps.kt:498)
	at net.corda.serialization.internal.model.ClassCarpentingTypeLoader.load(TypeLoader.kt:45)
	at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory.reflect(RemoteSerializerFactory.kt:129)
	at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory.access$reflect(RemoteSerializerFactory.kt:47)
	at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory$get$1.invoke(RemoteSerializerFactory.kt:71)
	at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory$get$1.invoke(RemoteSerializerFactory.kt:47)
	at net.corda.serialization.internal.amqp.DefaultDescriptorBasedSerializerRegistry.getOrBuild(DescriptorBasedSerializerRegistry.kt:28)
	at net.corda.serialization.internal.amqp.DefaultRemoteSerializerFactory.get(RemoteSerializerFactory.kt:66)
	at net.corda.serialization.internal.amqp.ComposedSerializerFactory.get(SerializerFactory.kt)
	at net.corda.serialization.internal.amqp.DeserializationInput.readObject(DeserializationInput.kt:172)
	at net.corda.serialization.internal.amqp.DeserializationInput.readObjectOrNull(DeserializationInput.kt:147)
	at net.corda.serialization.internal.amqp.DeserializationInput$deserialize$1.invoke(DeserializationInput.kt:124)
	at net.corda.serialization.internal.amqp.DeserializationInput.des(DeserializationInput.kt:99)
	at net.corda.serialization.internal.amqp.DeserializationInput.deserialize(DeserializationInput.kt:119)
	at net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme.deserialize(AMQPSerializationScheme.kt:145)
	at net.corda.serialization.internal.SerializationFactoryImpl$deserialize$1$1.invoke(SerializationScheme.kt:105)
	at net.corda.core.serialization.SerializationFactory.withCurrentContext(SerializationAPI.kt:71)
	at net.corda.serialization.internal.SerializationFactoryImpl$deserialize$1.invoke(SerializationScheme.kt:105)
	at net.corda.serialization.internal.SerializationFactoryImpl$deserialize$1.invoke(SerializationScheme.kt:73)
	at net.corda.core.serialization.SerializationFactory.asCurrent(SerializationAPI.kt:85)
	at net.corda.serialization.internal.SerializationFactoryImpl.deserialize(SerializationScheme.kt:105)
	at net.corda.core.internal.TransactionUtilsKt$deserialiseComponentGroup$1.invoke(TransactionUtils.kt:78)
	at net.corda.core.internal.TransactionUtilsKt$deserialiseComponentGroup$1.invoke(TransactionUtils.kt)
	at net.corda.core.internal.LazyMappedList.get(InternalUtils.kt:567)
	at net.corda.core.internal.LazyMappedList.get(InternalUtils.kt:567)
	at java.util.AbstractList$Itr.next(AbstractList.java:358)
	at net.corda.core.transactions.LedgerTransaction.createLtxForVerification(LedgerTransaction.kt:668)
	at net.corda.core.transactions.LedgerTransaction.access$createLtxForVerification(LedgerTransaction.kt:44)
	at net.corda.core.transactions.LedgerTransaction$internalPrepareVerify$1.invoke(LedgerTransaction.kt:154)
	at net.corda.core.transactions.LedgerTransaction$internalPrepareVerify$1.invoke(LedgerTransaction.kt:44)
	at net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder$withAttachmentsClassloaderContext$1.invoke(AttachmentsClassLoader.kt:345)
	at net.corda.core.serialization.SerializationFactory.withCurrentContext(SerializationAPI.kt:71)
	at net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext(AttachmentsClassLoader.kt:344)
	at net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder.withAttachmentsClassloaderContext$default(AttachmentsClassLoader.kt:319)
	at net.corda.core.transactions.LedgerTransaction.internalPrepareVerify$core(LedgerTransaction.kt:146)
	at net.corda.core.transactions.LedgerTransaction.verify(LedgerTransaction.kt:136)
	at net.corda.core.transactions.TransactionBuilder.addMissingDependency(TransactionBuilder.kt:185)
	at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core(TransactionBuilder.kt:165)
	at net.corda.core.transactions.TransactionBuilder.toWireTransactionWithContext$core$default(TransactionBuilder.kt:133)
	at net.corda.core.transactions.TransactionBuilder.toWireTransaction(TransactionBuilder.kt:130)
	at net.corda.testing.dsl.TestTransactionDSLInterpreter.toWireTransaction$test_utils(TestDSL.kt:131)
	at net.corda.testing.dsl.TestTransactionDSLInterpreter.verifies(TestDSL.kt:175)
	at net.corda.testing.dsl.Verifies$DefaultImpls.failsWith(LedgerDSLInterpreter.kt:45)
	at net.corda.testing.dsl.TransactionDSLInterpreter$DefaultImpls.failsWith(TransactionDSLInterpreter.kt)
	at net.corda.testing.dsl.TestTransactionDSLInterpreter.failsWith(TestDSL.kt:74)
	at net.corda.testing.dsl.Verifies$DefaultImpls.fails(LedgerDSLInterpreter.kt:75)
	at net.corda.testing.dsl.TransactionDSLInterpreter$DefaultImpls.fails(TransactionDSLInterpreter.kt)
	at net.corda.testing.dsl.TestTransactionDSLInterpreter.fails(TestDSL.kt:74)
	at net.corda.testing.dsl.TransactionDSL.fails(TransactionDSLInterpreter.kt)
	at com.template.contracts.ContractTests.lambda$MetalContractRequiresTheIssuerToBeARequiredSignerInTheTransaction$8(ContractTests.java:134)
	at net.corda.testing.node.NodeTestUtils$transaction$1.invoke(NodeTestUtils.kt:54)
	at net.corda.testing.node.NodeTestUtils$transaction$1.invoke(NodeTestUtils.kt)
	at net.corda.testing.node.NodeTestUtils$ledger$2.invoke(NodeTestUtils.kt:39)
	at net.corda.testing.node.NodeTestUtils$ledger$2.invoke(NodeTestUtils.kt)
	at net.corda.testing.internal.InternalTestUtilsKt$withTestSerializationEnvIfNotSet$1.invoke(InternalTestUtils.kt:231)
	at net.corda.testing.internal.InternalTestUtilsKt$withTestSerializationEnvIfNotSet$1.invoke(InternalTestUtils.kt)
	at net.corda.testing.common.internal.CommonSerializationTestHelpersKt.asContextEnv(CommonSerializationTestHelpers.kt:11)
	at net.corda.testing.internal.InternalSerializationTestHelpersKt.asTestContextEnv(InternalSerializationTestHelpers.kt:33)
	at net.corda.testing.internal.InternalSerializationTestHelpersKt.asTestContextEnv$default(InternalSerializationTestHelpers.kt:31)
	at net.corda.testing.internal.InternalTestUtilsKt.withTestSerializationEnvIfNotSet(InternalTestUtils.kt:231)
	at net.corda.testing.node.NodeTestUtils.ledger(NodeTestUtils.kt:36)
	at net.corda.testing.node.NodeTestUtils.transaction(NodeTestUtils.kt:53)
	at net.corda.testing.node.NodeTestUtils.transaction$default(NodeTestUtils.kt:51)
	at net.corda.testing.node.NodeTestUtils.transaction(NodeTestUtils.kt)
	at com.template.contracts.ContractTests.MetalContractRequiresTheIssuerToBeARequiredSignerInTheTransaction(ContractTests.java:130)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:64)
Caused by: java.lang.ClassNotFoundException: net.corda.core.contracts.CommandData
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at net.corda.core.serialization.internal.AttachmentsClassLoader.loadClass(AttachmentsClassLoader.kt:289)
	... 115 more

build.gradle from Contract module

apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'

cordapp {
    targetPlatformVersion corda_platform_version
    minimumPlatformVersion corda_platform_version
    contract {
        name "Template CorDapp"
        vendor "Corda Open Source"
        licence "Apache License, Version 2.0"
        versionId 1
    }
}

sourceSets {
    main{
        java {
            srcDir 'src/main/java'
            java.outputDir = file('bin/main')
        }
    }
    test{
        java{
            srcDir 'src/test/java'
            java.outputDir = file('bin/test')
        }
    }
}

dependencies {
    // Corda dependencies.
    cordaCompile "$corda_release_group:corda-core:$corda_release_version"
    cordaRuntime "$corda_release_group:corda:$corda_release_version"
    testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
}

答案1

得分: 0

似乎您的项目结构有问题,因为出现了一个核心包的 NoClassDefFoundError 错误。

尝试关闭项目,还有将项目从最近项目列表中移除。
然后打开项目文件夹,按照提示选择“导入 Gradle 项目”。

英文:

It looks like something wrong with your project structure since it is a NoClassDefFoundError of a core package.

Try closing the project and also removing the project from your recent project list.
And open the project folder then follow the prompt to import Gradle project.

答案2

得分: 0

选择“编辑配置”并选择“JAR清单”作为“缩短命令行”:

[ERROR]TransactionBuilder. – The transaction currently built is missing an attachment for :classnet/corda/core/contracts/CommandData

英文:

Edit Configurations and choose "JAR manifest" for "Shorten command line":

[ERROR]TransactionBuilder. – The transaction currently built is missing an attachment for :classnet/corda/core/contracts/CommandData

huangapple
  • 本文由 发表于 2020年5月29日 16:02:36
  • 转载请务必保留本文链接:https://java.coder-hub.com/62081333.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定