Tag Archives: java

Java container — unsupported operation exception

Let’s take an example

importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.Collection;
importjava.util.Collections;
importjava.util.List;

publicclassUnsupportedOperation{
staticvoidtest(Stringmsg,List<String>list){
System.out.println("----------"+msg+"----------");
Collection<String>c=list;
Collection<String>subList=list.subList(1,4);
Collection<String>subList2=newArrayList<>(subList);
try{c.retainAll(subList2);}catch(Exceptione){
System.out.println("retainAll:"+e);
}
try{c.removeAll(subList2);}catch(Exceptione){
System.out.println("removeAll:"+e);
}
try{c.clear();}catch(Exceptione){
System.out.println("clear:"+e);
}
try{c.add("X");}catch(Exceptione){
System.out.println("add:"+e);
}
try{c.addAll(subList2);}catch(Exceptione){
System.out.println("addAll:"+e);
}
try{c.remove("C");}catch(Exceptione){
System.out.println("remove:"+e);
}
try{list.set(0,"W");}catch(Exceptione){
System.err.println("List.set:"+e);
}
System.out.println("List.className="+list.getClass().getSimpleName());
}
publicstaticvoidmain(String[]args){
List<String>list=Arrays.asList("ABCDEFG".split(""));
test("ModifiableCopy",newArrayList<String>(list));
test("Arrays.asList",list);
test("UnmodifiableList",Collections.unmodifiableList(list));
}
}

Implementation results:

----------ModifiableCopy----------
List.className=ArrayList
----------Arrays.asList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.className=ArrayList
----------UnmodifiableList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.set:java.lang.UnsupportedOperationException
List.className=UnmodifiableRandomAccessList

So why did this happen?It’s easy to understand that the unmodifiable list can’t be modified, but you can see from the results that it’s also ArrayList. Why can’t the list returned by array. Aslist() be modified

Arrays. Aslist() will generate a list, which is based on a fixed size array and only supports those operations that will not change the size of the array. Any method that changes the size of the underlying data structure will produce an unsupported operation exception to indicate the call to the unsupported operation

In fact, in the above code, I deliberately use getsimplename (), because this method will not display the package name. If we will

System.out.println("List.className="+list.getClass().getSimpleName());

Replace with:

System.out.println("List.className="+list.getClass().getName());

So here’s the result:

----------ModifiableCopy----------
List.className=java.util.ArrayList
----------Arrays.asList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.className=java.util.Arrays$ArrayList
----------UnmodifiableList----------
retainAll:java.lang.UnsupportedOperationException
removeAll:java.lang.UnsupportedOperationException
clear:java.lang.UnsupportedOperationException
add:java.lang.UnsupportedOperationException
addAll:java.lang.UnsupportedOperationException
remove:java.lang.UnsupportedOperationException
List.className=java.util.Collections$UnmodifiableRandomAccessList
List.set:java.lang.UnsupportedOperationException

As you can see, although the name returned by arrays.aslist is called ArrayList, this ArrayList is an internal class in arrays, not java.util.arraylist

Looking at the source code, you can find that the declaration of the internal class of arrays.arraylist is as follows:

privatestaticclassArrayList<E>extendsAbstractList<E>
implementsRandomAccess,java.io.Serializable

In the implementation of this class, there is no method to modify the E [] array (add, delete, clear, etc.)

Therefore, when these methods are called on this kind of object, the implementation of its parent class abstractlist will be called, so the unsupported operation exception is thrown directly

Therefore, it is a common practice for to pass the results of arrays. Aslist() to any collection (or use addall() method or collection. Addall() static method) as the parameters of the construction method, so as to generate a general container that allows all methods to be used — this is shown in the first call to test() in main(), Such a call will produce a new size adjustable underlying data structure the “immutable” method of the collections class wraps the container into an agent. As long as you perform any operation that attempts to modify the container, the agent will generate an unsupported operationexception . The goal of using these methods is to produce “constant” container objects

The last try statement block in test () checks the set () method as part of the list. Arrays. Aslist() returns a fixed size list, while collections. Unmodifiable list() produces a list that cannot be modified. As you can see from the output, it’s OK to modify the elements in the list returned by arrays. Aslist(), because it doesn’t violate the “fixed size” feature. But obviously, the result of unmodifiablelist () is not modifiable in any case

————————————————————–

operations that throw exceptions like the above are called “unsupported operations” in Java containers. So why are methods defined as optional?That’s because it can prevent interface explosion in the design. To make this work:

1. Unsupported operation exception must be a rare event. That is, for most classes, all operations should work, only in special cases. This is true in Java containers, because the container classes you use 99% of the time, such as ArrayList, LinkedList, HashSet, HashMap, and other specific implementations, support all operations

2. If an operation is not supported, it may lead to an unsupported operation exception when the interface is implemented, rather than an exception after the product is delivered to the customer. This is reasonable. After all, it indicates a programming error: an incorrect interface implementation is used

It is worth noting that such operations can only be detected at run time

NoClassDefFoundError: Failed resolution of: Lorg/apache/http/conn/scheme/SchemeRegistry;

When the Android project is running on Android 9.0, it will flash back and report the following error

Java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/conn/scheme/SchemeRegistry;

terms of settlement:

Add the

<uses-library android:name="org.apache.http.legacy" android:required="false" />

Contribution by aizier River

How to Solve Error: Failed to execute goal on project

Problem description

There is a mistake in the idea install module. After reading the console information, it is estimated that it is a dependency problem

[ERROR] Failed to execute goal on project 
xxx.yyy.share: Could not resolve dependencies for project 
com.dfl:xxx.yyy.zzz:jar:1.0-SNAPSHOT: 
Failure to find com.xxx:xxx-target:pom:1.0-SNAPSHOT in https://xxxx/snapshot 
was cached in the local repository, 
resolution will not be reattempted until the update interval of spring-snapshots has elapsed or updates are forced -> [Help 1]

Analysis and solution

From the log information, we can see that the zzz module can’t find the jar package, which comes from the target module and can’t be found in the local warehouse or private server.

It is speculated that the jar of private server warehouse is expired or deleted.

So I went to ask the boss, and sure enough, the jar of private server’s warehouse was deleted, so that the boss could deploy it again.

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilder

http://maven.aliyun.com/nexus/content/groups/public/ , the warehouse address is updated to HTTPS, so SSL authentication is required when downloading. We can ignore the problems caused by SSL check. We can directly ignore the check by using the command:
open the terminal under the project path command:

mvn clean install -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

I tried this, but it didn’t work

I’ve tried the following one. It’s OK

-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true

Solve the error of springboot failed to load ApplicationContext

Springboot uses version 2.1.4

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
//@ContextConfiguration(value = {"classpath*:application.yml","classpath*:logback-spring.xml"})
public class LoggerTest {

    private final Logger logger = LoggerFactory.getLogger(LoggerTest.class);

    @Test
    public void test(){
        String name="zhangsan";
        String password = "123";
        logger.debug("ggggg");
        logger.error("ddddd");
        logger.info("ffff");
        logger.info("name: {},password: {}",name,password);
    }

}

During unit testing, springboot always reports an error when starting

Failed to load ApplicationContext

So all kinds of search data are basically due to the need to add the annotation:

(1)@ContextConfiguration(locations= {“classpath*:application.yml”,”classpath*:logback-spring.xml”})

(2) Or the configuration file in the annotation is not added completely

(3) Or the path of the annotation configuration file is wrong.

My profile path is as follows:

Only these two, the path is right, but has been throwing red report error.

Later, I thought that there might be other reasons, so I annotated the annotation and retested it. It was found that although the error was still failed to load ApplicationContext, the information of caused by error was as follows:

Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]  
……..
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when ‘hibernate.dialect’ not set

The error message should be related to the hibernate.dialect configuration of the configuration file, so try to modify the configuration file:

Add database platform in spring.datasource.jpa: org.hibernate.dialect.mysql5innodbdialect

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/selling?characterEncoding=utf-8&useSSL=false
  jpa:
    show-sql: true
    database-platform: org.hibernate.dialect.H2Dialect
  jackson:
    default-property-inclusion: non_null
  redis:
    host: 127.0.0.1
    port: 6379

Run again, success!

When testing another method, an error is reported:

Table ‘selling.hibernate_ sequence’ doesn’t exist

This kind of primary key is set to self growth, plus the following strategies:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer categoryId;

 

Failed to retrieve application JMX service URL

When starting a spring cloud project, the event log reports two messages:

13:08	All files are up-to-date

13:08	XxxWebApplication: Failed to retrieve application JMX service URL

An article gives a solution:
toolbar – edit configurations – spring boot:
restart will not report “failed to retrieve application JMX service URL” error.


How to make “all files are up-to-date” not display?This problem has not been solved. If you know how to solve it, please let me know~

Failed to start docker.service: Unit not found(Docker service does not start)

Linux deployment docker appears: failed to start docker.service : unit not found
linux has deployed k8s and other projects before, Some of the remaining dockers are damaged
after re installation, the service always fails: failed to start docker.service : unit not found
warning: if applicable to my situation, it needs to be reinstalled

solution:
Direct Yum update
be sure to restart Linux
Yum install docker
systemctl start docker.service

Springboot start error: protocol handler start failed

Problem Description:
in the process of migrating the old project functions to the new reconstructed project, the protocol handler start failed error is reported when starting the new reconstructed project 👇

Protocol handler start failed

Error reason:
port number conflict

The problem is that the Eureka is started when the old project is started to view the interface data. When the new project is started, the Eureka of the old project is not closed, but another Eureka is re opened, resulting in port conflict.

Solution:
Close Eureka of the old project!

Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1

Background: JDK1.8 is used in this project

The following error occurred when compiling Maven project:

Failed to execute goal org.apache.maven.plugins :maven-compiler- plugin:3.1

The Maven plug-in is configured in POM as follows, and JDK1.8 is declared in the configuration:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>3.1</version>
	<configuration>
		<verbose>true</verbose>
		<fork>true</fork>
		<executable>${JAVA8_HOME}/bin/javac</executable>
	</configuration>
</plugin>

Here’s ${java8_ The variable home} is in the settings.xml The configuration is as follows:

<profile>
            <id>custom-compiler</id>
            <properties>
                <JAVA8_HOME>C:\Program Files (x86)\Java\jdk1.8.0_73</JAVA8_HOME>
            </properties>
</profile>

Of course, it should be activated here, so settings.xml The file should also have the following configuration:

<activeProfiles>
        <activeProfile>custom-compiler</activeProfile>
</activeProfiles>

From the POM file, click Ctrl on the variable java8_ Home can jump to settings.xml To find its definition, it should be able to find the variable. The above problem is not because the variable cannot be found. I will add Java 8 in POM file_ The variable home is directly replaced by the actual path, that is, by

C:\Program Files (x86)\Java\jdk1.8.0_73\bin\javac

It’s strange to find that the compilation passed.

Reasons for disclosure:

Maven actually has a default warehouse. M2 warehouse and default warehouse settings.xml Configuration file, we are in this default settings.xml A Java 8 is also added to the file_ After the variables of home are compiled, they are passed. This means that when Maven is compiled, it is not my custom variables that I configured in idea settings.xml It’s the default one. Because there is no java8 in it, we can’t find it before_ Home, resulting in compilation failure

Summary: Maven should be found first when compiling settings.xml If it can’t be found, I will go to the “user settings file” configured under the settings option of idea settings.xml Documents.

Solution: delete the one Maven is looking for by default settings.xml In this way, the customized file will take effect

 

Concurrent notes (4): Notes on the use of wait / notify / notifyAll method

1: Why must wait be used in synchronized protected synchronization code?

The introduction of wait method in the source code is as follows:

        /**
         * As in the one argument version, interrupts and spurious wakeups are
         * possible, and this method should always be used in a loop:
         * <pre&>
         *     synchronized (obj) {
         *         while (&lt;condition does not hold&>)
         *             obj.wait();
         *         ... // Perform action appropriate to condition
         *     }
         * </pre&>
         * This method should only be called by a thread that is the owner
         * of this object's monitor. See the {@code notify} method for a
         * description of the ways in which a thread can become the owner of
         * a monitor.
         *
         */
        public final void wait() throws InterruptedException {
            wait(0);
        }

That is to say, when using the wait method, you must write the wait method in the synchronized protected while code block, and always judge whether the execution conditions are met. If the execution conditions are met, continue to execute. If not, execute the wait method. Before executing the wait method, you must hold the monitor of the object Lock, also known as synchronized lock .

1.1 what would be the problem of not doing so?

    class BlockingQueue{

        Queue<String&> buffer = new LinkedList<&>();
        public void give(String data){
            buffer.add(data);
            notify();
        }
        public String take() throws InterruptedException {
            while(buffer.isEmpty()){
                wait();
            }
            return buffer.remove();
        }
    }

In the code, we can see that there are two methods. The give method is responsible for adding data to the buffer. After adding, the notify method is executed to wake up the waiting thread. The take method is responsible for checking whether the whole buffer is empty. If it is empty, it will enter the waiting process. If it is not empty, it will take out a data. This is a typical idea of producers and consumers.

If you don’t use the wait () method correctly in the code shown above, what exception might occur?

First, the consumer thread calls the take method and determines whether the buffer.isEmpty Method returns true. If true, it means that the buffer is empty, then the thread wants to wait, but before the thread calls the wait method (while)( buffer.isEmpty After ()), it is suspended by the scheduler, so there is no time to execute the wait method .

At this time, the producer starts to run and executes the whole give method. It adds data to the buffer and executes the notify method, but the notify method has no effect, because the wait method of consumer thread has not been executed in time, so no thread is waiting to be awakened .

At this time, the consumer thread that has just been suspended by the scheduler comes back to continue to execute the wait method and enters the waiting . At this time, the consumer may fall into endless waiting, because it missed the wake-up of notify in the give method.

PS: the scheduler mentioned above pauses threads, because in multithreading, CPU scheduling is based on time slices, and each thread can get a certain amount of time slices. But if the thread runs out of time slices, it will be suspended and give up CPU resources to other threads. The “judgment execution” in the code is not an atomic operation. It may be interrupted in the middle, which is unsafe for the thread. Therefore, the thread may be suspended before calling the wait method.

1.2 correct use of wait() method

    class BlockingQueue{
        Queue<String&> buffer = new LinkedList<&>();
        public void give(String data){
            synchronized (this){
                buffer.add(data);
                notify();
            }
        }
        public String take() throws InterruptedException {
            synchronized (this){
                while(buffer.isEmpty()){
                    wait();
                }
                return buffer.remove();
            }
        }
    }

This ensures that the notify method never runs in the buffer . Isempty and wait methods are called to improve the security of the program. In addition, the wait method will release the monitor lock, which also requires that we must first enter into synchronized to hold the lock.

one . two . The problem of false wake-up can be avoided by using while structure judgment

The thread may not have been notified/NotifyAll is also waked up without interruption or timeout, which we don’t want to see. However, in actual production, the probability of false wake-up is very small, but the program still needs to ensure the correctness of false wake-up, so it needs to adopt the structure of while loop.

while(conditiondoesnothold)
obj.wait();

In this way, even if it is falsely awakened, it will check the conditions in while again. If the conditions are not met, it will continue to wait, which eliminates the risk of false wake-up.

2: Similarities and differences between wait and sleep

2.1 similarities

they all block threads

All of them can respond to interrupt : in the process of waiting, if an interrupt signal is received, they can respond and throw interruptedexception exception.

2.2 differences

The wait method must be used in synchronized protected code, but the sleep method does not have this requirement .

when the sleep method is executed in the synchronization code, the monitor lock will not be released, but when the wait method is executed, the monitor lock will be released actively .

The sleep method requires that a time must be defined, and the time will be actively restored when it is expired. For the wait method without parameters, it means that it will wait forever until it is interrupted or awakened, and it will not be actively restored.

wait/notify/notifyAll is defined in the object class, while sleep is defined in the thread class .

2.2.1 why is wait/notify/notifyAll defined in the object class and sleep defined in the thread class?

First of all, because every object in Java has a lock called monitor monitor, every object can be locked, and there is a location in the object header to store the lock information. This lock is at the object level, not the thread level. Wait/notify/notifyAll are also lock level operations. Their locks belong to objects, so it is most appropriate to define them in the object class, because the object class is the parent of all objects.

Secondly, a thread may hold multiple locks in order to realize the complex logic of cooperation. Since we are asking the current thread to wait for the lock of an object, we should naturally operate the object instead of the thread.