简体   繁体   English

两个简单的 IBM MQ 客户端测试写入 MQ 队列 - 为什么一个有效,而另一个无效?

[英]Two simple IBM MQ client tests write to MQ queue - why does one work, but, NOT the other?

I'm running two(2) client tests.我正在运行两(2)个客户端测试。

Presumably they should both work.据推测,他们都应该工作。 But, one does not, and I do not know why.但是,一个没有,我不知道为什么。

(1) This one works... (1) 这个有效...

package aaa.bbb.ccc;

import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;

public class MQCheck {
    public static void main(String args[]) {
    try {
        int openOptions = CMQC.MQOO_INQUIRE | CMQC.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT;
        MQEnvironment.hostname = "localhost";
        MQEnvironment.port = 1414;
        MQEnvironment.channel = "DEV.APP.SVRCONN";
        MQEnvironment.properties.put(CMQC.USER_ID_PROPERTY, "admin");
        MQEnvironment.properties.put(CMQC.PASSWORD_PROPERTY, "passw0rd");          
        MQEnvironment.properties.put(CMQC.TRANSPORT_PROPERTY, CMQC.TRANSPORT_MQSERIES);
        MQQueueManager qMgr;
        qMgr = new MQQueueManager("QM1");
        MQQueue destQueue = qMgr.accessQueue("mylocalqueue", openOptions);
        MQMessage hello_world = new MQMessage();
        hello_world.writeUTF("Blah...blah...bleah...test message no.1...!");
        MQPutMessageOptions pmo = new MQPutMessageOptions();
        destQueue.put(hello_world, pmo);
        destQueue.close();
        qMgr.disconnect();
        System.out.println("------------------------success...");            
    } catch (Exception e) {
        System.out.println("Exception: " + e);
        e.printStackTrace();
    }
    }
}

(2) This one does NOT work... (2) 这个不行...

package aaa.bbb.ccc;

import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQSession;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;

public class MQCheck3 {

    public static void main(String args[]) {

    Connection qconn = null;
    QueueSession qsess = null;
    MQSession mqsess;
    Queue queue = null;

    try {
        MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
        connectionFactory.setHostName("localhost");
        connectionFactory.setChannel("DEV.APP.SVRCONN");//communications link
        connectionFactory.setPort(1414);
        connectionFactory.setQueueManager("QM1");
        connectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
        connectionFactory.setBooleanProperty(WMQConstants.CAPABILITY_USERNAME_PASSWORD, true);
        connectionFactory.setStringProperty(WMQConstants.USERID, "admin");
        connectionFactory.setStringProperty(WMQConstants.PASSWORD, "passw0rd");            
        qconn = (MQQueueConnection) connectionFactory.createConnection();
        qconn = connectionFactory.createQueueConnection();
        qconn.start();
        mqsess = (MQSession) qconn.createSession(false, Session.AUTO_ACKNOWLEDGE); //.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        queue = mqsess.createQueue("mylocalqueue");
        TextMessage textMessage = mqsess.createTextMessage("Bleah...bleah...blech...test message no.2...!");
        MessageProducer mc = mqsess.createProducer(queue);
        mc.send(textMessage, 0, 0, 0);
        System.out.println("------------------------success...");  
    } catch (JMSException e) {
        System.out.println("Exception: " + e);
        e.printStackTrace();
    } finally {
        try {
        qsess.close();
        qconn.close();
        } catch (JMSException e) {
        System.err.print(e);
        }
    }
    }
}

NOTE: Running the code in (2) gets the following exception...注意:运行 (2) 中的代码会出现以下异常...

Exception: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QM1' with connection mode 'Client' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'QM1' with connection mode 'Client' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
    at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:514)
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:214)
    at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:408)
    at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6398)
    at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:5740)
    at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:293)
    at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:234)
    at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:111)
    at aaa.bbb.ccc.MQCheck3.main(MQCheck3.java:35)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:202)
    ... 8 more
Exception in thread "main" java.lang.NullPointerException
    at aaa.bbb.ccc.MQCheck3.main(MQCheck3.java:48)

*QUESTION: can anyone explain to me why the 2nd example does not work?: * *问题:谁能向我解释为什么第二个例子不起作用?:*

-Is there something that is incorrect and/or missing from the code that would enable it to work? - 代码中是否存在不正确和/或缺失的内容使其能够正常工作?

FYI - running MQ server from Docker image:仅供参考 - 从 Docker 镜像运行 MQ 服务器:

C:>docker exec mq dspmqver C:>docker exec mq dspmqver

C:\>docker exec mq dspmqver
Name:        IBM MQ
Version:     9.0.3.0
Level:       p903-L170517.DE
BuildType:   IKAP - (Production)
Platform:    IBM MQ for Linux (x86-64 platform)
Mode:        64-bit
O/S:         Linux 4.9.31-moby
InstName:    Installation1
InstDesc:
Primary:     Yes
InstPath:    /opt/mqm
DataPath:    /var/mqm
MaxCmdLevel: 903
LicenseType: Developer

C:\>

pom.xml pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>aaa.bbb.ccc</groupId>
    <artifactId>mqcheck</artifactId>
    <version>1</version>
    <packaging>jar</packaging>
    <name>mqcheck</name>
    <description>mqcheck</description>

    <properties>
    <mq.version>8.0.0.2</mq.version>
    </properties>

    <dependencies>   
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>fscontext</artifactId>
        <version>${mq.version}</version>
    </dependency>          
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>jms</artifactId>
        <version>${mq.version}</version>
    </dependency>        
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>com.ibm.mq</artifactId>
        <version>${mq.version}</version>
    </dependency>
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>com.ibm.mqjms</artifactId>
        <version>${mq.version}</version>
    </dependency>
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>com.ibm.mq.jmqi</artifactId>
        <version>${mq.version}</version>
    </dependency>
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>com.ibm.mq.headers</artifactId>
        <version>${mq.version}</version>
    </dependency>
    <dependency>
        <groupId>ibm.mq</groupId>
        <artifactId>com.ibm.mq.commonservices</artifactId>
        <version>${mq.version}</version>
    </dependency>    
    </dependencies>

    <build>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <plugins>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <showDeprecation>true</showDeprecation>
        </configuration>
        </plugin>              
    </plugins>
    </build>
</project>

as per the suggestion in the post below (thx, joshmc), here is the AMQERR01.log it appears to provide a clue... -now, the quest to determine how to I unblock the 'admin' user :-)根据下面帖子中的建议(thx,joshmc),这里是 AMQERR01.log,它似乎提供了一个线索...... - 现在,寻求确定如何解除对“管理员”用户的阻止:-)

----- cmqxrmsa.c : 1347 -------------------------------------------------------
08/11/17 17:32:09 - Process(1847.6) User(root) Program(amqrmppa)
            Host(bd069b8075db) Installation(Installation1)
            VRMF(9.0.3.0) QMgr(QM1)
            Time(2017-08-11T17:32:09.967Z)

AMQ9776: Channel was blocked by userid

EXPLANATION:
The inbound channel 'DEV.APP.SVRCONN' was blocked from address '172.17.0.1'
because the active values of the channel were mapped to a userid which should
be blocked. The active values of the channel were 'MCAUSER(admin)
CLNTUSER(admin)'.
ACTION:
Contact the systems administrator, who should examine the channel
authentication records to ensure that the correct settings have been
configured. The ALTER QMGR CHLAUTH switch is used to control whether channel
authentication records are used. The command DISPLAY CHLAUTH can be used to
query the channel authentication records.
----- cmqxrmsa.c : 1347 ------------------------------------------------------- 

running following command (as suggested)...运行以下命令(如建议)...

C:\>docker exec --tty --interactive mq runmqsc
5724-H72 (C) Copyright IBM Corp. 1994, 2017.
Starting MQSC for queue manager QM1.

DIS CHL(DEV.APP.SVRCONN) MCAUSER DIS CHL(DEV.APP.SVRCONN) MCAUSER

DIS CHL(DEV.APP.SVRCONN) MCAUSER
     1 : DIS CHL(DEV.APP.SVRCONN) MCAUSER
AMQ8414: Display Channel details.
   CHANNEL(DEV.APP.SVRCONN)                CHLTYPE(SVRCONN)
   MCAUSER(app)
       :

DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1)显示CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK)所有地址(172.17.0.1)

DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
     5 : DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')
AMQ8878: Display channel authentication record details.
   CHLAUTH(DEV.APP.SVRCONN)                TYPE(ADDRESSMAP)
   DESCR( )                                CUSTOM( )
   ADDRESS(*)                              USERSRC(CHANNEL)
   CHCKCLNT(ASQMGR)                        ALTDATE(2017-08-11)
   ALTTIME(19.23.31)

DIS QMGR CONNAUTH DIS QMGR CONNAUT

DIS QMGR CONNAUTH
     1 : DIS QMGR CONNAUTH
AMQ8408: Display Queue Manager details.
   QMNAME(QM1)                             CONNAUTH(DEV.AUTHINFO)

DIS AUTHINFO(DEV.AUTHINFO) DIS AUTHINFO(DEV.AUTHINFO)

DIS AUTHINFO(DEV.AUTHINFO)
     2 : DIS AUTHINFO(DEV.AUTHINFO)
AMQ8566: Display authentication information details.
   AUTHINFO(DEV.AUTHINFO)                  AUTHTYPE(IDPWOS)
   ADOPTCTX(YES)                           DESCR( )
   CHCKCLNT(REQDADM)                       CHCKLOCL(OPTIONAL)
   FAILDLAY(1)                             AUTHENMD(OS)
   ALTDATE(2017-08-14)                     ALTTIME(13.57.29)

DISPLAY CHLAUTH(DEV.APP.SVRCONN) all显示 CLAUTH(DEV.APP.SVRCONN) 全部

DISPLAY CHLAUTH(DEV.APP.SVRCONN) all
     1 : DISPLAY CHLAUTH(DEV.APP.SVRCONN) all
AMQ8878: Display channel authentication record details.
   CHLAUTH(DEV.APP.SVRCONN)                TYPE(ADDRESSMAP)
   DESCR( )                                CUSTOM( )
   ADDRESS(*)                              USERSRC(CHANNEL)
   CHCKCLNT(ASQMGR)                        ALTDATE(2017-08-16)
   ALTTIME(13.43.26)

DISPLAY CHLAUTH( ) all*显示克劳斯( ) 全部*

DISPLAY CHLAUTH(*) all
     2 : DISPLAY CHLAUTH(*) all
AMQ8878: Display channel authentication record details.
   CHLAUTH(DEV.ADMIN.SVRCONN)              TYPE(USERMAP)
   DESCR(Allows admin user to connect via ADMIN channel)
   CUSTOM( )                               ADDRESS( )
   CLNTUSER(admin)                         USERSRC(CHANNEL)
   CHCKCLNT(ASQMGR)                        ALTDATE(2017-08-16)
   ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
   CHLAUTH(DEV.ADMIN.SVRCONN)              TYPE(BLOCKUSER)
   DESCR(Allows admins on ADMIN channel)   CUSTOM( )
   USERLIST(nobody)                        WARN(NO)
   ALTDATE(2017-08-16)                     ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
   CHLAUTH(DEV.APP.SVRCONN)                TYPE(ADDRESSMAP)
   DESCR( )                                CUSTOM( )
   ADDRESS(*)                              USERSRC(CHANNEL)
   CHCKCLNT(ASQMGR)                        ALTDATE(2017-08-16)
   ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
   CHLAUTH(MY.ADMIN.SVRCONN)               TYPE(ADDRESSMAP)
   DESCR( )                                CUSTOM( )
   ADDRESS(127.0.0.1)                      USERSRC(CHANNEL)
   CHCKCLNT(ASQMGR)                        ALTDATE(2017-08-11)
   ALTTIME(20.17.14)
AMQ8878: Display channel authentication record details.
   CHLAUTH(MY.ADMIN.SVRCONN)               TYPE(BLOCKUSER)
   DESCR( )                                CUSTOM( )
   USERLIST(*NOBODY)                       WARN(NO)
   ALTDATE(2017-08-11)                     ALTTIME(20.17.51)
AMQ8878: Display channel authentication record details.
   CHLAUTH(SYSTEM.ADMIN.SVRCONN)           TYPE(ADDRESSMAP)
   DESCR(Default rule to allow MQ Explorer access)
   CUSTOM( )                               ADDRESS(*)
   USERSRC(CHANNEL)                        CHCKCLNT(ASQMGR)
   ALTDATE(2017-08-03)                     ALTTIME(17.22.22)
AMQ8878: Display channel authentication record details.
   CHLAUTH(SYSTEM.*)                       TYPE(ADDRESSMAP)
   DESCR(Default rule to disable all SYSTEM channels)
   CUSTOM( )                               ADDRESS(*)
   USERSRC(NOACCESS)                       WARN(NO)
   ALTDATE(2017-08-03)                     ALTTIME(17.22.22)
AMQ8878: Display channel authentication record details.
   CHLAUTH(*)                              TYPE(ADDRESSMAP)
   DESCR(Back-stop rule - Blocks everyone)
   CUSTOM( )                               ADDRESS(*)
   USERSRC(NOACCESS)                       WARN(NO)
   ALTDATE(2017-08-16)                     ALTTIME(13.43.26)
AMQ8878: Display channel authentication record details.
   CHLAUTH(*)                              TYPE(BLOCKUSER)
   DESCR(Default rule to disallow privileged users)
   CUSTOM( )                               USERLIST(*MQADMIN)
   WARN(NO)                                ALTDATE(2017-08-03)
   ALTTIME(17.22.22)

The reason '2035' ('MQRC_NOT_AUTHORIZED') can be caused by quite a few issues. reason '2035' ('MQRC_NOT_AUTHORIZED')可能是由很多问题引起的。

IBM Support Technote " WMQ 7.1 / 7.5 / 8.0 / 9.0 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 or JMSWMQ2013 when using client connection as an MQ Administrator " has a good write up on diagnosing and resolving issues like this. IBM 支持技术说明“ WMQ 7.1 / 7.5 / 8.0 / 9.0 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 or JMSWMQ2013 when using client connection as an MQ Administrator ”有一篇关于诊断和解决此类问题的好文章。

If you want more specific help, to start with please provide the following details by editing and adding them to your question.如果您需要更具体的帮助,请首先通过编辑并将其添加到您的问题中来提供以下详细信息。

  1. Version of IBM MQ Classes for JMS used by the client application.客户端应用程序使用的 JMS 的 IBM MQ 类的版本。
  2. Version of IBM MQ installed on the IBM MQ queue manager IBM MQ 队列管理器上安装的 IBM MQ 版本
  3. Errors in the queue manager's AMQERR01.LOG that happen at the same time as the error you receive in the IBM MQ Classes for JMS client application.队列管理器的 AMQERR01.LOG 中的错误与您在 IBM MQ Classes for JMS 客户端应用程序中收到的错误同时发生。

Based on the error you have in the AMQERR01.LOG you have a CHLAUTH rule that is blocking you.根据您在AMQERR01.LOG中的AMQERR01.LOG您有一个阻止您的CHLAUTH规则。 Run the following command to see which rule this is:运行以下命令以查看这是哪条规则:

DISPLAY CHLAUTH(DEV.APP.SVRCONN) MATCH(RUNCHECK) ALL ADDRESS(172.17.0.1) CLNTUSER('admin')

If it is the default rule that blocks MQ administrative users from connecting, then this is a good thing from a security standpoint.如果阻止 MQ 管理用户连接是默认规则,那么从安全角度来看,这是一件好事。 It is much better to have an application connect to the queue manager as a USERID that is low privileged and does not have MQ administrative authority.最好让应用程序以低特权且没有 MQ 管理权限的 USERID 连接到队列管理器。 To do this you need to grant the user authority to connect to the queue manager as well as to PUT or GET from the queues required.为此,您需要授予用户连接到队列管理器以及从所需队列执行PUTGET权限。


After looking at the output so far I think what is happening is this.在查看到目前为止的输出后,我认为正在发生的事情就是这样。

  1. The IBM MQ Classes for Java program is not actually authenticating as the admin user and is being defaulted to the MCAUSER(app) on the SVRCONN channel which is not a MQ Administrative user so does not get blocked. IBM MQ Classes for Java 程序实际上并未以管理员用户身份进行身份验证,而是默认为 SVRCONN 通道上的 MCAUSER(app),该通道不是 MQ 管理用户,因此不会被阻止。 The issue is that the MQEnvironment.properties is meant to hold the value of a Hash table of properties not individual properties.问题在于MQEnvironment.properties旨在保存属性的哈希表的值,而不是单个属性。 Check out @Roger's answer to " Java program to connect WMQ with User Id instead of channel " for examples of using the Hashtable which is thread safe compared to the MQEnvironment which is not.查看@Roger 对“ 将 WMQ 与用户 ID 而不是通道连接的 Java 程序”的回答,了解使用线程安全的 Hashtable 与非 MQEnvironment 相比的示例。 But in fixing this issue the IBM MQ Classes for Java app should be blocked the same as the JMS app.但是在解决此问题时,IBM MQ Classes for Java 应用程序应该像 JMS 应用程序一样被阻止。

  2. The IBM MQ Classes for JMS program is properly authenticating as the admin user and ADOPTCTX(YES) is set and the admin user is a MQ Administrative user so is blocked by the following default CHLAUTH rule: IBM MQ Classes for JMS 程序正在以管理员用户身份正确进行身份验证,并且设置了 ADOPTCTX(YES),并且管理员用户是 MQ 管理用户,因此被以下默认 CHLAUTH 规则阻止:

     CHLAUTH(*) TYPE(BLOCKUSER) DESCR(Default rule to disallow privileged users) CUSTOM( ) USERLIST(*MQADMIN) WARN(NO)

Please validate by running the following:请通过运行以下命令进行验证:

DIS QMGR CONNAUTH

Then run the following command replacing the value SYSTEM.DEFAULT.AUTHINFO.IDPWOS with the value found in output of the above command if it is different:然后运行以下命令,将SYSTEM.DEFAULT.AUTHINFO.IDPWOS值替换为在上述命令的输出中找到的值(如果不同):

DIS AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)

Note I'm not sure why the RUNCHECK is not returning the BLOCKUSER rule, I don't have a 9.0.3 to try this on but with a similar ADDRESSMAP rule to the one that is being returned for you I still get the BLOCKUSER rule on both 8.0.0.5 and 8.0.0.6.注意我不知道为什么RUNCHECK没有返回BLOCKUSER规则,我没有 9.0.3 来尝试这个,但是与返回给你的规则相似的ADDRESSMAP规则我仍然得到BLOCKUSER规则在 8.0.0.5 和 8.0.0.6 上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JBoss Fuse/REST DSL - 为什么我的修改(使用 IBM MQ)不起作用? - JBoss Fuse/REST DSL - Why do my modifications (to use IBM MQ) not work? 如何验证池的IBM MQ连接 - How to validate IBM MQ connection for Pool 连接到MQ管理器会收到MQ错误2495 - Connecting to MQ manager get MQ error 2495 NoClassDefFoundError 无法初始化类 com.ibm.mq.headers.internal.HeaderType - NoClassDefFoundError Could not initialize class com.ibm.mq.headers.internal.HeaderType 我们可以将我的Java-Spring-mvc服务连接到IBM MQ而不用从队列中生成或使用绑定文件吗? - can we connect my Java-Spring-mvc service to IBM MQ without generating or using binding files from the queues 为什么此Java流的一个版本可以在静态地图上工作,而另一个版本却失败? - Why does one version of this Java stream work on a Static Map while the other fails? 带有JDk8的TLSv2带有MQ8的密码套件? - TLSv2 with JDk8 Ciphersuites with MQ8? 为什么 stream() 在 Scala 中不像在 Java 中那样工作? 是否有其他与 stream() API 相同的 API? - Why doesn't stream() work in Scala the way it does in Java? Is there any other API that does the same as stream() API? 当两个接口具有冲突的返回类型时,为什么一个方法成为默认值? - When two interfaces have conflicting return types, why does one method become default? Lambda表达式在一个接口上工作吗? - does Lambda expression work on one interface?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM