Skip to content
标签
欢迎扫码关注公众号

OTS 批量写入时报 UnsupportedOperationException 异常

使用 SyncClient.batchWriteRow 方法批量写入 OTS 时报了如下错误:

txt
java.lang.reflect.InvocationTargetException: null
    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.mokasz.zy.server.game.system.job.helper.ScheduleRunnable.run(ScheduleRunnable.java:38)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.UnsupportedOperationException: This is supposed to be overridden by subclasses.
    at com.google.protobuf.GeneratedMessage.getUnknownFields(GeneratedMessage.java:262)
    at com.alicloud.openservices.tablestore.core.protocol.OtsInternalApi$Condition.getSerializedSize(OtsInternalApi.java:4644)
    at com.google.protobuf.CodedOutputStream.computeMessageSizeNoTag(CodedOutputStream.java:877)
    at com.google.protobuf.CodedOutputStream.computeMessageSize(CodedOutputStream.java:661)
    at com.alicloud.openservices.tablestore.core.protocol.OtsInternalApi$RowInBatchWriteRowRequest.getSerializedSize(OtsInternalApi.java:30734)
    at com.google.protobuf.CodedOutputStream.computeMessageSizeNoTag(CodedOutputStream.java:877)
    at com.google.protobuf.CodedOutputStream.computeMessageSize(CodedOutputStream.java:661)
    at com.alicloud.openservices.tablestore.core.protocol.OtsInternalApi$TableInBatchWriteRowRequest.getSerializedSize(OtsInternalApi.java:31444)
    at com.google.protobuf.CodedOutputStream.computeMessageSizeNoTag(CodedOutputStream.java:877)
    at com.google.protobuf.CodedOutputStream.computeMessageSize(CodedOutputStream.java:661)
    at com.alicloud.openservices.tablestore.core.protocol.OtsInternalApi$BatchWriteRowRequest.getSerializedSize(OtsInternalApi.java:32104)
    at com.google.protobuf.AbstractMessageLite.toByteArray(AbstractMessageLite.java:69)
    at com.alicloud.openservices.tablestore.core.OperationLauncher.asyncInvokePost(OperationLauncher.java:117)
    at com.alicloud.openservices.tablestore.core.BatchWriteRowLauncher.fire(BatchWriteRowLauncher.java:64)
    at com.alicloud.openservices.tablestore.InternalClient.batchWriteRow(InternalClient.java:609)
    at com.alicloud.openservices.tablestore.SyncClient.batchWriteRow(SyncClient.java:282)
    ... 11 common frames omitted

参考官方文档,说是由于包冲突导致的。查了下果然在另外的包中依赖了 protobuf-java3.13.0 版本,而项目中依赖的 tablestore 5.4.0 中依赖的是 protobuf-java 2.4.1

官方文档中也给出了解决方案,在 tablestore 的依赖中添加下面配置中的 classifierexclusions 部分。需要注意的是其中 <classifier>jar-with-dependencies</classifier> 部分不能省略。

xml
<dependency>
    <groupId>com.aliyun.openservices</groupId>
    <artifactId>tablestore</artifactId>
    <version>替换为您当前使用的版本</version>
    <classifier>jar-with-dependencies</classifier>
    <exclusions>
        <exclusion>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpasyncclient</artifactId>
        </exclusion>
    </exclusions>
</dependency>

说明

classifierjar-with-dependencies ,它将依赖的 HttpClientProtobuf 库都通过 rename package 的方式打包进去,去除了对 HttpClientProtobuf 的依赖。

附上 SyncClient 批量写入的部分示例代码:

java
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.model.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class OtsServiceImpl implements OtsService {

    private final SyncClient syncClient;

    @Override
    public void saveUserLogs(List<UserLogDO> userLogs) {
        BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();

        userLogs.stream().map(l -> l.toRowPutChange())
                .forEach(c -> batchWriteRowRequest.addRowChange(c));

        BatchWriteRowResponse batchWriteRowResponse = syncClient.batchWriteRow(batchWriteRowRequest);

        log.info("saveUserVideoLogs SucceedRows : {} FailedRows: {}",
                batchWriteRowResponse.getSucceedRows().size(),
                batchWriteRowResponse.getFailedRows().size());
    }
}

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.