2017-04-08 24 views
0

我想在類JarClassLoaderMenu中啓用日誌記錄。log4j2日誌只能在一個類中工作

Menu類它的工作原理(日誌打印到文件和控制檯)。但是日誌記錄在JarClassLoader中不起作用(日誌記錄在控制檯或文件中都不起作用)。

爲了簡單起見,我只將消息添加到JarClassLoader的類構造函數中,並在main(String[] args)方法的開始處添加一條消息。

log4j2.properties

name=PropertiesConfig 
property.filename=classloading/menu-module/logs 
appenders=console, file 

appender.console.type=Console 
appender.console.name=STDOUT 
appender.console.layout.type=PatternLayout 
appender.console.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n 

appender.file.type=File 
appender.file.name=LOGFILE 
appender.file.fileName=${filename}/propertieslogs.log 
appender.file.layout.type=PatternLayout 
appender.file.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n 

rootLogger.level=info 
rootLogger.appenderRefs=stdout 
rootLogger.appenderRef.stdout.ref=STDOUT 

loggers=file 
logger.file.name=com.example.classloading 
logger.file.level=info 
logger.file.appenderRefs=file 
logger.file.appenderRef.file.ref=LOGFILE 

JarClassLoader

package com.example.classloading; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Enumeration; 
import java.util.HashMap; 
import java.util.jar.JarEntry; 
import java.util.jar.JarFile; 

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 

public class JarClassLoader extends ClassLoader { 

    private static final Logger log = LogManager.getLogger(JarClassLoader.class); 

    private HashMap<String, Class<?>> cache = new HashMap<String, Class<?>>(); 
    private String jarFileName; 
    private String packageName; 
    private static String WARNING = "Warning : No jar file found. Packet unmarshalling won't be possible. Please verify your classpath"; 

    public JarClassLoader(String jarFileName, String packageName) {   
     log.info(">> inside JarClassLoader"); 

     this.jarFileName = jarFileName; 
     this.packageName = packageName; 

     cacheClasses(); 
    } 

    private void cacheClasses() { 
     try { 
      JarFile jarFile = new JarFile(jarFileName); 
      Enumeration entries = jarFile.entries(); 
      while (entries.hasMoreElements()) { 
       JarEntry jarEntry = (JarEntry) entries.nextElement(); 
       // simple class validation based on package name 
       if (match(normalize(jarEntry.getName()), packageName)) { 
        byte[] classData = loadClassData(jarFile, jarEntry); 
        if (classData != null) { 
         Class<?> clazz = defineClass(stripClassName(normalize(jarEntry.getName())), classData, 0, classData.length); 
         cache.put(clazz.getName(), clazz); 
         System.out.println("== class " + clazz.getName() + " loaded in cache"); 
        } 
       } 
      } 
     } 
     catch (IOException IOE) { 
      System.out.println(WARNING); 
     } 
    } 

    public synchronized Class<?> loadClass(String name) throws ClassNotFoundException { 
     Class<?> result = cache.get(name); 
     if (result == null) 
      result = cache.get(packageName + "." + name); 
     if (result == null) 
      result = super.findSystemClass(name);  
     System.out.println("== loadClass(" + name + ")");  
     return result; 
    } 

    private String stripClassName(String className) { 
     return className.substring(0, className.length() - 6); 
    } 

    private String normalize(String className) { 
     return className.replace('/', '.'); 
    } 

    private boolean match(String className, String packageName) { 
     return className.startsWith(packageName) && className.endsWith(".class"); 
    } 

    private byte[] loadClassData(JarFile jarFile, JarEntry jarEntry) throws IOException { 
     long size = jarEntry.getSize(); 
     if (size == -1 || size == 0) 
      return null; 

     byte[] data = new byte[(int)size]; 
     InputStream in = jarFile.getInputStream(jarEntry); 
     in.read(data); 

     return data; 
    } 
} 

Menu

package com.example.classloading; 

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 

import java.util.Scanner; 

public class Menu { 

    private static final Logger log = LogManager.getLogger(); 

    public static void main(String[] args) { 

     int select; 
     do { 
      log.info(">> menu started"); 

      System.out.println("=== MENU ==="); 
      System.out.println("This is a simple multi-module project that can dynamically load modules."); 
      System.out.println("1. Load and run simple-module"); 
      System.out.println("2. Load and run module in jar from ..."); 
      System.out.println("0. EXIT"); 

      Scanner scanner = new Scanner(System.in); 
      select = scanner.nextInt(); 

      switch (select) { 
       case 1: { 
        JarClassLoader jarClassLoader = new JarClassLoader("classloading/simple-module/target/simple-module-1.0-SNAPSHOT.jar", "com.example.classloading"); 
        try { 
         Class<?> clas = jarClassLoader.loadClass("com.example.classloading.SimpleModule"); 
         Module sample = (Module) clas.newInstance(); 
         sample.run(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
        break; 
       } 
       case 2: { 
        System.out.print(" Path to jar: "); 
        String jarFileName = scanner.next(); 
        System.out.print(" Package name: "); 
        String packageName = scanner.next(); 
        System.out.print(" Class to load and run: "); 
        String classToLoad = scanner.next(); 

        JarClassLoader jarClassLoader = new JarClassLoader(jarFileName, packageName); 
        try { 
         Class<?> clas = jarClassLoader.loadClass(classToLoad); 
         Module sample = (Module) clas.newInstance(); 
         sample.run(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
        break; 
       } 
      } 
     } while (select != 0); 
    } 

} 

output


所以,在JarClassLoader類爲什麼不記錄工作?

+0

在'JarClassLoader'中,您不會導入'org.apache.logging.log4j.LogManager',這樣就不會編譯。或者它使用'com.example.classloading.LogManager'。 – Andreas

+0

@Andreas我的不好:當然,這是重要的。複製了另一個我的問題的代碼。請撤銷你的「-1」。 :) – Woland

+0

@Woland如果他不撤銷他的-1,我會給你+1來平衡情況:) –

回答

1

我已經運行你的代碼,並沒有記錄問題。當我運行確切的代碼時,您的輸出如下所示;

[INFO ] 2017-04-09 20:07:15.208 [main] Menu - >> menu started 
=== MENU === 
This is a simple multi-module project that can dynamically load modules. 
1. Load and run simple-module 
2. Load and run module in jar from ... 
0. EXIT 
1 
[INFO ] 2017-04-09 20:07:20.681 [main] JarClassLoader - >> inside JarClassLoader 

在您的截圖中,我沒有看到您在控制檯中輸入了「1」或「2」作爲選擇。只要你沒有從控制檯輸入任何東西,java程序就會等待輸入,並且因爲這個原因,它永遠不會到達記錄完成的那一行。