apache / apache/netbeans

code format bug. javax.swing.text.BadLocationException

Open
#5,976 2 comments 0 reactions 0 assignees View on GitHub
Java kind:bug
Dominant language
Java
Stars
3.1k
Forks
935
Avg merge
2d 3h
Merged PRs (30d)
17

Description

### Apache NetBeans version

Apache NetBeans 17

### What happened

```
javax.swing.text.BadLocationException: Invalid offset=-1 < 0; docLen=8540
at org.netbeans.modules.editor.lib2.document.EditorDocumentContent.checkOffsetNonNegative(EditorDocumentContent.java:246)
at org.netbeans.modules.editor.lib2.document.EditorDocumentContent.checkOffsetInContent(EditorDocumentContent.java:259)
at org.netbeans.modules.editor.lib2.document.EditorDocumentContent.createPosition(EditorDocumentContent.java:173)
at java.desktop/javax.swing.text.AbstractDocument.createPosition(AbstractDocument.java:861)
at org.netbeans.modules.editor.lib2.view.OffsetRegion.createPos(OffsetRegion.java:58)
Caused: java.lang.IllegalArgumentException: Invalid offset=-1 in doc: org.netbeans.modules.editor.NbEditorDocument@6b1edd0f, mimeType='text/x-java', kitClass=null, length=8540, version=5, file=org.netbeans.modules.java.JavaDataObject@33347d36[D:\work\source\owner\owner-app\owner-app-scmp-support\src\main\java\com\sprucetec\owner\app\scmp\product\helper\ProductAttrTemplateHelper.java@7003df10:3c0e3b81]
at org.netbeans.modules.editor.lib2.view.OffsetRegion.createPos(OffsetRegion.java:60)
at org.netbeans.modules.editor.lib2.view.OffsetRegion.create(OffsetRegion.java:36)
at org.netbeans.modules.editor.lib2.view.OffsetRegion.union(OffsetRegion.java:49)
at org.netbeans.modules.editor.lib2.view.ViewUpdates.viewFactoryChanged(ViewUpdates.java:356)
at jdk.internal.reflect.GeneratedMethodAccessor181.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.openide.util.WeakListenerImpl$ProxyListener.invoke(WeakListenerImpl.java:462)
at jdk.proxy17/jdk.proxy17.$Proxy53.viewFactoryChanged(Unknown Source)
at org.netbeans.modules.editor.lib2.view.EditorViewFactory.fireEvent(EditorViewFactory.java:235)
at org.netbeans.modules.editor.lib2.view.HighlightsViewFactory$1.run(HighlightsViewFactory.java:373)
at org.netbeans.editor.BaseDocument.render(BaseDocument.java:1407)
at org.netbeans.modules.editor.lib2.view.HighlightsViewFactory.highlightChanged(HighlightsViewFactory.java:347)
at jdk.internal.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.openide.util.WeakListenerImpl$ProxyListener.invoke(WeakListenerImpl.java:462)
at jdk.proxy17/jdk.proxy17.$Proxy51.highlightChanged(Unknown Source)
at org.netbeans.modules.editor.lib2.highlighting.DirectMergeContainer.highlightChanged(DirectMergeContainer.java:120)
at jdk.internal.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.openide.util.WeakListenerImpl$ProxyListener.invoke(WeakListenerImpl.java:462)
at jdk.proxy17/jdk.proxy17.$Proxy51.highlightChanged(Unknown Source)
at org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer.fireHighlightsChange(AbstractHighlightsContainer.java:88)
at org.netbeans.spi.editor.highlighting.support.OffsetsBag.setHighlights(OffsetsBag.java:282)
at org.netbeans.modules.java.editor.semantic.SemanticHighlighter$1$1.run(SemanticHighlighter.java:79)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
[catch] at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

```

### How to reproduce
```java
package com.sprucetec.owner.app.scmp.product.helper;

import com.sprucetec.owner.app.common.enums.YesOrNoEnum;
import com.sprucetec.owner.app.common.helper.ImageUrlHelper;
import com.sprucetec.owner.app.common.helper.ProductPlatformServiceHelper;
import com.sprucetec.owner.app.common.helper.sku.PmsCopySkuDetail;
import com.sprucetec.owner.app.common.helper.sku.attr.PmsAttrInfoDTO;
import com.sprucetec.owner.app.common.helper.sku.attr.PmsAttrValueInfoDTO;
import com.sprucetec.owner.app.common.helper.sku.attr.PmsCascadeAttrValueParam;
import com.sprucetec.owner.app.scmp.product.res.ProductTemplateFieldVo;
import com.sprucetec.owner.app.scmp.product.res.ProductTemplateVo;
import lombok.NonNull;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* Description 属性模板Helper
*
* @author haoshaolong
* @date 2023/5/19
*/
@Component
public class ProductAttrTemplateHelper {

@Autowired
private ProductPlatformServiceHelper pmsPlatHelper;
@Autowired
private ImageUrlHelper imageUrlHelper;

/**
* 根据biId获取属性模板
* @param biId 通用名Id
* @return
*/
public PmsAttrInfoDTO getAttrTemplateByBiId(@NonNull Long biId) {
PmsAttrInfoDTO attrInfo = pmsPlatHelper.getAttrTemplateByBiId(biId);
// 处理级联属性
if (attrInfo != null && CollectionUtils.isNotEmpty(attrInfo.getRelationAttrList())) {
Map child2Parent = attrInfo.getRelationAttrList().stream()
.collect(Collectors.toMap(PmsAttrInfoDTO.CascadeRelation::getChildAttrId, PmsAttrInfoDTO.CascadeRelation::getParentAttrId));
Map> parent2Children = attrInfo.getRelationAttrList().stream()
.collect(Collectors.groupingBy(PmsAttrInfoDTO.CascadeRelation::getParentAttrId,
Collectors.mapping(PmsAttrInfoDTO.CascadeRelation::getChildAttrId, Collectors.toList())));
this.buildAttrTemplateCascadeRelation(attrInfo.getCoreAttrListBean(), child2Parent, parent2Children);
this.buildAttrTemplateCascadeRelation(attrInfo.getDisplayAttrListBean(), child2Parent, parent2Children);
this.buildAttrTemplateCascadeRelation(attrInfo.getQualityAttrListBean(), child2Parent, parent2Children);
this.buildAttrTemplateCascadeRelation(attrInfo.getManagementAttrListBean(), child2Parent, parent2Children);
}
return attrInfo;
}

private void buildAttrTemplateCascadeRelation(List attrBeans,
Map child2Parent,
Map> parent2Children) {
if (CollectionUtils.isNotEmpty(attrBeans)) {
attrBeans.forEach(attrBean -> {
if (attrBean.getAttrId() != null) {
attrBean.setParentAttrId(child2Parent.get(attrBean.getAttrId()));
attrBean.setChildAttrIds(parent2Children.getOrDefault(attrBean.getAttrId(), Collections.emptyList()));
}
});
}
}

/**
* 填充属性值到模板
* @param biId
* @param attrInfo
* @param skuAttrValues
*/
public void fillAttrValueIntoTemplate(Long biId, PmsAttrInfoDTO attrInfo,
List skuAttrValues) {
// 查询属性值状态
PmsCascadeAttrValueParam param = new PmsCascadeAttrValueParam();
param.setBiId(biId);
param.setAttrList(skuAttrValues.stream().map(PmsCascadeAttrValueParam.AttrValueListParam::new).collect(Collectors.toList()));
List attrValueInfos = pmsPlatHelper.getCascadeValueStateWithBi(param);

Map attrValueMap = attrValueInfos.stream()
.collect(Collectors.toMap(PmsAttrValueInfoDTO::getAttrValueId, Function.identity()));
skuAttrValues.stream()
.filter(attr -> attr.getAttrValueId() != null && attr.getAttrValueId() != 0)
.forEach(attr -> {
PmsAttrValueInfoDTO attrValue = attrValueMap.get(attr.getAttrValueId());
if (attrValue == null) {
// 这种情况表示在中台没有查询到, 也认为是失效
attr.setAttrValueStatus(YesOrNoEnum.NO.getCode());
} else {
attr.setAttrValueStatus(attrValue.getState() == 1 ? YesOrNoEnum.YES.getCode() : YesOrNoEnum.NO.getCode());
}
});

// 把sku的属性值填充到最新模板中
this.buildLastAllSkuTemplateAttr(attrInfo.getCoreAttrListBean(), skuAttrValues);
this.buildLastAllSkuTemplateAttr(attrInfo.getDisplayAttrListBean(), skuAttrValues);
this.buildLastAllSkuTemplateAttr(attrInfo.getQualityAttrListBean(), skuAttrValues);
this.buildLastAllSkuTemplateAttr(attrInfo.getManagementAttrListBean(), skuAttrValues);
}

private void buildLastAllSkuTemplateAttr(List newAttrBeans,
List skuAttrValues) {
if (CollectionUtils.isEmpty(newAttrBeans) || CollectionUtils.isEmpty(skuAttrValues)) {
return;
}
Map map = skuAttrValues.stream().collect(Collectors.toMap(p -> p.getAttrId(), Function.identity()));
newAttrBeans.forEach(attrBean -> {
PmsCopySkuDetail.PSkuAttr oldAttr = map.get(attrBean.getAttrId().longValue());
boolean oldIsNull = oldAttr == null;
attrBean.setAttrValueId(oldIsNull ? null : oldAttr.getAttrValueId().intValue());
attrBean.setAttrValue(oldIsNull ? null : oldAttr.getAttrValue());
attrBean.setAttrValueStatus(oldIsNull ? null : oldAttr.getAttrValueStatus());
attrBean.setValueDesc(oldIsNull ? null : oldAttr.getValueDesc());
attrBean.setValueImg(oldIsNull ? null : imageUrlHelper.getImgStr(oldAttr.getValueImg()));
});
}

public static ProductTemplateVo buildTemplateVoFromDto(PmsAttrInfoDTO attrInfo) {
ProductTemplateVo vo = new ProductTemplateVo();
List coreAttrList = attrInfo.getCoreAttrListBean().stream()
.map(ProductAttrTemplateHelper::buildTemplateFiledVoFromDto).collect(Collectors.toList());
vo.setCoreAttrList(coreAttrList);
List displayAttrList = attrInfo.getDisplayAttrListBean().stream()
.map(ProductAttrTemplateHelper::buildTemplateFiledVoFromDto).collect(Collectors.toList());
vo.setDisplayAttrList(displayAttrList);
List managementAttrList = attrInfo.getManagementAttrListBean().stream()
.map(ProductAttrTemplateHelper::buildTemplateFiledVoFromDto).collect(Collectors.toList());
vo.setManagementAttrList(managementAttrList);
List qualityAttrList = attrInfo.getQualityAttrListBean().stream()
.map(ProductAttrTemplateHelper::buildTemplateFiledVoFromDto).collect(Collectors.toList());
vo.setQualityAttrList(qualityAttrList);
List concatCspuAttrList = attrInfo.getConcatCspuAttrListBean().stream()
.map(ProductAttrTemplateHelper::buildTemplateFiledVoFromDto).collect(Collectors.toList());
vo.setConcatCspuAttrList(concatCspuAttrList);
return vo;
}

public static ProductTemplateFieldVo buildTemplateFiledVoFromDto(PmsAttrInfoDTO.AttrBean attrBean) {
return ProductTemplateFieldVo.builder()
.attrId(attrBean.getAttrId())
.attrCode(attrBean.getAttrCode())
.attrName(attrBean.getAttrName())
.attrGroupId(attrBean.getAttrGroupId())
.attrValue(attrBean.getAttrValue())
.attrValueId(attrBean.getAttrValueId())
.inputType(attrBean.getInputType())
.isMust(attrBean.getIsMust())
.isShow(attrBean.getIsShow())
.isCustom(attrBean.getIsCustom())
.parentAttrId(attrBean.getParentAttrId())
.childAttrIds(attrBean.getChildAttrIds())
.build();
}

}

```

### Did this work correctly in an earlier version?

No / Don't know

### Operating System

windows11

### JDK

java17

### Apache NetBeans packaging

Apache NetBeans provided installer

### Anything else

_No response_

### Are you willing to submit a pull request?

No

Contributor guide

Open the contributing guide

Research direction

Start with the reproduced Java file and the stack-trace entry points in EditorDocumentContent, OffsetRegion, ViewUpdates, and HighlightsViewFactory. Reproduce the BadLocationException in Apache NetBeans 17, then trace how the -1 offset reaches OffsetRegion.createPos. Done means the reported formatting scenario no longer produces the exception and the editor remains usable.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.