Published in 2019-05-232020-03-03 author Ryan
The landlord is happily in the deployment environment today, downloading JDK, packaging the project and uploading it to the server.
Configure JDK, package and upload the project, the landlord will not repeat here, and the readers will solve it by themselves!
1. Start the project
java -jar xxxx.jar
What the landlord didn't expect is that the program card is in the location where the database connection is established. (viewing method: jstack < PID >)
2. Stack information
Since the project has just started, the database connection pool is initialized, and there is not much thread stack. Here I post the stack information of the main problems I encountered:
"restartedMain" #11 prio=5 os_prio=0 tid=0x00007f4430002800 nid=0x65b0 runnable [0x00007f447837a000] java.lang.Thread.State: RUNNABLE at java.io.FileInputStream.readBytes(Native Method) at java.io.FileInputStream.read(FileInputStream.java:255) at sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539) at sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:144) at sun.security.provider.SecureRandom$SeederHolder.<clinit>(SecureRandom.java:203) at sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:221) - locked <0x00000000d6eb8930> (a sun.security.provider.SecureRandom) at java.security.SecureRandom.nextBytes(SecureRandom.java:468) at oracle.security.o5logon.O5Logon.a(Unknown Source) at oracle.security.o5logon.O5Logon.<clinit>(Unknown Source) at oracle.jdbc.driver.T4CTTIoauthenticate.<init>(T4CTTIoauthenticate.java:566) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:370) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
Maybe you ask me, why do you want to locate this thread? This is mainly because after several jstack operations, Taoist friends found that the thread has always stayed at this position, which is enough to show that this thread is the current thread!
3. Analyze stack information
From the above stack information, what information can we know?
- The current thread name is: restartedMain
- The current thread status is: RUNNABLE
- Current thread ID: 0x00007f4430002800
- native thread ID: 0x65b0
- Current running location: at java.io.FileInputStream.readBytes(Native Method)
By analyzing the stack, there must be no problem reading the file. We trace to the upper layer of the thread stack. The target point falls on
at sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539)
Obviously, here is the call of jdk source code. Next, punch in the jdk source code to check!
4. Source code analysis
We follow up the source code step by step through the stack information,


From the perspective of the method nextBytes, it is called to generate the random number of bytes specified by the user. Well, when it is generated, it needs to read a file to generate random numbers.
5. Write a test to verify the idea
[ryan@ryanmacbook ~]$ vim HelloWorld.java import java.security.SecureRandom; class HelloWorld { public static void main(String args[]) throws Exception { byte[] bytes = new byte[32]; SecureRandom.getInstance("SHA1PRNG").nextBytes(bytes); System.out.println("SourceRandom nextBytes : " + new String(bytes)); } }
Followed by execution
javac HelloWorld.java
If you don't, you can give up java. The java world may not be suitable for you.
Next execution
java HelloWorld
After execution, the result is
[ryan@ryanmacbook ~]$ java HelloWorld ^C
[ryan@ryanmacbook ~]
$
It's stuck. The landlord forced kill.
That's our problem.
Next, what is the solution? You have to ask the landlord. The landlord doesn't know. What should I do? Go to Baidu. Programmers who can't use Baidu are not good programmers:
6. Solutions
The final solution is to modify java.security.egd when the project is started. The professional term is called entropy pool policy as follows:
java -Djava.security.egd=file:/dev/urandom HelloWorld
The essence of the problem is whether SecureRandom.nextBytes() is invoked in the Oracle driver class. The landlord hasn't had time to see if other drivers also have this problem. Of course, it doesn't rule out that it has something to do with the operating system. Supplement after verifying other operating systems!
Decisive success!
Taoist friends checked it and said it was a JVM bug. It was caused by not collecting all the noise when collecting it. If you also encounter such problems, sometimes available and sometimes unavailable, it is the problem of noise collection.
[reference link] http://ifeve.com/jvm-random-and-entropy-source/