[长期更新]java问题列表

Posted by 梁远鹏 on 2023-05-04 | 阅读 |,阅读约 7 分钟

TOC

说明

本文主要收集 java 遇到的一些常见问题,欢迎对本文进行投稿你认为好的场景或问题.

问题来了

使用 jdk17 时立刻堆栈报错提示内存不足

VM Arguments:
jvm_args: -Xmx1G -XX:+UnlockExperimentalVMOptions -XX:ErrorFile=/usr/local/lan/logs/parser/hs_err.log -XX:HeapDumpPath=/usr/local/lan/dumps/parser 
java_command: com.lan.parser.YdcApplication
java_class_path (initial): /usr/local/tomcat/webapps/ROOT/resources:/usr/local/tomcat/webapps/ROOT/classes:/usr/local/tomcat/webapps/ROOT/libs/aircompressor-0.20.jar:/usr/local/tomcat/webapps/ROOT/libs/pagehelper-spring-boot-autoconfigure-1.2.12.jar:/usr/local/tomcat/webapps/ROOT/libs/commons-pool2-2.9.0.jar:/usr/local/tomcat/webapps/ROOT/libs/persistence-api-1.0.jar:/usr/local/tomcat/webapps/ROOT/libs/jersey-common-2.32.jar:/usr/local/tomcat/webapps/ROOT/libs/spring-oxm-5.3.13.jar:/usr/local/tomcat/webapps/ROOT/libs/feign-slf4j-10.12.jar:/usr/local/tomcat/webapps/ROOT/libs/jakarta.inject-api-2.0.1.jar:/usr/local/tomcat/webapps/ROOT/libs/json-20180130.jar:/usr/local/tomcat/webapps/ROOT/libs/jersey-client-2.32.jar:/usr/local/tomcat/webapps/ROOT/libs/opentelemetry-context-1.17.0.jar:/usr/local/tomcat/webapps/ROOT/libs/logback-classic-1.2.7.jar:/usr/local/tomcat/webapps/ROOT/libs/micrometer-registry-otlp-1.9.4.jar:/usr/local/tomcat/webapps/ROOT/libs/j2objc-annotations-1.1.jar:/usr/local/tomcat/webapps/ROOT/libs/netty-transport-native-unix-common-4.1.70.Final.jar:/usr/local/tomcat/webapps/ROOT/libs/netty-handler-proxy-4.1.70.Final.jar:/usr/local/tomcat/webapps/ROOT/libs/mysql-connector-java-5.1.42.jar:/usr/local/tomcat/webapps/ROOT/libs/druid-spring-boot-starter-1.2.11.jar:/usr/local/tomcat/webapps/ROOT/libs/commons-codec-1.15.jar:/usr/local/tomcat/webapps/ROOT/libs/slf4j-api-1.7.32.jar:/usr/local/tomcat/webapps/ROOT/libs/jcip-annotations-1.0.jar:/usr/local/tomcat/webapps/ROOT/libs/druid-1.2.11.jar:/usr/local/tomcat/webapps/ROOT/libs/commons-math3-3.6.1.jar:/usr/local/tomcat/webapps/ROOT/libs/snappy-java-1.1.8.4.jar:/usr/local/tomcat/webapps/ROOT/libs/pulsar-client-api-2.10.0.jar:/usr/local/tomcat/webapps/ROOT/libs/opentelemetry-proto-0.16.0-alpha.jar:/usr/local/tomcat/webapps/ROOT/libs/metrics-core-4.1.26.jar:/usr/local/tomcat/webapps/ROOT/libs/hivemq-mqtt-client-1.2.0.jar:/usr/local/tomcat/webapps/ROOT/libs/spring-webmvc-5.3.13.jar:/usr/local/tomcat/webapps/ROOT/lib
Launcher Type: SUN_STANDARD

[Global flags]
     intx CICompilerCount                          = 2                                         {product} {ergonomic}
     uint ConcGCThreads                            = 1                                         {product} {ergonomic}
    ccstr ErrorFile                                = /usr/local/lan/logs/parser/hs_err.log            {product} {command line}
     uint G1ConcRefinementThreads                  = 2                                         {product} {ergonomic}
     uint G1EagerReclaimRemSetThreshold            = 8                                    {experimental} {ergonomic}
   size_t G1HeapRegionSize                         = 1048576                                   {product} {ergonomic}
    uintx GCDrainStackTargetSize                   = 64                                        {product} {ergonomic}
    ccstr HeapDumpPath                             = /usr/local/lan/dumps/parser         {manageable} {command line}
   size_t InitialHeapSize                          = 130023424                                 {product} {ergonomic}
   size_t MarkStackSize                            = 4194304                                   {product} {ergonomic}
   size_t MaxHeapSize                              = 1073741824                                {product} {command line}
   size_t MinHeapDeltaBytes                        = 1048576                                   {product} {ergonomic}
   size_t MinHeapSize                              = 8388608                                   {product} {ergonomic}
    uintx NonNMethodCodeHeapSize                   = 5826188                                {pd product} {ergonomic}
    uintx NonProfiledCodeHeapSize                  = 122916026                              {pd product} {ergonomic}
    uintx ProfiledCodeHeapSize                     = 122916026                              {pd product} {ergonomic}
    uintx ReservedCodeCacheSize                    = 251658240                              {pd product} {ergonomic}
     bool SegmentedCodeCache                       = true                                      {product} {ergonomic}
   size_t SoftMaxHeapSize                          = 1073741824                             {manageable} {ergonomic}
     bool UnlockExperimentalVMOptions              = true                                 {experimental} {environment}
     bool UseCompressedClassPointers               = true                           {product lp64_product} {ergonomic}
     bool UseCompressedOops                        = true                           {product lp64_product} {ergonomic}
     bool UseFastUnorderedTimeStamps               = true                                 {experimental} {ergonomic}
     bool UseG1GC                                  = true                                      {product} {ergonomic}

Logging:
Log output configuration:
 #0: stdout all=warning uptime,level,tags
 #1: stderr all=off uptime,level,tags

Environment Variables:
JAVA_HOME=/opt/java/openjdk
JAVA_TOOL_OPTIONS=-Xmx1G -XX:+UnlockExperimentalVMOptions
PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
TZ=Asia/Shanghai

Signal Handlers:
   SIGSEGV: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
    SIGBUS: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
    SIGFPE: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
   SIGPIPE: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
   SIGXFSZ: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
    SIGILL: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
   SIGUSR2: SR_handler in libjvm.so, mask=00000000000000000000000000000000, flags=SA_RESTART|SA_SIGINFO
    SIGHUP: SIG_DFL, mask=00000000000000000000000000000000, flags=none
    SIGINT: SIG_DFL, mask=00000000000000000000000000000000, flags=none
   SIGTERM: SIG_DFL, mask=00000000000000000000000000000000, flags=none
   SIGQUIT: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO
   SIGTRAP: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO


---------------  S Y S T E M  ---------------

OS:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"
uname: Linux 3.10.0-1160.71.1.el7.x86_64 #1 SMP Tue Jun 28 15:37:28 UTC 2022 x86_64
OS uptime: 32 days 20:11 hours
libc: glibc 2.35 NPTL 2.35 
rlimit (soft/hard): STACK 8192k/infinity , CORE infinity/infinity , NPROC infinity/infinity , NOFILE 1048576/1048576 , AS infinity/infinity , CPU infinity/infinity , DATA infinity/infinity , FSIZE infinity/infinity , MEMLOCK 64k/64k
load average: 10.92 11.49 11.05

/proc/meminfo:
MemTotal:        8008932 kB
MemFree:          990724 kB
MemAvailable:    1427868 kB
Buffers:           19560 kB
Cached:           813384 kB
SwapCached:       113108 kB
Active:          3917744 kB
Inactive:        2723696 kB
Active(anon):    3674760 kB
Inactive(anon):  2198536 kB
Active(file):     242984 kB
Inactive(file):   525160 kB
Unevictable:           4 kB
Mlocked:               4 kB
SwapTotal:       8388604 kB
SwapFree:        4455608 kB
Dirty:              4816 kB
Writeback:             0 kB
AnonPages:       5774248 kB
Mapped:           170672 kB
Shmem:             64744 kB
Slab:             177808 kB
SReclaimable:     129676 kB
SUnreclaim:        48132 kB
KernelStack:       18496 kB
PageTables:        32676 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    12393068 kB
Committed_AS:   13919420 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       23220 kB
VmallocChunk:   34359683124 kB
Percpu:             1064 kB
HardwareCorrupted:     0 kB
AnonHugePages:   1767424 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      106368 kB
DirectMap2M:     4087808 kB
DirectMap1G:     6291456 kB

/sys/kernel/mm/transparent_hugepage/enabled: [always] madvise never
/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter): [always] madvise never

Process Memory:
Virtual Size: 1450120K (peak: 1450120K)
Resident Set Size: 11900K (peak: 11900K) (anon: 5904K, file: 5996K, shmem: 0K)
Swapped out: 0K
C-Heap outstanding allocations: 6701K, retained: 66K
glibc malloc tunables: (default)

/proc/sys/kernel/threads-max (system-wide limit on the number of threads): 999999
/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have): 65530
/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers): 32768

container (cgroup) information:
container_type: cgroupv1
cpu_cpuset_cpus: 0-1
cpu_memory_nodes: 0
active_processor_count: 2
cpu_quota: no quota
cpu_period: 100000
cpu_shares: no shares
memory_limit_in_bytes: unlimited
memory_and_swap_limit_in_bytes: unlimited
memory_soft_limit_in_bytes: unlimited
memory_usage_in_bytes: 6124 k
memory_max_usage_in_bytes: 6124 k
maximum number of tasks: unlimited
current number of tasks: 1

KVM virtualization detected
Steal ticks since vm start: 0
Steal ticks percentage since vm start:  0.000

CPU: total 2 (initial active 2) (1 cores per cpu, 2 threads per core) family 6 model 79 stepping 1 microcode 0x1, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, rtm, adx, fma, vzeroupper, clflush, hv
CPU Model and flags from /proc/cpuinfo:
model name	: Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat spec_ctrl intel_stibp

Online cpus: 0-1
Offline cpus: 
BIOS frequency limitation: <Not Available>
Frequency switch latency (ns): <Not Available>
Available cpu frequencies: <Not Available>
Current governor: <Not Available>
Core performance/turbo boost: <Not Available>

Memory: 4k page, physical 8008932k(990600k free), swap 8388604k(4455608k free)
Page Sizes: 4k

vm_info: OpenJDK 64-Bit Server VM (17.0.5+8) for linux-amd64 JRE (17.0.5+8), built on Oct 18 2022 00:00:00 by "temurin" with gcc 10.3.0

END.

一个应用程序,同时打包了 jdk11 和 jdk17 的版本,使用 jdk17 时容器无法正常启动,总是提示内存不够.

一开始也向这个方向排查了一遍,发现不存在内存问题,但跑 jdk17 版本的容器时总是会失败.

百思不得其解,最终在 stackoverflow 找到了解决的办法.

为容器设置 --security-opt seccomp=unconfined 覆盖默认的设置就可以正常启动了.

根本原因还没有研究.

基于 operator-framework-spring-boot-starter 的项目启动失败

2023-09-07T14:05:09.037+08:00  INFO 235286 --- [omcatreconciler] i.j.operator.processing.Controller       : Starting 'mytomcatreconciler' controller for reconciler: cn.lank8s.demo.operator.reconciler.MyTomcatReconciler, resource: cn.lank8s.demo.operator.apis.MyTomcat
2023-09-07T14:05:10.515+08:00 ERROR 235286 --- [           main] i.j.o.s.starter.OperatorStarter          : Could not start operator

io.javaoperatorsdk.operator.OperatorException: Error starting operator
	at io.javaoperatorsdk.operator.Operator.start(Operator.java:166) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.springboot.starter.OperatorStarter.start(OperatorStarter.java:28) ~[operator-framework-spring-boot-starter-5.2.0.jar:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:343) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:228) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:165) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:437) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:370) ~[spring-context-6.0.10.jar:6.0.10]
	at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109) ~[spring-boot-3.1.1.jar:3.1.1]
	at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80) ~[spring-boot-3.1.1.jar:3.1.1]
	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) ~[spring-boot-3.1.1.jar:3.1.1]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.1.1.jar:3.1.1]
	at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80) ~[spring-boot-3.1.1.jar:3.1.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:331) ~[spring-boot-3.1.1.jar:3.1.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-3.1.1.jar:3.1.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-3.1.1.jar:3.1.1]
	at cn.lank8s.demo.operator.OperatorApplication.main(OperatorApplication.java:18) ~[classes/:na]
Caused by: io.javaoperatorsdk.operator.OperatorException: io.javaoperatorsdk.operator.MissingCRDException: 'mytomcats.lank8s.cn' v1 CRD was not found on the cluster, controller 'mytomcatreconciler' cannot be registered
	at io.javaoperatorsdk.operator.api.config.ExecutorServiceManager.lambda$executeAndWaitForAllToComplete$2(ExecutorServiceManager.java:81) ~[operator-framework-core-4.4.0.jar:na]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
	at io.javaoperatorsdk.operator.api.config.ExecutorServiceManager.executeAndWaitForAllToComplete(ExecutorServiceManager.java:76) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.api.config.ExecutorServiceManager.boundedExecuteAndWaitForAllToComplete(ExecutorServiceManager.java:56) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.ControllerManager.start(ControllerManager.java:42) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.Operator.start(Operator.java:161) ~[operator-framework-core-4.4.0.jar:na]
	... 23 common frames omitted
Caused by: io.javaoperatorsdk.operator.MissingCRDException: 'mytomcats.lank8s.cn' v1 CRD was not found on the cluster, controller 'mytomcatreconciler' cannot be registered
	at io.javaoperatorsdk.operator.processing.Controller.throwMissingCRDException(Controller.java:388) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.processing.Controller.start(Controller.java:349) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.ControllerManager.lambda$start$0(ControllerManager.java:43) ~[operator-framework-core-4.4.0.jar:na]
	at io.javaoperatorsdk.operator.api.config.ExecutorServiceManager.lambda$executeAndWaitForAllToComplete$0(ExecutorServiceManager.java:70) ~[operator-framework-core-4.4.0.jar:na]
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
	at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

原因是项目启动依赖于项目对应的 CRD,需要先将 CRD 资源 create 到 kubernetes 当中.

可以执行 mvn compile 来生成 CRD 的 yaml.

lan@lan:~/repo/git/kubernetes-with-java/operator$ ls target/classes/META-INF/fabric8/
mytomcats.lank8s.cn-v1beta1.yml  mytomcats.lank8s.cn-v1.yml
lan@lan:~/repo/git/kubernetes-with-java/operator$ k create -f target/classes/META-INF/fabric8/mytomcats.lank8s.cn-v1.yml 
customresourcedefinition.apiextensions.k8s.io/mytomcats.lank8s.cn created

基于 operator-framework-spring-boot-starter 的项目,Graalvm 打包的二进制文件启动失败

lan@lan:~/work/lanactions/lanactions/kubernetes-with-java/operator$ target/operator 

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.1)

2023-09-07T06:35:19.486Z  INFO 11782 --- [           main] c.l.demo.operator.OperatorApplication    : Starting AOT-processed OperatorApplication using Java 17.0.7 with PID 11782 (/home/lan/work/lanactions/lanactions/kubernetes-with-java/operator/target/operator started by runner in /home/lan/work/lanactions/lanactions/kubernetes-with-java/operator)
2023-09-07T06:35:19.486Z  INFO 11782 --- [           main] c.l.demo.operator.OperatorApplication    : No active profile set, falling back to 1 default profile: "default"
2023-09-07T06:35:19.506Z  INFO 11782 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-09-07T06:35:19.506Z  INFO 11782 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-09-07T06:35:19.506Z  INFO 11782 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.10]
2023-09-07T06:35:19.513Z  INFO 11782 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-09-07T06:35:19.513Z  INFO 11782 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 27 ms
2023-09-07T06:35:19.519Z  WARN 11782 --- [           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myTomcatReconciler': Instantiation of supplied bean failed
2023-09-07T06:35:19.519Z  INFO 11782 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-09-07T06:35:19.520Z ERROR 11782 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myTomcatReconciler': Instantiation of supplied bean failed
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1220) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[operator:6.0.10]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:941) ~[operator:6.0.10]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[operator:6.0.10]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[operator:3.1.1]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[operator:3.1.1]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) ~[operator:3.1.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[operator:3.1.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[operator:3.1.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[operator:3.1.1]
        at cn.lank8s.demo.operator.OperatorApplication.main(OperatorApplication.java:18) ~[operator:na]
Caused by: java.lang.ExceptionInInitializerError: null
        at org.snakeyaml.engine.v2.api.Load.loadAllFromInputStream(Load.java:166) ~[na:na]
        at io.fabric8.kubernetes.client.utils.KubernetesSerialization.parseYaml(KubernetesSerialization.java:270) ~[operator:na]
        at io.fabric8.kubernetes.client.utils.KubernetesSerialization.unmarshal(KubernetesSerialization.java:252) ~[operator:na]
        at io.fabric8.kubernetes.client.utils.KubernetesSerialization.unmarshal(KubernetesSerialization.java:342) ~[operator:na]
        at io.fabric8.kubernetes.client.utils.KubernetesSerialization.unmarshal(KubernetesSerialization.java:327) ~[operator:na]
        at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:185) ~[na:na]
        at io.fabric8.kubernetes.client.internal.KubeConfigUtils.parseConfigFromString(KubeConfigUtils.java:47) ~[na:na]
        at io.fabric8.kubernetes.client.Config.loadFromKubeconfig(Config.java:704) ~[operator:na]
        at io.fabric8.kubernetes.client.Config.tryKubeConfig(Config.java:668) ~[operator:na]
        at io.fabric8.kubernetes.client.Config.autoConfigure(Config.java:286) ~[operator:na]
        at io.fabric8.kubernetes.client.Config.<init>(Config.java:251) ~[operator:na]
        at io.fabric8.kubernetes.client.Config.<init>(Config.java:242) ~[operator:na]
        at io.fabric8.kubernetes.client.ConfigBuilder.<init>(ConfigBuilder.java:10) ~[operator:na]
        at io.fabric8.kubernetes.client.ConfigBuilder.<init>(ConfigBuilder.java:7) ~[operator:na]
        at io.fabric8.kubernetes.client.DefaultKubernetesClient.<init>(DefaultKubernetesClient.java:37) ~[na:na]
        at cn.lank8s.demo.operator.reconciler.MyTomcatReconciler.<init>(MyTomcatReconciler.java:34) ~[operator:na]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1254) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:949) ~[operator:6.0.10]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[operator:6.0.10]
        ... 17 common frames omitted
Caused by: java.nio.charset.UnsupportedCharsetException: UTF-32BE
        at [email protected]/java.nio.charset.Charset.forName(Charset.java:528) ~[operator:na]
        at org.snakeyaml.engine.v2.api.YamlUnicodeReader.<clinit>(YamlUnicodeReader.java:50) ~[na:na]
        ... 36 common frames omitted

看起来似乎是丢失了需要的 yaml 配置文件.

gradle 打包 shade 包

两个第三方包都依赖了同一个第三方包,但版本不一样导致冲突.

socketio客户端 使用客户端证书

本来计划是希望给每一个客户分发一个客户端证书,将证书作为权限管理的一部分,不过测试过后发现似乎不支持,因为在建立链接之前会发送一个 http 请求? (具体测试的时间有点久了,不太确认.)

maven deploy 时报错-repository element was not specified in the POM inside distributionManagement eleme

原因是因为我项目中的一个子模块没有引用父模块.

解决方案: 在这个模块的 pom.xml 里面单独配置仓库信息:

<distributionManagement>
        <repository>
                <id>alisnapshot</id>
                <name>alisnapshot</name>
                <url>https://packages.aliyun.com/maven/repository/2127020-snapshot-G5gKXW</url>
        </repository>
</distributionManagement>

一次 git-commit-id-plugin maven 插件的升级

当前项目使用的是 2.1.5 版本的 git-commit-id-plugin,这应该是在 2020 年左右引进来的,是同事在网上复制的.

在中央仓库看了一下这个依赖包,没想到这个是 2013 年的版本了,着实有点老了.最新的版本是 2021 年的 4.9.10,看起来已经不更新了,但在搜索 git-commit-id-plugin 的时候还看到了另一个包,依赖包的 group 是 io.github.git-commit-id,因此可以很轻松的在 github 上找到这个项目: git-commit-id-maven-plugin,这个应该是项目的继承者了,当前最新的包是 2024 年发布的 9.0.0,因此果断升级到这个依赖的这个版本.

<plugin>
        <groupId>pl.project13.maven</groupId>
        <artifactId>git-commit-id-plugin</artifactId>
        <version>2.1.5</version>
</plugin>

升级后:

<plugin>
        <groupId>io.github.git-commit-id</groupId>
        <artifactId>git-commit-id-maven-plugin</artifactId>
        <version>9.0.0</version>
</plugin>

renovate 没有升级依赖到最新版本

项目使用 renovate 来对依赖进行自动化升级,不过配置上没有进行过太多的折腾,使用的是默认配置. 我发现依赖包是有新版本的,但是 renovate 却没有提 PR 进行升级,目前还没找到原因.

Jib 构建多架构的容器镜像

Jib 有 maven 插件和 gradle 插件,可以很方便的在无docker环境下为应用构建容器镜像,但是如何构建一个多架构容器镜像呢?

jacoco 被跳过了 [INFO] Skipping JaCoCo execution due to missing execution data file.

使用 jacoco 的 maven 插件单元测试检查测试覆盖率,发现 jacoco 在 mvn clean test 执行过程中被跳过了.

...
--- jacoco-maven-plugin:0.8.12:report (default-report) @
[INFO] Skipping JaCoCo execution due to missing execution data file.
...

配置是直接从其他人博文中复制的,查看了一下官方文档,https://www.jacoco.org/jacoco/trunk/doc/prepare-agent-mojo.html

发现有一个显示maven-surefire-plugin插件的配置:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>@{argLine} -your -extra -arguments</argLine>
    </configuration>
  </plugin>

有一个值得注意的点是我的maven-surefire-plugin确实配置了argLine,但是没有@{argLine},于是我在我的配置中加上了@{argLine}重新跑了下 mvn clean test后就可以生成 jacoco 报告了.

在此之前我还谷歌了一些其他网友的解决方案,但原因都不太一样,不适用,因此上述内容可能也不是你 jacoco 报告失效的唯一原因.

non-static inner classes like this can only by instantiated using default, no-argument constructor

    @Data
    class JibContainerObj implements Serializable {
        private String image;
        private String imageId;
        private String imageDigest;
        private boolean imagePushed;
        private List<String> tags = Collections.emptyList();
        public JibContainerObj(){

        }
    }

    @Test
    public void testStart() throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        InputStream inputStream = getClass().getResourceAsStream("/jib-image.json");
        Assertions.assertNotNull(inputStream);
        JibContainerObj jibContainerObj = objectMapper.readValue(inputStream, new TypeReference<JibContainerObj>(){});
    }

引起这个问题是上述代码中读取 jib-image.json 文件 然后使用 jackson 去反序列化为对象的时候发生的,根据提示,内部类需要为静态类,因此在内部类上添加静态修饰就可以了.

--- class JibContainerObj implements Serializable {
+++ static class JibContainerObj implements Serializable {

fastjson迁移到jackson

项目需要代码大量使用了 fastjson,现在需要彻底拜托 fastjson (漏洞烦恼),迁移到 jackson.

所幸有较多时间处理,没有赶工上线的焦虑.

原先基于 fastjson 封装了一个工具类叫 JSONUtil,第一步就是先将工具类改名为 FastjsonUtil,避免由于惯性的问题继续让该类被同事使用.(在声明抛弃fastjson并且改名之前已经新增了不少代码仍然使用这个类…)

基于 jackson 封装一个 JacksonUtil 的,新的代码都将使用这个工具类来操作 json 相关内容.

最后一步则是逐步将使用 FastjsonUtil 的代码迁移到 JacksonUtil,同时检查下测试是否足够覆盖,如果没有的话就补充一下测试内容.

在整个过程中分多个版本上线,将压力分摊到多次上线中,整体来说没有什么大问题,最重要的一个因素是时间多.

socketio 序列化错误

Cannot construct instance of com.* (although at least one Creator exists): cannot deserialize

socketIOClient.emit(LAN_K8S_EVENT, new JSONObject(JacksonJsonUtils.beanToJson(dto)));

使用 jackson 序列化或直接传递对象到socketio server 的时候报错了,提示无法反序列化为对象,缺少构造函数,然而实际情况是构造函数是有的.

最后解决方案是使用 org.json.JSONObject 来将对象再包一层,传递 JSONObject 对象给服务器就没问题了.

根本问题是传递到 socketio server 时, json 数据中的双引号"被转义变成了\", 不确定是否有更优雅的方法解决.

项目 issue 也有其他人遇到这个问题: EventListener Can not parse JSON string to Java Object

微信公众号

扫描下面的二维码关注我们的微信公众号,第一时间查看最新内容。同时也可以关注我的Github,看看我都在了解什么技术,在页面底部可以找到我的Github。

wechat-qrcode