log4j的一個(gè)bug
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
? 作者?|??dint
來源 |? urlify.cn/nUr67v
66套java從入門到精通實(shí)戰(zhàn)課程分享
java項(xiàng)目中使用log4j記錄日志幾乎成了標(biāo)配,
最近一個(gè)項(xiàng)目中出了個(gè)問題? 現(xiàn)象是這樣的:? 不連vpn程序一切正常,連上VPN啟動程序 直接異常退出,
錯(cuò)誤日志直接指向了 log4j 庫
org.apache.logging.log4j.core.util.UuidUtil.clinit
就是說在 UuidUtil 這個(gè)類初始化時(shí)出了問題最終錯(cuò)誤在此處
? ?
?
?數(shù)組index超界? ??
?
原因是在我的機(jī)器上不連vpn? mac是一個(gè)長度為6的數(shù)組? ?連vpn后長度為8 了
?
mac長度為8? ?則 length=6? index=2?
則等價(jià)于:?
mac=new byte[8];
node=new byte[8];
System.arraycopy(mac, 2, node, 2+ 2, 6);
于是java.lang.ArrayIndexOutOfBoundsException
?
作者的意圖我想是:
如果mac長度小于等6 則將其復(fù)制到node從2開始的后面幾位
如果mac長度大于 6 則復(fù)制最后六位到node從2開始的后6位?
則應(yīng)該寫成:
?System.arraycopy(mac,index, node,2,length);?
坑!
?
既然知道原因了 那么解決方案也很簡單,直接修改UuidUtil.java 即可
?
?
最后附上異常信息和原類:
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.apache.logging.log4j.core.util.WatchManager.
at org.apache.logging.log4j.core.config.AbstractConfiguration.
at org.apache.logging.log4j.core.config.NullConfiguration.
at org.apache.logging.log4j.core.LoggerContext.
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
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.
? ?
/*
?*?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[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?<????}
?
?
????/*?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.
?????*?
?????*?- Digits?1-12?are?the?lower?48?bits?of?the?number?of?100?ns?increments?since?the?start?of?the?UUID
?????*?epoch.
?????*?- Digit?13?is?the?version?(with?a?value?of?1).
?????*?- Digits?14-16?are?a?sequence?number?that?is?incremented?each?time?a?UUID?is?generated.
?????*?- Digit?17?is?the?variant?(with?a?value?of?binary?10)?and?10?bits?of?the?sequence?number
?????*?- Digit?18?is?final?16?bits?of?the?sequence?number.
?????*?- Digits?19-32?represent?the?system?the?application?is?running?on.
?????*?
?????*
?????*?@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)?<????????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);
????}
}
粉絲福利:實(shí)戰(zhàn)springboot+CAS單點(diǎn)登錄系統(tǒng)視頻教程免費(fèi)領(lǐng)取
???
?長按上方微信二維碼?2 秒 即可獲取資料
感謝點(diǎn)贊支持下哈?
