精华内容
下载资源
问答
  • fabric官方提供的java sdk包含两个项目[fabric-sdk-java和[fabric-gateway-java,前者用于与fabric网络交互的低级API(比如创建channel、加入channel、安装chaincode等),后者为高级API(主要针对chaincode的调用)

    概述

    fabric官方提供的java sdk包含两个项目fabric-sdk-javafabric-gateway-java,前者用于与fabric网络交互的低级API(比如创建channel、加入channel、安装chaincode等),fabric-sdk-java还包含了fabric-ca client的实现,后者为高级API(主要针对chaincode的调用),fabric-gateway-java使用了fabric-sdk-java的api。

    一、fabric-gateway-java的基本用法

    依赖:

    <dependency>
      <groupId>org.hyperledger.fabric</groupId>
      <artifactId>fabric-gateway-java</artifactId>
      <version>2.0.0</version>
    </dependency>
    

    官方示例:

    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.concurrent.TimeoutException;
    
    import org.hyperledger.fabric.gateway.Contract;
    import org.hyperledger.fabric.gateway.ContractException;
    import org.hyperledger.fabric.gateway.Gateway;
    import org.hyperledger.fabric.gateway.Network;
    import org.hyperledger.fabric.gateway.Wallet;
    import org.hyperledger.fabric.gateway.Wallets;
    
    class Sample {
        public static void main(String[] args) throws IOException {
        
           // 载入一个存在的持有用户身份的钱包,用于访问fabric网络
            Path walletDirectory = Paths.get("wallet");
            Wallet wallet = Wallets.newFileSystemWallet(walletDirectory);
    
            //Path为fabric网络配置文件的路径
            Path networkConfigFile = Paths.get("connection.json");
    
            // 配置gateway连接用于访问fabric网络(用户和网络配置文件)
            Gateway.Builder builder = Gateway.createBuilder()
                    .identity(wallet, "user1")
                    .networkConfig(networkConfigFile);
    
            // 创建一个gateway连接
            try (Gateway gateway = builder.connect()) {
    
                //根据gateway获取指定的通道网络
                Network network = gateway.getNetwork("mychannel");
                //根据chaincode名称从通道网络中获取智能合约
                Contract contract = network.getContract("fabcar");
    
                // 提交事务 存储到账本
                byte[] createCarResult = contract.createTransaction("createCar")
                        .submit("CAR10", "VW", "Polo", "Grey", "Mary");
                System.out.println(new String(createCarResult, StandardCharsets.UTF_8));
    
                // 从账本中查询状态
                byte[] queryAllCarsResult = contract.evaluateTransaction("queryAllCars");
                System.out.println(new String(queryAllCarsResult, StandardCharsets.UTF_8));
    
            } catch (ContractException | TimeoutException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    这里抽象出了钱包、网关的概念,网关即API调用的入口,每个钱包可以存放多个用户身份,构造网关的时候指定钱包其中一个用户。
    怎么构建一个钱包,可以参考fabric-gateway-java/src/test/java/org/hyperledger/fabric/gateway/TestUtils.java
    钱包就是一个目录,里面存放了一个一个的身份,每个身份包含了mspId,证书类型、证书和私钥,参考fabric-gateway-java/src/test/fixtures/test-wallet/x509-v1.id,下面一个身份文件示例:

    {"version":1,"mspId":"mspId","type":"X.509","credentials":{"certificate":"-----BEGIN CERTIFICATE-----\nMIIBWjCB3qADAgECAgYBbvXSw4QwDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwI\nSm9obiBEb2UwHhcNMTkxMjEwMTYzNzQwWhcNMTkxMTI2MDA1NTUxWjATMREwDwYD\nVQQDDAhKb2huIERvZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABBIV2OGF/VkRcQTf\n5NjLpQMIW+kc6VmBdpd7+YJ4CrpxtCISiMcDf4LxQ2QdVhkM0FSiYCFLxnDOg8u6\nTm+uKVzlH0HEKkPycoDk784dcvyXiUuWuo6ZHXaCQJfEHNldPzANBgkqhkiG9w0B\nAQsFAANoADBlAjEAoNys0S+/R9/w3bUMwohRN7NuIh2JYmxy3oEafunF4LaNaRd8\ndG9gLBn/7LQZGUu7AjBLQQMV0GPZCNl6JN4TZyxcARxDCmpiuIAzwZuFRYpaAVTO\npJgR6ICTZ0Ko3rz4cT4=\n-----END CERTIFICATE-----\n","privateKey":"-----BEGIN PRIVATE KEY-----\nMIG/AgEAMBAGByqGSM49AgEGBSuBBAAiBIGnMIGkAgEBBDAAL3tEAlZDEPZiOxZp\njjGncTzZtLBbtO30tqT+WdTbRqwF9OpGLBAgsbzzo9nhqBagBwYFK4EEACKhZANi\nAAQSFdjhhf1ZEXEE3+TYy6UDCFvpHOlZgXaXe/mCeAq6cbQiEojHA3+C8UNkHVYZ\nDNBUomAhS8ZwzoPLuk5vrilc5R9BxCpD8nKA5O/OHXL8l4lLlrqOmR12gkCXxBzZ\nXT8=\n-----END PRIVATE KEY-----\n"}}
    

    fabric网络配置文件示例:

    {
        "name": "basic-network",
        "version": "1.0.0",
        "client": {
            "organization": "Org1",
            "connection": {
                "timeout": {
                    "peer": {
                        "endorser": "300"
                    },
                    "orderer": "300"
                }
            }
        },
        "channels": {
            "mychannel": {
                "orderers": [
                    "orderer.example.com"
                ],
                "peers": {
                    "peer0.org1.example.com": {
                    	"endorsingPeer": true,
                    	"chaincodeQuery": true,
                    	"ledgerQuery": true,
                    	"eventSource": true
                    }
                }
            }
        },
        "organizations": {
            "Org1": {
                "mspid": "Org1MSP",
                "peers": [
                    "peer0.org1.example.com"
                ],
                "certificateAuthorities": [
                    "ca.example.com"
                ]
            }
        },
        "orderers": {
            "orderer.example.com": {
                "url": "grpc://localhost:7050"
            }
        },
        "peers": {
            "peer0.org1.example.com": {
                "url": "grpc://localhost:7051"
            }
        },
        "certificateAuthorities": {
            "ca.example.com": {
                "url": "http://localhost:7054",
                "caName": "ca.example.com"
            }
        }
    }
    
    

    二、fabric-sdk-java的基本用法

    这里主要摘取了End2endLifecycleIT.java的代码进行分析,根据这个demo学习sdk如何使用,最后总结主要用到的类和方法。

    chaincode详见:
    https://github.com/hyperledger/fabric-sdk-java/blob/v2.0.0/src/test/fixture/sdkintegration/gocc/sample_11/src/github.com/example_cc/example_cc.go

    场景:有两个组织peerOrg1,peerOrg2。首先创建两个sdk client,根据client创建channel,将peer加入通道,打包、审批、提交chaincode,最后调用chaincode。

    依赖:

    <repositories>
        <repository>
            <id>snapshots-repo</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
        
    <dependencies>
      <!-- https://mvnrepository.com/artifact/org.hyperledger.fabric-sdk-java/fabric-sdk-java -->
         <dependency>
             <groupId>org.hyperledger.fabric-sdk-java</groupId>
             <artifactId>fabric-sdk-java</artifactId>
             <version>2.0.0-SNAPSHOT</version>
         </dependency>
    </dependencies>
    

    1. 创建 client实例org1Client

     HFClient org1Client = HFClient.createNewInstance();
     org1Client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
    

    创建了与fabric网络交互的sdk client实例org1Client,设置了加密套件。

    2. 创建org1Channel,Orderer和Org1的peer加入Channel

     SampleOrg org1 = testConfig.getIntegrationTestsSampleOrg("peerOrg1");
     Channel org1Channel = constructChannel(CHANNEL_NAME, org1Client, org1, true);
    

    testConfig从properties文件读取key/value配置,根据key/value组装SampleOrg、SampleUser对象。
    从testConfig获取peerOrg1的配置,并调用constructChannel创建channel。

    constructChannel方法:

            SampleUser peerAdmin = myOrg.getPeerAdmin();
            client.setUserContext(peerAdmin);
    
            Collection<Orderer> orderers = new LinkedList<>();
    
            for (String orderName : myOrg.getOrdererNames()) {
    
                Properties ordererProperties = testConfig.getOrdererProperties(orderName);
                orderers.add(client.newOrderer(orderName, myOrg.getOrdererLocation(orderName),
                        ordererProperties));
            }
    
            //Just pick the first orderer in the list to create the channel.
            Orderer anOrderer = orderers.iterator().next();
            orderers.remove(anOrderer);
    
            String path = TEST_FIXTURES_PATH + "/sdkintegration/e2e-2Orgs/" + testConfig.getFabricConfigGenVers() + "/" + name + ".tx";
            
            ChannelConfiguration channelConfiguration = new ChannelConfiguration(new File(path));
    
            Channel newChannel = client.newChannel(name, anOrderer, channelConfiguration, client.getChannelConfigurationSignature(channelConfiguration, peerAdmin));
    
            out("Created channel %s", name);
    
            for (String peerName : myOrg.getPeerNames()) {
                String peerLocation = myOrg.getPeerLocation(peerName);
    
                Properties peerProperties = testConfig.getPeerProperties(peerName); //test properties for peer.. if any.
                if (peerProperties == null) {
                    peerProperties = new Properties();
                }
                Peer peer = client.newPeer(peerName, peerLocation, peerProperties);
                newChannel.joinPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(PeerRole.ENDORSING_PEER, PeerRole.LEDGER_QUERY, PeerRole.CHAINCODE_QUERY, PeerRole.EVENT_SOURCE))); 
    
                out("Peer %s joined channel %s", peerName, name);
            }
            for (Orderer orderer : orderers) { //add remaining orderers if any.
                newChannel.addOrderer(orderer);
            }
    
            newChannel.initialize();
      
    
    • 设置身份上下文setUserContext
    • 遍历orderer配置列表,生成orderer对象,取出第一个orderer用于创建通道
    • 根据通道配置文件(tx)构建ChannelConfiguration对象
    • 根据orderer、ChannelConfiguration、通道配置签名创建通道newChannel
    • 遍历peer配置列表生成peer对象,加入到通道newChannel,并设置peer的默认角色
    • 将剩余的orderer加入通道
    • 调用initialize方法初始化通道

    3. 创建client实例org2Client

     HFClient org2Client = HFClient.createNewInstance();
     org2Client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
    

    4. 创建org2Channel,Org2的peer加入Channel

     SampleOrg org2 = testConfig.getIntegrationTestsSampleOrg("peerOrg2");
     Channel org2Channel = constructChannel(CHANNEL_NAME, org2Client, org2,
                    false);
    

    constructChannel方法和上一步一致,不创建新的chanel,取得已经创建的Channel,其他代码一致

    client.newChannel(name).addOrderer(anOrderer)
    

    5. Org1、Org2的Peer交叉加入Channel

    //Add to the channel peers from other org.
    Collection<Peer> org2OtherPeers = addOtherOrgPeers(org2Client, org2Channel, org1);
    //Since org2's peers has joined channel can now add them to org1 too
    Collection<Peer> org1OtherPeers = addOtherOrgPeers(org1Client, org1Channel, org2);
    

    addOtherOrgPeers方法:

    for (String peerName : otherOrg.getPeerNames()) {
         String peerLocation = otherOrg.getPeerLocation(peerName);
         Properties peerProperties = testConfig.getPeerProperties(peerName); //test properties for peer.. if any.
         if (peerProperties == null) {
             peerProperties = new Properties();
         }
         Peer peer = myClient.newPeer(peerName, peerLocation, peerProperties);
         myChannel.addPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(PeerRole.ENDORSING_PEER, PeerRole.LEDGER_QUERY, PeerRole.CHAINCODE_QUERY, PeerRole.EVENT_SOURCE))); 
     }
    

    添加peer的时候设置了默认角色
    其中createPeerOptionsChannel类的静态方法,PeerOptionsChannel的静态内部类

    public static PeerOptions createPeerOptions() {
                return new PeerOptions();
    }
    

    6. chaincode package

    chaincode路径在文章开头已经提到过了

       LifecycleChaincodePackage lifecycleChaincodePackage = createLifecycleChaincodePackage(
                    "lc_example_cc_go_1", // some label
                    Type.GO_LANG,
                    IntegrationSuite.getGoChaincodePath("sample1").toString(),
                    CHAIN_CODE_PATH,
                    "src/test/fixture/meta-infs/end2endit");
    
     private LifecycleChaincodePackage createLifecycleChaincodePackage(String chaincodeLabel, Type chaincodeType, String chaincodeSourceLocation, String chaincodePath, String metadadataSource) throws IOException, InvalidArgumentException {
         out("creating install package %s.", chaincodeLabel);
         Path metadataSourcePath = null;
         if (metadadataSource != null) {
             metadataSourcePath = Paths.get(metadadataSource);
         }
         LifecycleChaincodePackage lifecycleChaincodePackage = LifecycleChaincodePackage.fromSource(chaincodeLabel, Paths.get(chaincodeSourceLocation),
                 chaincodeType,
                 chaincodePath, metadataSourcePath);
         return lifecycleChaincodePackage;
     }
    

    meta目录结构

    src/test/fixture/meta-infs/end2endit
    └── META-INF
        └── statedb
            └── couchdb
                └── indexes
                    └── IndexA.json
    

    IndexA.json

    {
      "ddoc": "indexADDoc",
      "index": {
        "fields": [
          "a"
        ]
      },
      "name": "indexA",
      "type": "json"
    }
    

    7. 生成背书策略对象(opt)

    LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy = LifecycleChaincodeEndorsementPolicy.fromSignaturePolicyYamlFile(Paths.get(TEST_FIXTURES_PATH +
           "/sdkintegration/chaincodeendorsementpolicy.yaml"));
    

    chaincodeendorsementpolicy.yaml

    # A Shotgun policy xx
    identities:  # list roles to be used in the policy
        user1: {"role": {"name": "member", "mspId": "Org1MSP"}} # role member in org with mspid Org1MSP
        user2: {"role": {"name": "member", "mspId": "Org2MSP"}}
        admin1: {"role": {"name": "admin", "mspId": "Org1MSP"}} # admin role.
        admin2: {"role": {"name": "admin", "mspId": "Org2MSP"}}
    
    policy: # the policy  .. could have been flat but show grouping.
        1-of: # signed by one of these groups  can be <n>-of  where <n> is any digit 2-of, 3-of etc..
          - 1-of:
            - signed-by: "user1" # a reference to one of the identities defined above.
            - signed-by: "admin1"
          - 1-of:
            - signed-by: "user2"
            - signed-by: "admin2"
    

    8. chaincode install

      final String goChaincodeName = "lc_example_cc_go";
      runChannel(org1Client, org1Channel, org1, org1MyPeers, org1OtherPeers,
              org2Client, org2Channel, org2, org2MyPeers, org2OtherPeers,
              lifecycleChaincodePackage, goChaincodeName,
              "1", //Version - bump up next time.
              chaincodeEndorsementPolicy,
              null, // ChaincodeCollectionConfiguration
              true,  // initRequired
              expectedMap);
    

    runChannel

    org1Client.setUserContext(org1.getPeerAdmin());
    
    final String chaincodeLabel = lifecycleChaincodePackage.getLabel();
    final Type chaincodeType = lifecycleChaincodePackage.getType();
    
    //Org1 installs the chaincode on its peers.
    out("Org1 installs the chaincode on its peers.");
    String org1ChaincodePackageID = lifecycleInstallChaincode(org1Client, org1MyPeers, lifecycleChaincodePackage);
    

    lifecycleInstallChaincode

    LifecycleInstallChaincodeRequest installProposalRequest = client.newLifecycleInstallChaincodeRequest();
    installProposalRequest.setLifecycleChaincodePackage(lifecycleChaincodePackage);
    installProposalRequest.setProposalWaitTime(DEPLOYWAITTIME);
    
    Collection<LifecycleInstallChaincodeProposalResponse> responses = client.sendLifecycleInstallChaincodeRequest(installProposalRequest, peers);
    
    String packageID = null;
    for (LifecycleInstallChaincodeProposalResponse response : responses) {
       if (response.getStatus() == ProposalResponse.Status.SUCCESS) {
           out("Successful install proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
           if (packageID == null) {
               packageID = response.getPackageId();
               assertNotNull(format("Hashcode came back as null from peer: %s ", response.getPeer()), packageID);
           } else {
               assertEquals("Miss match on what the peers returned back as the packageID", packageID, response.getPackageId());
           }
       } 
    }
    
    • 使用步骤6中的lifecycleChaincodePackaged对象构造LifecycleInstallChaincodeRequest对象
    • 调用client.sendLifecycleInstallChaincodeRequest执行安装,返回LifecycleInstallChaincodeProposalResponse,再从response获取packageId

    9. chaincode queryinstalled

    Collection<LifecycleQueryInstalledChaincodesProposalResponse> results = client.sendLifecycleQueryInstalledChaincodes(client.newLifecycleQueryInstalledChaincodesRequest(), peers);
    for (LifecycleQueryInstalledChaincodesProposalResponse peerResults : results) {
      if(peerResults.getStatus()==ChaincodeResponse.Status.SUCCESS){
        for (LifecycleQueryInstalledChaincodesResult lifecycleQueryInstalledChaincodesResult : peerResults.getLifecycleQueryInstalledChaincodesResult()) {
              if (excpectedPackageId.equals(lifecycleQueryInstalledChaincodesResult.getPackageId())) {
                  found = true;
                  break;
              }
         }
       }
    }
    

    10. chaincode query chaincode definition(opt)

    sequence第一次调用一定是1

    long sequence = -1L;
    final QueryLifecycleQueryChaincodeDefinitionRequest queryLifecycleQueryChaincodeDefinitionRequest = org1Client.newQueryLifecycleQueryChaincodeDefinitionRequest();
    queryLifecycleQueryChaincodeDefinitionRequest.setChaincodeName(chaincodeName);
    
    Collection<LifecycleQueryChaincodeDefinitionProposalResponse> firstQueryDefininitions = org1Channel.lifecycleQueryChaincodeDefinition(queryLifecycleQueryChaincodeDefinitionRequest, org1MyPeers);
    
    for (LifecycleQueryChaincodeDefinitionProposalResponse firstDefinition : firstQueryDefininitions) {
        if (firstDefinition.getStatus() == ProposalResponse.Status.SUCCESS) {
            sequence = firstDefinition.getSequence() + 1L; //Need to bump it up to the next.
            break;
        } else { //Failed but why?
            if (404 == firstDefinition.getChaincodeActionResponseStatus()) {
                // not found .. done set sequence to 1;
                sequence = 1;
                break;
            }
        }
    }
    
    • 根据chaincode名称构造QueryLifecycleQueryChaincodeDefinitionRequest对象
    • 查询lifecycleQueryChaincodeDefinition

    11. chaincode approveformyorg

    TransactionEvent transactionEvent = lifecycleApproveChaincodeDefinitionForMyOrg(org1Client, org1Channel,
                     Collections.singleton(anOrg1Peer), 
                     sequence, chaincodeName, chaincodeVersion,
                     lifecycleChaincodeEndorsementPolicy, 
                     chaincodeCollectionConfiguration, 
                     initRequired, org1ChaincodePackageID)
                     .get(testConfig.getTransactionWaitTime(), 
                     TimeUnit.SECONDS);
    assertTrue(transactionEvent.isValid());
    

    如果transactionEvent.isValid()的值为true,则审批通过。

    CompletableFuture<TransactionEvent> lifecycleApproveChaincodeDefinitionForMyOrg(HFClient client, Channel channel,Collection<Peer> peers, long sequence,String chaincodeName, String chaincodeVersion, LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy, ChaincodeCollectionConfiguration chaincodeCollectionConfiguration, boolean initRequired, String org1ChaincodePackageID) {
        LifecycleApproveChaincodeDefinitionForMyOrgRequest lifecycleApproveChaincodeDefinitionForMyOrgRequest = client.newLifecycleApproveChaincodeDefinitionForMyOrgRequest();
        lifecycleApproveChaincodeDefinitionForMyOrgRequest.setSequence(sequence);
        lifecycleApproveChaincodeDefinitionForMyOrgRequest.setChaincodeName(chaincodeName);
        lifecycleApproveChaincodeDefinitionForMyOrgRequest.setChaincodeVersion(chaincodeVersion);
        lifecycleApproveChaincodeDefinitionForMyOrgRequest.setInitRequired(initRequired);
    
        if (null != chaincodeCollectionConfiguration) {
            lifecycleApproveChaincodeDefinitionForMyOrgRequest.setChaincodeCollectionConfiguration(chaincodeCollectionConfiguration);
        }
    
        if (null != chaincodeEndorsementPolicy) {
            lifecycleApproveChaincodeDefinitionForMyOrgRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
        }
    
        lifecycleApproveChaincodeDefinitionForMyOrgRequest.setPackageId(org1ChaincodePackageID);
    
        Collection<LifecycleApproveChaincodeDefinitionForMyOrgProposalResponse> lifecycleApproveChaincodeDefinitionForMyOrgProposalResponse = channel.sendLifecycleApproveChaincodeDefinitionForMyOrgProposal(lifecycleApproveChaincodeDefinitionForMyOrgRequest,
                peers);
    
        for (LifecycleApproveChaincodeDefinitionForMyOrgProposalResponse response : lifecycleApproveChaincodeDefinitionForMyOrgProposalResponse) {
            final Peer peer = response.getPeer();
            assertEquals(format("failure on %s  message is: %s", peer, response.getMessage()), ChaincodeResponse.Status.SUCCESS, response.getStatus());
            assertFalse(peer + " " + response.getMessage(), response.isInvalid());
            assertTrue(format("failure on %s", peer), response.isVerified());
        }
        return channel.sendTransaction(lifecycleApproveChaincodeDefinitionForMyOrgProposalResponse);
    }
    
    • 构造LifecycleApproveChaincodeDefinitionForMyOrgRequest对象(sequence、chaincodeName、chaincodeVersion、initRequired、packageId)
    • chaincodeCollectionConfiguration和chaincodeEndorsementPolicy可为空,这里chaincodeEndorsementPolicy使用了第7步构造的对象

    12. chaincode checkcommitreadiness

    out("Checking on org2's network for approvals");
    verifyByCheckCommitReadinessStatus(org2Client, org2Channel, sequence, chaincodeName, chaincodeVersion, lifecycleChaincodeEndorsementPolicy, chaincodeCollectionConfiguration, initRequired, org2MyPeers,
            new HashSet<>(Arrays.asList(ORG_1_MSP, ORG_2_MSP)), // Approved
            Collections.emptySet()); // Un approved.
    
    out("Checking on org1's network for approvals");
    verifyByCheckCommitReadinessStatus(org1Client, org1Channel, sequence, chaincodeName, chaincodeVersion, lifecycleChaincodeEndorsementPolicy, chaincodeCollectionConfiguration, initRequired, org1MyPeers,
            new HashSet<>(Arrays.asList(ORG_1_MSP, ORG_2_MSP)), // Approved
            Collections.emptySet()); // unapproved.
    
    private void verifyByCheckCommitReadinessStatus(HFClient client, Channel channel, long definitionSequence, String chaincodeName,
                                                        String chaincodeVersion, LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy,
                                                        ChaincodeCollectionConfiguration chaincodeCollectionConfiguration, boolean initRequired, Collection<Peer> org1MyPeers,
                                                        Set<String> expectedApproved, Set<String> expectedUnApproved) throws InvalidArgumentException, ProposalException {
       LifecycleCheckCommitReadinessRequest lifecycleCheckCommitReadinessRequest = client.newLifecycleSimulateCommitChaincodeDefinitionRequest();
       lifecycleCheckCommitReadinessRequest.setSequence(definitionSequence);
       lifecycleCheckCommitReadinessRequest.setChaincodeName(chaincodeName);
       lifecycleCheckCommitReadinessRequest.setChaincodeVersion(chaincodeVersion);
       if (null != chaincodeEndorsementPolicy) {
           lifecycleCheckCommitReadinessRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
       }
       if (null != chaincodeCollectionConfiguration) {
           lifecycleCheckCommitReadinessRequest.setChaincodeCollectionConfiguration(chaincodeCollectionConfiguration);
       }
       lifecycleCheckCommitReadinessRequest.setInitRequired(initRequired);
    
       Collection<LifecycleCheckCommitReadinessProposalResponse> lifecycleSimulateCommitChaincodeDefinitionProposalResponse = channel.sendLifecycleCheckCommitReadinessRequest(lifecycleCheckCommitReadinessRequest, org1MyPeers);
       for (LifecycleCheckCommitReadinessProposalResponse resp : lifecycleSimulateCommitChaincodeDefinitionProposalResponse) {
           final Peer peer = resp.getPeer();
           assertEquals(ChaincodeResponse.Status.SUCCESS, resp.getStatus());
           assertEquals(format("Approved orgs failed on %s", peer), expectedApproved, resp.getApprovedOrgs());
           assertEquals(format("UnApproved orgs failed on %s", peer), expectedUnApproved, resp.getUnApprovedOrgs());
       }
    }
    

    主要构造LifecycleCheckCommitReadinessRequest对象(sequence、chaincodeName、chaincodeVersion、initRequired)

    13. chaincode commit

    out("Org2 doing commit chaincode definition");
    Collection<Peer> org2EndorsingPeers = Arrays.asList(org2MyPeers.iterator().next(), org2OtherPeers.iterator().next());
    transactionEvent = commitChaincodeDefinitionRequest(org2Client, org2Channel, sequence, chaincodeName, chaincodeVersion, org2ChaincodeEndorsementPolicy, chaincodeCollectionConfiguration, initRequired, org2EndorsingPeers)
            .get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS);
    assertTrue(transactionEvent.isValid());
    
    out("Org2 done with commit. block #%d!", transactionEvent.getBlockEvent().getBlockNumber());
    
     private CompletableFuture<TransactionEvent> commitChaincodeDefinitionRequest(HFClient client, Channel channel, long definitionSequence, String chaincodeName, String chaincodeVersion,
                                                                                  LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy,
                                                                                    ChaincodeCollectionConfiguration chaincodeCollectionConfiguration,
                                                                                     boolean initRequired, Collection<Peer> endorsingPeers) throws ProposalException, InvalidArgumentException, InterruptedException, ExecutionException, TimeoutException {
       	LifecycleCommitChaincodeDefinitionRequest lifecycleCommitChaincodeDefinitionRequest = client.newLifecycleCommitChaincodeDefinitionRequest();
        lifecycleCommitChaincodeDefinitionRequest.setSequence(definitionSequence);
        lifecycleCommitChaincodeDefinitionRequest.setChaincodeName(chaincodeName);
        lifecycleCommitChaincodeDefinitionRequest.setChaincodeVersion(chaincodeVersion);
        if (null != chaincodeEndorsementPolicy) {
            lifecycleCommitChaincodeDefinitionRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
        }
        if (null != chaincodeCollectionConfiguration) {
            lifecycleCommitChaincodeDefinitionRequest.setChaincodeCollectionConfiguration(chaincodeCollectionConfiguration);
        }
        lifecycleCommitChaincodeDefinitionRequest.setInitRequired(initRequired);
    
        Collection<LifecycleCommitChaincodeDefinitionProposalResponse> lifecycleCommitChaincodeDefinitionProposalResponses = channel.sendLifecycleCommitChaincodeDefinitionProposal(lifecycleCommitChaincodeDefinitionRequest,
                endorsingPeers);
                
        for (LifecycleCommitChaincodeDefinitionProposalResponse resp : lifecycleCommitChaincodeDefinitionProposalResponses) {
    
            final Peer peer = resp.getPeer();
            assertEquals(format("%s had unexpected status.", peer.toString()), ChaincodeResponse.Status.SUCCESS, resp.getStatus());
            assertTrue(format("%s not verified.", peer.toString()), resp.isVerified());
        }
        return channel.sendTransaction(lifecycleCommitChaincodeDefinitionProposalResponses);
    }
    

    主要构造LifecycleCommitChaincodeDefinitionRequest对象(sequence、chaincodeName、chaincodeVersion、initRequired)

    14. chaincode init、 chaincode invoke

    out("Org1 doing init");
    transactionEvent = executeChaincode(org1Client, org1.getPeerAdmin(), org1Channel, "init",
            initRequired ? true : null, // doInit don't even specify it has it should default to false
            chaincodeName, chaincodeType, "a,", "100", "b", "300").get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS);
    assertTrue(transactionEvent.isValid());
    
    transactionEvent = executeChaincode(org2Client, org2.getPeerAdmin(), org2Channel, "move",
            false, // doInit
            chaincodeName, chaincodeType, "a,", "b", "10").get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS);
    assertTrue(transactionEvent.isValid());
    
    CompletableFuture<TransactionEvent> executeChaincode(HFClient client, User userContext, Channel channel, String fcn, Boolean doInit, String chaincodeName, Type chaincodeType, String... args) throws InvalidArgumentException, ProposalException {
    
            final ExecutionException[] executionExceptions = new ExecutionException[1];
    
            Collection<ProposalResponse> successful = new LinkedList<>();
            Collection<ProposalResponse> failed = new LinkedList<>();
    
            TransactionProposalRequest transactionProposalRequest = client.newTransactionProposalRequest();
            transactionProposalRequest.setChaincodeName(chaincodeName);
            transactionProposalRequest.setChaincodeLanguage(chaincodeType);
            transactionProposalRequest.setUserContext(userContext);
    
            transactionProposalRequest.setFcn(fcn);
            transactionProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime());
            transactionProposalRequest.setArgs(args);
            if (null != doInit) {
                transactionProposalRequest.setInit(doInit);
            }
    
            //  Collection<ProposalResponse> transactionPropResp = channel.sendTransactionProposalToEndorsers(transactionProposalRequest);
            Collection<ProposalResponse> transactionPropResp = channel.sendTransactionProposal(transactionProposalRequest, channel.getPeers());
            for (ProposalResponse response : transactionPropResp) {
                if (response.getStatus() == ProposalResponse.Status.SUCCESS) {
                    out("Successful transaction proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
                    successful.add(response);
                } else {
                    failed.add(response);
                }
            }
    
            out("Received %d transaction proposal responses. Successful+verified: %d . Failed: %d",
                    transactionPropResp.size(), successful.size(), failed.size());
            if (failed.size() > 0) {
                ProposalResponse firstTransactionProposalResponse = failed.iterator().next();
                fail("Not enough endorsers for executeChaincode(move a,b,100):" + failed.size() + " endorser error: " +
                        firstTransactionProposalResponse.getMessage() +
                        ". Was verified: " + firstTransactionProposalResponse.isVerified());
            }
            out("Successfully received transaction proposal responses.");
    
            //  System.exit(10);
    
            
            // Send Transaction Transaction to orderer
            out("Sending chaincode transaction(move a,b,100) to orderer.");
            return channel.sendTransaction(successful);
    
        }
    

    构造TransactionProposalRequest对象,最后多了一步将结果发送给orderer:channel.sendTransaction(successful)

    15. chaincode query

    executeVerifyByQuery(org1Client, org1Channel, chaincodeName, (String) expected.get("queryBvalue"));
    executeVerifyByQuery(org2Client, org2Channel, chaincodeName, (String) expected.get("queryBvalue"));
    
     void executeVerifyByQuery(HFClient client, Channel channel, String chaincodeName, String expect) throws ProposalException, InvalidArgumentException {
            out("Now query chaincode for the value of b.");
            QueryByChaincodeRequest queryByChaincodeRequest = client.newQueryProposalRequest();
            queryByChaincodeRequest.setArgs("b");
            queryByChaincodeRequest.setFcn("query");
            queryByChaincodeRequest.setChaincodeName(chaincodeName);
    
            Collection<ProposalResponse> queryProposals = channel.queryByChaincode(queryByChaincodeRequest, channel.getPeers());
            for (ProposalResponse proposalResponse : queryProposals) {
                if (!proposalResponse.isVerified() || proposalResponse.getStatus() != ProposalResponse.Status.SUCCESS) {
                    fail("Failed query proposal from peer " + proposalResponse.getPeer().getName() + " status: " + proposalResponse.getStatus() +
                            ". Messages: " + proposalResponse.getMessage()
                            + ". Was verified : " + proposalResponse.isVerified());
                } else {
                    String payload = proposalResponse.getProposalResponse().getResponse().getPayload().toStringUtf8();
                    out("Query payload of b from peer %s returned %s", proposalResponse.getPeer().getName(), payload);
                    assertEquals(expect, payload);
                }
            }
    
        }
    

    主要构造QueryByChaincodeRequest对象(chaincodeName、Fcn、Args)

    总结一下

    创建sdk实例,并设置当前用户身份

     HFClient client = HFClient.createNewInstance();
     client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
     client.setUserContext(peerAdmin);
    

    创建channel

    ChannelConfiguration channelConfiguration = new ChannelConfiguration(new File(path));
    Channel newChannel = client.newChannel(name, anOrderer, channelConfiguration, client.getChannelConfigurationSignature(channelConfiguration, peerAdmin));
    

    创建peer并加入channel

    Peer peer = client.newPeer(peerName, peerLocation, peerProperties);
    newChannel.joinPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(PeerRole.ENDORSING_PEER, PeerRole.LEDGER_QUERY, PeerRole.CHAINCODE_QUERY, PeerRole.EVENT_SOURCE))); 
    

    orderer加入channel

    newChannel.addOrderer(orderer);
    

    初始化channel

     newChannel.initialize(); 
    

    打包chaincode

    LifecycleChaincodePackage lifecycleChaincodePackage = LifecycleChaincodePackage.fromSource(chaincodeLabel, Paths.get(chaincodeSourceLocation),
             chaincodeType,
             chaincodePath, metadataSourcePath);
    

    安装chaincode

    LifecycleInstallChaincodeRequest installProposalRequest = client.newLifecycleInstallChaincodeRequest();
    installProposalRequest.setLifecycleChaincodePackage(lifecycleChaincodePackage);
    Collection<LifecycleInstallChaincodeProposalResponse> responses = client.sendLifecycleInstallChaincodeRequest(installProposalRequest, peers);
    

    查询已安装chaincode

    //sendLifecycleQueryInstalledChaincode
    final LifecycleQueryInstalledChaincodeRequest lifecycleQueryInstalledChaincodeRequest = client.newLifecycleQueryInstalledChaincodeRequest();
    lifecycleQueryInstalledChaincodeRequest.setPackageID(packageId);
    Collection<LifecycleQueryInstalledChaincodeProposalResponse> responses = client.sendLifecycleQueryInstalledChaincode(lifecycleQueryInstalledChaincodeRequest, peers);
    
    //sendLifecycleQueryInstalledChaincodes
    Collection<LifecycleQueryInstalledChaincodesProposalResponse> results = client.sendLifecycleQueryInstalledChaincodes(client.newLifecycleQueryInstalledChaincodesRequest(), peers);
    

    审批chaincode

    LifecycleApproveChaincodeDefinitionForMyOrgRequest lifecycleApproveChaincodeDefinitionForMyOrgRequest = client.newLifecycleApproveChaincodeDefinitionForMyOrgRequest();
    lifecycleApproveChaincodeDefinitionForMyOrgRequest.setSequence(sequence);
    lifecycleApproveChaincodeDefinitionForMyOrgRequest.setChaincodeName(chaincodeName);
    lifecycleApproveChaincodeDefinitionForMyOrgRequest.setChaincodeVersion(chaincodeVersion);
    lifecycleApproveChaincodeDefinitionForMyOrgRequest.setInitRequired(initRequired);
    lifecycleApproveChaincodeDefinitionForMyOrgRequest.setPackageId(org1ChaincodePackageID);
    Collection<LifecycleApproveChaincodeDefinitionForMyOrgProposalResponse> lifecycleApproveChaincodeDefinitionForMyOrgProposalResponse = channel.sendLifecycleApproveChaincodeDefinitionForMyOrgProposal(lifecycleApproveChaincodeDefinitionForMyOrgRequest,peers);
    

    查询审批chaincode

    LifecycleCheckCommitReadinessRequest lifecycleCheckCommitReadinessRequest = client.newLifecycleSimulateCommitChaincodeDefinitionRequest();
    lifecycleCheckCommitReadinessRequest.setSequence(definitionSequence);
    lifecycleCheckCommitReadinessRequest.setChaincodeName(chaincodeName);
    lifecycleCheckCommitReadinessRequest.setChaincodeVersion(chaincodeVersion);
    lifecycleCheckCommitReadinessRequest.setInitRequired(initRequired);
    Collection<LifecycleCheckCommitReadinessProposalResponse> lifecycleSimulateCommitChaincodeDefinitionProposalResponse = channel.sendLifecycleCheckCommitReadinessRequest(lifecycleCheckCommitReadinessRequest, org1MyPeers);
    

    提交chaincode

    LifecycleCommitChaincodeDefinitionRequest lifecycleCommitChaincodeDefinitionRequest = client.newLifecycleCommitChaincodeDefinitionRequest();
    lifecycleCommitChaincodeDefinitionRequest.setSequence(definitionSequence);
    lifecycleCommitChaincodeDefinitionRequest.setChaincodeName(chaincodeName);
    lifecycleCommitChaincodeDefinitionRequest.setChaincodeVersion(chaincodeVersion);
    lifecycleCommitChaincodeDefinitionRequest.setInitRequired(initRequired);
    Collection<LifecycleCommitChaincodeDefinitionProposalResponse> lifecycleCommitChaincodeDefinitionProposalResponses = channel.sendLifecycleCommitChaincodeDefinitionProposal(lifecycleCommitChaincodeDefinitionRequest,endorsingPeers);
    

    调用chaincode

    TransactionProposalRequest transactionProposalRequest = client.newTransactionProposalRequest();
    transactionProposalRequest.setChaincodeName(chaincodeName);
    transactionProposalRequest.setChaincodeLanguage(chaincodeType);
    transactionProposalRequest.setUserContext(userContext);
    transactionProposalRequest.setFcn(fcn);
    transactionProposalRequest.setArgs(args);
    transactionProposalRequest.setInit(doInit);
    //  Collection<ProposalResponse> transactionPropResp = channel.sendTransactionProposalToEndorsers(transactionProposalRequest);
    Collection<ProposalResponse> transactionPropResp = channel.sendTransactionProposal(transactionProposalRequest, channel.getPeers());
    

    查询chaincode状态值

    QueryByChaincodeRequest queryByChaincodeRequest = client.newQueryProposalRequest();
    queryByChaincodeRequest.setArgs("b");
    queryByChaincodeRequest.setFcn("query");
    queryByChaincodeRequest.setChaincodeName(chaincodeName);
    Collection<ProposalResponse> queryProposals = channel.queryByChaincode(queryByChaincodeRequest, channel.getPeers());
    
    展开全文
  • Fabric Java SDK最新教程

    千次阅读 2019-04-25 19:44:00
    Fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,全称为Fabric-sdk-java,网上可用资料不多,本文列出了精心整理的针对Fabric Java SDK的最新精选教程。 如果希望快速掌握Fabric Java SDK的使用...
        

    Fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,全称为Fabric-sdk-java,网上可用资料不多,本文列出了精心整理的针对Fabric Java SDK的最新精选教程。

    如果希望快速掌握Fabric Java SDK的使用方法,建议访问汇智网的在线互动教程:

    1、官方文档

    使用Fabric Java SDK开发必备的手册,从Java SDK源代码注释生成的每个接口、类和方法的简要说明,聊胜于无,但是要指望它达到真正理解并掌握Fabric Java SDK的使用方法还远远不够。

    链接:https://sdkjavadocs.github.io/

    2、Fabric-sdk-java链码访问快速上手教程

    非常简洁的fabric java sdk中文起步教程,hello-world级别,适合快速熟悉fabric java sdk的使用方法。使用的fabric-sdk-java版本为1.4.1。

    链接:http://blog.hubwiz.com/2019/04/23/fabric-sdk-java-hello-world/

    3、超级账本Fabric-SDK-Java简明教程

    这是一个关于Fabric Java SDK的简明教程,通过使用fabric-sdk-java创建一个简单的Java客户端,来快速了解Fabric Java SDK的使用方法,例如连接配置文件编写、Fabric-CA使用、交易执行流程、链码调用等,适合快速上手fabric java
    sdk。

    链接:https://codeburst.io/a-concise-tutorial-on-working-with-hyperledger-fabric-java-sdk-a6f11d8bb5b0

    4、超级账本fabric-sdk-java基础教程

    这也是一个适合快速上手Fabric java sdk的教程,内容主要包括CA用户登记、初始化HFClient、初始化通道对象、调用链码等fabric java sdk运用的主要环节,要比前面的教程更简单一些。

    链接:https://medium.com/@lkolisko/hyperledger-fabric-sdk-java-basics-tutorial-a67b2b898410

    5、使用超级账本fabric java sdk访问链码

    这篇文章的重点在于链码的调用,因此比较详细地步骤讲解了使用fabric java sdk查询链码状态或提交链码交易的代码,使用的是官方的fabcar链码案例。

    链接:https://medium.com/@lkolisko/tutorial-invoking-chaincode-from-hyperledger-fabric-java-sdk-e8dea535a1be

    6、使用fabric java sdk进行TLS通信

    这篇文章的重点是介绍如何使用fabric java sdk访问启用了tls通信的超级账本fabric区块链网络。IBM专供。

    链接:https://developer.ibm.com/tutorials/hyperledger-fabric-java-sdk-for-tls-enabled-fabric-network/

    7、使用fabric java sdk创建和部署网络

    这篇文章介绍如何使用fabric java sdk来创建并部署一个fabric区块链网络。

    链接:https://developer.ibm.com/patterns/create-and-deploy-blockchain-network-using-fabric-sdk-java/

    8、使用Hyperledger Fabric Java SDK 构建和部署区块链网络

    这篇文章主要介绍如何使用Hyperledger Fabric SDK Java创建,部署和测试区块链网络,以及链码开发、部署与调用。适用于较早版本的fabric1.1。

    链接:http://blog.hubwiz.com/2019/03/27/hyperledger-fabric-sdk-java/

    展开全文
  • Java sdk安装及配置

    万次阅读 热门讨论 2017-07-13 09:44:03
    1.安装Java SDK开发环境。 首先去官网下载Java SDK,http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html, 下载完成之后,开始安装。 点击下一步,安装完成。 2.配置Java SDK...

    1.安装Java SDK开发环境。

    首先去官网下载Java SDK,http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,


    下载完成之后,开始安装。


    点击下一步,安装完成。

    2.配置Java SDK环境变量

    单击“计算机-属性-高级系统设置”,单击“环境变量”。在“系统变量”栏下单击“新建”,创建新的系统环境变量。


    (1)新建->变量名"JAVA_HOME",变量值"C:\Java\jdk1.8.0_05"(即JDK的安装路径) 
    (2)编辑->变量名"Path",在原变量值的最后面加上“;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin” 
    (3)新建->变量名“CLASSPATH”,变量值“.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar

    新建的过程如下:



    编辑path的过程如下:




    展开全文
  • 海康威视运行Java SDK

    2019-11-28 16:59:26
    海康威视运行Java SDK1. SDK下载2. 安装海康威视设备3. 导入项目4. 放入dll文件4.1 放入dll文件前项目4.2 按官方说明文档,将dll放入5. 运行6. 解决方案7. 测试连接 海康威视开发平台:https://open.hikvision.com/...

    海康威视开发平台:https://open.hikvision.com/

    1. SDK下载

    https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10

    在这里插入图片描述

    2. 安装海康威视设备

    安装步骤:https://blog.csdn.net/WeiHao0240/article/details/103295039

    3. 导入项目

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    项目导入:https://blog.csdn.net/WeiHao0240/article/details/103296362

    4. 放入dll文件

    Demo内容说明【以下为官方给的说明文档】

    1. 该Demo主要介绍预览、回放、云台控制、参数配置等基本功能
      【注意事项】

    1. 请到海康威视官网下载最新版本设备网络SDK:http://www.hikvision.com/Cn/download_more_401.html

    2. 请修改程序代码,其中HCNetSDK.java文件自己指定loadlibrary加载库的路径,【库文件】里的HCNetSDK.dll、HCCore.dll、PlayCtrl.dll、SuperRender.dll、HCNetSDKCom文件夹等文件均拷贝到该路径>下。
      HCNetSDKCom文件夹(包含里面的功能组件dll库文件)需要和HCNetSDK.dll、HCCore.dll一起加载,放在同一个目录下,且HCNetSDKCom文件夹名不能修改。

    3. 如果自行开发软件不能正常实现相应功能,而且程序没有指定加载的dll库路径,请在程序运行的情况下尝试删除HCNetSDK.dll。如果可以删除,说明程序可能调用到系统盘Windows->System32目录下的dll文件,建议删除或者更新该目录下的相关dll文件;如果不能删除,dll文件右键选择属性确认SDK库版本。

    4. 如按上述步骤操作后还是不能实现相应功能,请根据NET_DVR_GetLastError返回的错误号判断原因。

    4.1 放入dll文件前项目

    在这里插入图片描述

    4.2 按官方说明文档,将dll放入

    在这里插入图片描述
    在这里插入图片描述

    将上面的文件直接放到项目根目录下

    在这里插入图片描述
    在这里插入图片描述

    5. 运行

    在这里插入图片描述

    运行时会报错:

    java.lang.UnsatisfiedLinkError: Unable to load library 'PlayCtrl': ÕҲ»µ½ָ¶¨
    	at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:145)
    	at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:188)
    	at com.sun.jna.Library$Handler.<init>(Library.java:123)
    	at com.sun.jna.Native.loadLibrary(Native.java:255)
    	at com.sun.jna.Native.loadLibrary(Native.java:241)
    	at ClientDemo.PlayCtrl.<clinit>(HCNetSDK.java:3063)
    	at ClientDemo.ClientDemo.<clinit>(ClientDemo.java:67)
    Exception in thread "main" 
    Process finished with exit code 1
    

    6. 解决方案

    将AudioRender.dll文件也放到根目录下
    在这里插入图片描述
    在这里插入图片描述

    7. 测试连接

    在这里插入图片描述

    展开全文
  • win10 配置java sdk

    千次阅读 2018-06-23 15:49:45
    win10 配置java sdk
  • Hyperledger Fabric Java SDK最新教程

    千次阅读 2019-04-25 19:35:03
    Fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,全称为Fabric-sdk-java,网上可用资料不多,本文列出了精心整理的针对Fabric Java SDK的最新精选教程。 如果希望快速掌握Fabric Java SDK的使用...
  • 海康威视(HIKVISION) JAVA SDK Demo成功运行

    千次阅读 热门讨论 2019-06-11 16:04:39
    海康威视(HIKVISION) JAVA SDK Demo成功运行引子下载说明代码编译添加文件问题排查总结 引子 调海康的JAVA SDK花费时间较长,所以记录下,为其他小伙伴填填坑,提高一下效率。官方文档确实少,而且demo中的说明...
  • 百度语音合成java SDK使用

    千次阅读 2018-03-19 15:31:20
    支持 JAVA版本:1.7+查看源码Java SDK代码现已公开,您可以查看代码、或者在License范围内修改和编译SDK以适配您的环境。github链接:https://github.com/Baidu-AIP/java-sdk直接使用JAR包步骤如下:1.在官方网站...
  • 微信Java SDK开发文档

    2020-05-09 10:01:14
    微信Java SDK开发文档 说明:如果使用新版本(2.0.0以上的),请参考新项目文档:https://github.com/Wechat-Group/weixin-java-tools/wiki 公众号开发 Quick Start(快速入门) 微信消息路由器 ...
  • linux 系统配置 java sdk

    2018-12-01 11:41:20
    linux 系统配置 java sdk java jdk 下载网址 java jdk 版本 oracle jdk-8u191-linux-x64.tar.gz linux 下有两种java jdk ,openjdk 和 oracle Java JDK,选择安装的是后者,版本号 jdk-8u191-linux-x64.tar.gz ...
  • 未检测到Java SDK 环境-Java环境变量设置-Java开发环境搭建
  • java sdk 访问s3 access denied

    千次阅读 2019-05-25 15:46:40
    java sdk 访问s3 access denied问题解决官方说明 问题 在使用java sdk访问aws s3时,本地调试一切ok,发布到服务器时却一直access denied。 反复确认key和region设置都没有问题。 解决 使用build()而不是default...
  • android SDK中引用的java SDK

    千次阅读 2014-11-10 10:20:26
    Android 虽然使用Java语言作为开发工具,但是在实际开发中发现,还是与Java SDK有一些不同的地方。Android SDK引用了大部分的Java SDK,少数部分被Android SDK抛弃,比如说界面部分和jsp用到的HTTPServlet,java.awt...
  • Ubuntu下JAVA SDK安装

    千次阅读 2018-07-31 10:53:03
    参考:Ubuntu下JAVA SDK(JDK)的安装并运行第一个小程序 介绍 JAVA是一门write-once, run anywhere 的语言。  我们在这里要安装JDK(JAVA development kit)以运行Java程序,其中自动包含JRE(JAVA Runtime ...
  • Android Killer设置JAVA SDK环境配置里选中JAVA SDK目录中的bin目录
  • 最近在开源社区协助比原链完成了 java sdk,这里跟大家分享下哈。 Bytom Java SDK This SDK contains methods for easily interacting with the Bytom API. Below are examples to get you started. For more ...
  • JAVA SDK安装和环境变量配置

    万次阅读 2017-06-20 20:03:25
    现在我就JAVA SDK 的安装来写篇笔记,作为日后的参照。 操作步骤: 1.到java的官网下载一个Java SDK的安装包,建议是7.0之后的版本。 2.安装SDK。一般情况下不建议安装在C盘。 双击sdk安装包,选择安装路径,...
  • Java SDK jar的使用

    千次阅读 2016-08-12 17:23:48
    记录Java SDK中jar工具的简单使用,并描述如何创建jar文件,两种方式。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,861
精华内容 20,344
关键字:

javasdk

java 订阅