java.util.AbstractList.add의 UnsupportedOperationException

lottogame 2020. 12. 28. 07:44

java.util.AbstractList.add의 UnsupportedOperationException

코드 블록이 제대로 실행되는 데 문제가 있습니다. 이 코드가 무엇을하는지 잘 모르겠습니다 (서버에서 제대로 작동하기 위해 오래된 플러그인을 얻으려고합니다). 20 분마다 실행되고 오류가 발생한다는 것을 알고 있습니다. 다음은 문제가 발생하는 코드 섹션입니다.

public class DynamicThread extends Thread {
private LocalShops plugin = null;

public DynamicThread(ThreadGroup tgroup, String tname, LocalShops plugin) {
    super(tgroup, tname);
    this.plugin = plugin;

public void run() {
    Map<ItemInfo, List<Integer>> itemStockMap = Collections.synchronizedMap(new HashMap<ItemInfo, List<Integer>>());

    //Dump all the shop stock data into the map.
    for ( Shop shop : plugin.getShopManager().getAllShops() ) {
        for ( InventoryItem item : shop.getItems() ) {
            if (itemStockMap.containsKey(item.getInfo()))
                itemStockMap.get(item.getInfo()).add(item.getStock()); //Where error happens
                itemStockMap.put(item.getInfo(), Arrays.asList(item.getStock()));     
    for(ItemInfo item : itemStockMap.keySet()) {
        List<Integer> stockList = GenericFunctions.limitOutliers(itemStockMap.get(item));
        //remove the map before re-adding it
        if (DynamicManager.getPriceAdjMap().containsKey(item)) 

        //Get the overall stock change for a given item and then calculate the adjustment given the volatility
        int deltaStock = GenericFunctions.getSum(stockList) - Config.getGlobalBaseStock();
        DynamicManager.getPriceAdjMap().put(item, GenericFunctions.getAdjustment(Config.getGlobalVolatility(), deltaStock)); 

    Bukkit.getServer().getScheduler().callSyncMethod(plugin, plugin.getShopManager().updateSigns());


오류는 42 행에서 발생합니다.


출력되는 오류는 20 분마다 두 번 2 초 사이에 발생합니다.

2012-02-16 16:53:25 [INFO] Launch Dynamic Thread
2012-02-16 16:53:25 [SEVERE] Exception in thread "dynamic" 
2012-02-16 16:53:25 [SEVERE] java.lang.UnsupportedOperationException
2012-02-16 16:53:25 [SEVERE] at java.util.AbstractList.add(
2012-02-16 16:53:25 [SEVERE] at java.util.AbstractList.add(
2012-02-16 16:53:25 [SEVERE] at

2012-02-16 16:53:27 [INFO] Launch Dynamic Thread
2012-02-16 16:53:27 [SEVERE] Exception in thread "dynamic" 
2012-02-16 16:53:27 [SEVERE] java.lang.UnsupportedOperationException
2012-02-16 16:53:27 [SEVERE] at java.util.AbstractList.add(
2012-02-16 16:53:27 [SEVERE] at java.util.AbstractList.add(
2012-02-16 16:53:27 [SEVERE] at

도움을 주셔서 미리 감사드립니다.

여기 Arrays.asList()에서 목록을 만드는 데 사용 하고 Map있습니다.

itemStockMap.put(item.getInfo(), Arrays.asList(item.getStock()));  

이 메서드는 List배열에 의해 지원되는 크기 조정 불가능을 반환합니다 . 해당 방법의 문서에서 :

지정된 배열이 지원하는 고정 크기 목록을 반환합니다. (반환 된 목록을 "write through"배열로 변경합니다.)

In order to use a resizable List (and actually copy the contents), use the following:

        new ArrayList<Integer>(Arrays.asList(item.getStock()))

Note: in general, when seeing that UnsupportedOperationException is being thrown by add, etc. it's typically an indication that some code is trying to modify a non-resizable or unmodifiable collection.

For example, Collections.emptyList or Collections.singletonList (which return unmodifiable collections) may be used as optimizations but accidentally be passed into methods that try to modify them. For this reason it's good practice for methods to make defensive copies of collections before modifying them (unless of course modifying the collection is a method's intended side effect) - that way callers are free to use the most appropriate collection implementation without worrying about whether it needs to be modifiable.

I think I've worked out your problem. Arrays.asList(item.getStock()) returns a fixed size list based on the Array passed to it.

This means you cannot add more elements to it.

Instead you should do new ArrayList(Arrays.asList(item.getStock())).

This way you are creating a new list that you can add to.

The problem is you are creating your lists with Arrays.asList. Per the javadoc provided, the returned list is a Fixed Size, therefore add would be unsupported. Wrap the returned list in a copy constructor for arrayList and you should be set.

List is Interface and you can not Add value in it until it is instance of ArrayList(interface should be implemented by some class)

For Example:

    List<Integer> test = new ArrayList<>();
    test.add(new Integer(2));

    ArrayList<Integer> test2 = new ArrayList<>();
    test2.add(new Integer(2));

    List<Integer> test3 = Collections.EMPTY_LIST;
    test3.add(new Integer(2));

Here Object test and test2 are perfect, because they are object of ArrayList class so addition is possible
While in test3 it is just empty list so you can not add element in it.

I was also doing the same mistake.

Here is my Suggestion Use ArrayList when you have to do operations like add or remove, Use List only for reference purpose.

 Map<ItemInfo, ArrayList<Integer>> itemStockMap = Collections.synchronizedMap(new HashMap<ItemInfo, ArrayList<Integer>>());

The problem is in the class of the list object that is returned by the get call. It doesn't override the add methods appropriately, and your code is therefore using the placeholder method provided by AbstractList.

There's not much more we can say without knowing what the list class is, and (if it is custom code) seeing the source code.

In my case I had used:

List<File> removeFilesList= Collections.emptyList();

which made my File arraylist abstract. Used instead:

List<File> removeFilesList= new ArrayList<>();

And the error was fixed.

ReferenceURL :