java log4j 的一个bug
java项目中使用log4j记录日志几乎成了标配,
最近一个项目中出了个问题 现象是这样的: 不连vpn程序一切正常,连上VPN启动程序 直接异常退出,
错误日志直接指向了 log4j 库
org.apache.logging.log4j.core.util.UuidUtil.clinit
就是说在 UuidUtil 这个类初始化时出了问题
最终错误在此处
数组index超界
原因是在我的机器上不连vpn mac是一个长度为6的数组 连vpn后长度为8 了
mac长度为8 则 length=6 index=2
则等价于:
mac=new byte[8];
node=new byte[8];
System.arraycopy(mac, 2, node, 2+ 2, 6);
于是java.lang.ArrayIndexOutOfBoundsException
作者的意图我想是:
如果mac长度小于等6 则将其复制到node从2开始的后面几位
如果mac长度大于 6 则复制最后六位到node从2开始的后6位
则应该写成:
System.arraycopy(mac,index, node,2,length);
坑!
最后附上异常信息和原类:
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.apache.logging.log4j.core.util.WatchManager.<init>(WatchManager.java:53)
at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:135)
at org.apache.logging.log4j.core.config.NullConfiguration.<init>(NullConfiguration.java:32)
at org.apache.logging.log4j.core.LoggerContext.<clinit>(LoggerContext.java:85)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(ClassLoaderContextSelector.java:179)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(ClassLoaderContextSelector.java:153)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:78)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:65)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:148)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.commons.logging.LogAdapter$Log4jLog.<clinit>(LogAdapter.java:155)
at org.apache.commons.logging.LogAdapter$Log4jAdapter.createLog(LogAdapter.java:122)
at org.apache.commons.logging.LogAdapter.createLog(LogAdapter.java:89)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:67)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:59)
Caused by: java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at org.apache.logging.log4j.core.util.UuidUtil.<clinit>(UuidUtil.java:81)
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.logging.log4j.core.util; import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.PropertiesUtil; /**
* Generates a unique ID. The generated UUID will be unique for approximately 8,925 years so long as
* less than 10,000 IDs are generated per millisecond on the same device (as identified by its MAC address).
*/
public final class UuidUtil {
/**
* System property that may be used to seed the UUID generation with an integer value.
*/
public static final String UUID_SEQUENCE = "org.apache.logging.log4j.uuidSequence"; private static final Logger LOGGER = StatusLogger.getLogger(); private static final String ASSIGNED_SEQUENCES = "org.apache.logging.log4j.assignedSequences"; private static final AtomicInteger COUNT = new AtomicInteger(0);
private static final long TYPE1 = 0x1000L;
private static final byte VARIANT = (byte) 0x80;
private static final int SEQUENCE_MASK = 0x3FFF;
private static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
private static final long INITIAL_UUID_SEQNO = PropertiesUtil.getProperties().getLongProperty(UUID_SEQUENCE, 0); private static final long LEAST; private static final long LOW_MASK = 0xffffffffL;
private static final long MID_MASK = 0xffff00000000L;
private static final long HIGH_MASK = 0xfff000000000000L;
private static final int NODE_SIZE = 8;
private static final int SHIFT_2 = 16;
private static final int SHIFT_4 = 32;
private static final int SHIFT_6 = 48;
private static final int HUNDRED_NANOS_PER_MILLI = 10000; static {
byte[] mac = NetUtils.getMacAddress();
final Random randomGenerator = new SecureRandom();
if (mac == null || mac.length == 0) {
mac = new byte[6];
randomGenerator.nextBytes(mac);
}
final int length = mac.length >= 6 ? 6 : mac.length;
final int index = mac.length >= 6 ? mac.length - 6 : 0;
final byte[] node = new byte[NODE_SIZE];
node[0] = VARIANT;
node[1] = 0;
for (int i = 2; i < NODE_SIZE; ++i) {
node[i] = 0;
}
System.arraycopy(mac, index, node, index + 2, length);
final ByteBuffer buf = ByteBuffer.wrap(node);
long rand = INITIAL_UUID_SEQNO;
String assigned = PropertiesUtil.getProperties().getStringProperty(ASSIGNED_SEQUENCES);
long[] sequences;
if (assigned == null) {
sequences = new long[0];
} else {
final String[] array = assigned.split(Patterns.COMMA_SEPARATOR);
sequences = new long[array.length];
int i = 0;
for (final String value : array) {
sequences[i] = Long.parseLong(value);
++i;
}
}
if (rand == 0) {
rand = randomGenerator.nextLong();
}
rand &= SEQUENCE_MASK;
boolean duplicate;
do {
duplicate = false;
for (final long sequence : sequences) {
if (sequence == rand) {
duplicate = true;
break;
}
}
if (duplicate) {
rand = (rand + 1) & SEQUENCE_MASK;
}
} while (duplicate);
assigned = assigned == null ? Long.toString(rand) : assigned + ',' + Long.toString(rand);
System.setProperty(ASSIGNED_SEQUENCES, assigned); LEAST = buf.getLong() | rand << SHIFT_6;
} /* This class cannot be instantiated */
private UuidUtil() {
} /**
* Generates Type 1 UUID. The time contains the number of 100NS intervals that have occurred
* since 00:00:00.00 UTC, 10 October 1582. Each UUID on a particular machine is unique to the 100NS interval
* until they rollover around 3400 A.D.
* <ol>
* <li>Digits 1-12 are the lower 48 bits of the number of 100 ns increments since the start of the UUID
* epoch.</li>
* <li>Digit 13 is the version (with a value of 1).</li>
* <li>Digits 14-16 are a sequence number that is incremented each time a UUID is generated.</li>
* <li>Digit 17 is the variant (with a value of binary 10) and 10 bits of the sequence number</li>
* <li>Digit 18 is final 16 bits of the sequence number.</li>
* <li>Digits 19-32 represent the system the application is running on.</li>
* </ol>
*
* @return universally unique identifiers (UUID)
*/
public static UUID getTimeBasedUuid() { final long time = ((System.currentTimeMillis() * HUNDRED_NANOS_PER_MILLI) +
NUM_100NS_INTERVALS_SINCE_UUID_EPOCH) + (COUNT.incrementAndGet() % HUNDRED_NANOS_PER_MILLI);
final long timeLow = (time & LOW_MASK) << SHIFT_4;
final long timeMid = (time & MID_MASK) >> SHIFT_2;
final long timeHi = (time & HIGH_MASK) >> SHIFT_6;
final long most = timeLow | timeMid | TYPE1 | timeHi;
return new UUID(most, LEAST);
}
}
java log4j 的一个bug的更多相关文章
- java nio的一个严重BUG
java nio的一个严重BUG Posted on 2009-09-28 19:27 dennis 阅读(4588) 评论(5) 编辑 收藏 所属分类: java .源码解读 这个BU ...
- logback1.11的一个bug:有线程持续不断写入log文件,log文件就不会按设定以日期切换。
此Bug的解决方案请见:https://www.cnblogs.com/xiandedanteng/p/12205422.html logback是log4j的后继者,作者也是同一人,但其中的bug不 ...
- 从修复 testerhome(rubychina)网站的一个 bug 学习 ruby&rails on ruby
前言 testerhome: http://testerhome.com/topics/1480 对于一个差点脱离前沿技术人,想要学习ruby,就意味着要放弃熟悉的操作系统windows,熟悉的ide ...
- sqlite在Android上的一个bug:SQLiteCantOpenDatabaseException when nativeExecuteForCursorWindow
更多内容在这里查看 https://ahangchen.gitbooks.io/windy-afternoon/content/ ::-/com.company.product W/System.er ...
- [android开发IDE]adt-bundle-windows-x86的一个bug:无法解析.rs文件--------rs_core.rsh file not found
google的android自带的apps写的是相当牛逼的,将其导入到eclipse中方便我们学习扩展.可惜关于导入的资料太少了,尤其是4.1之后的gallery和camera合二为一了.之前导4.0 ...
- java Log4j日志配置详解大全
一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使 ...
- java log4j基本配置及日志级别配置详解
java log4j日志级别配置详解 1.1 前言 说出来真是丢脸,最近被公司派到客户公司面试外包开发岗位,本来准备了什么redis.rabbitMQ.SSM框架的相关面试题以及自己做过的一些项目回顾 ...
- androidstudio canary5一个bug
Android Studio最新开发版一直跟着升级.到Canary5的时候出了一个bug. app build.gradle添加自己编译的aar库,原本一直使用: compile(name:'ijkp ...
- 记录一个使用HttpClient过程中的一个bug
最近用HttpClient进行链接请求,开了多线程之后发现经常有线程hang住,查看线程dump java.lang.Thread.State: RUNNABLE at java.net.Socket ...
随机推荐
- 逻辑漏洞介绍 & 越权访问攻击 & 修复建议
介绍逻辑漏洞 逻辑漏洞就是指攻击者利用业务的设计缺陷,获取敏感信息或破坏业务的完整性.一般出现在密码修改.越权访问.密码找回.交易支付金额等功能处.其中越权访问又有水平越权和垂直越权两种,如下所示. ...
- httpclient post推送数据
客户端代码 /** * 从接口获取数据 * @param url 服务器接口地址 * @param json 传入的参数 若获取全部,此项为空 * @return 返回查询到的数据 * @throws ...
- 动态代理:jdk动态代理和cglib动态代理
/** * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为jdk动态代理和cglib,jdk动态代理是通过实现接口的方式创建代理类的,cglib是通过继承类的方式实现的代理类的 * jdk动 ...
- Spring学习(八)--Spring的AOP
自工作以后身不由己,加班无数,996.995不可控制,高高立起的flag无法完成,无奈,随波逐流,尽力而已! 1.advice通知 advice主要描述Spring AOP 围绕奥方法调用而注入的切面 ...
- MyEclpse 2015在线安装Gradle插件图解
MyEclpse 2015 安装Gradle插件 安装方式:在线安装 一.如何获得Gradle插件在线安装地址 Gradle插件最新在线安装地址可在如下网址中查找: https://github.co ...
- Java知识系统回顾整理01基础04操作符05赋值操作符
一.赋值操作 赋值操作的操作顺序是从右到左 int i = 5+5; 首先进行5+5的运算,得到结果10,然后把10这个值,赋给i public class HelloWorld { public s ...
- P2590 树的统计
一道树剖的模板题 首先,由于本人比较懒,就把单点修改写成了区间修改,其实也没有有多大区别(关键是我不会写单点修改QAQ) 不得不说,树剖的码量比较大,调了一上午才勉强调完. 这道题要求我们支持 单点修 ...
- ASP。NET MVC的部分视图和部分模型
下载source - 1.7 MB 介绍 本文解决了返回视图内容包含表单元素的部分视图的问题. 代码重用是一种非常有用的节省时间的特性,任何优秀的工程师都会在他们的工作过程中构建许多有用的函数.对于W ...
- VMware ESXi 客户端连接控制台时,提示“VMRC 控制台连接已断开...正在尝试重新连接”的解决方法
故障描述: 通过 VMware vSphere Client 连接到安装 VMware ESXi 虚拟环境的主机时,当启动其中的虚拟机后,无法连接到控制台. 选择"控制台"时,控制 ...
- docker overlay原理
周末两天研究了一下docker overlay网络的原理,因为我本身对go语言不太熟悉,直接看docker官方的libnetwork库看不太懂,看linux内核的vxlan代码又粗心大意,导致有一个环 ...