class文件扫描分析

一.简介

最近项目中需要分析java文件中依赖的类、Jar包中class文件扫描,通过提取字节码文件中的Constant_Class_info 常量池中的信息实现class 文件依赖分析。使用了ASM 轻量级jar包读取字节码文件,根据JVM虚拟机规范解析常量池信息。

字节码文件类型描述:
在这里插入图片描述

<dependency>
   <groupId>org.ow2.asm</groupId>
   <artifactId>asm</artifactId>
   <version>8.0</version>
</dependency>

二.实现



import org.objectweb.asm.ClassReader;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ClassUtil {
   

    /**
     * 分析class 文件中Constant_Class_info 信息
     * @param classStream
     * @return
     * @throws IOException
     */
    public static List<String> constClassInfo(InputStream classStream) throws IOException {
   
        ClassReader reader = new ClassReader(classStream);
        ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
        List<String> infos = new ArrayList<>();
        for(int i=1;i<reader.getItemCount();i++) {
   
            int off = reader.getItem(i);
            if(off > 0 && reader.readByte(off-1) == 7){
   
                int index = reader.readUnsignedShort(off);
                off = reader.getItem(index);
                int len = reader.readUnsignedShort(off);
                for(int j=0;j<len;j++){
   
                    int b = reader.readByte(off+2+j);
                    bos.write(b);
                }
                infos.add(bos.toString("utf-8"));
                bos.reset();
            }
        }
        return infos;
    }


    /**
     * 分析class 文件中Constant_Utf8_info 常量池信息项
     * @param classStream   class 字节码流
     * @throws IOException
     */
    public static List<String> constUtf8Info(InputStream classStream) throws IOException
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实验二--LL(1)分析法实验报告全文共11页,当前为第1页。实验二--LL(1)分析法实验报告全文共11页,当前为第1页。实验二 LL(1)分析法 实验二--LL(1)分析法实验报告全文共11页,当前为第1页。 实验二--LL(1)分析法实验报告全文共11页,当前为第1页。 实验目的 通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。 二、实验内容及设计原理 所谓LL(1)分析法,就是指从左到右扫描输入串(源程序),同时采用最左推导,且对每次直接推导只需向前看一个输入符号,便可确定当前所应当选择的规则。实现LL(1)分析的程序又称为LL(1)分析程序或LL1(1)分析器。 我们知道一个文法要能进行LL(1)分析,那么这个文法应该满足:无二义性,无左递归,无左公因子。当文法满足条件后,再分别构造文法每个非终结符的FIRST和FOLLOW集合,然后根据FIRST和FOLLOW集合构造LL(1)分析表,最后利用分析表,根据LL(1)语法分析构造一个分析器。LL(1)的语法分析程序包含了三个部分,总控程序,预测分析表函数,先进先出的语法分析栈,本程序也是采用了同样的方法进行语法分析,该程序是采用了C++语言来编写,其逻辑结构图如下: LL(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号a做哪种过程的。对于任何(X,a),总控程序每次都执行下述三种可能的动作之一: (1)若X = a ='#',则宣布分析成功,停止分析过程。 (2)若X = a '#',则把X从STACK栈顶弹出,让a指向下一个输入符号。 (3)若X是一个非终结符,则查看预测分析表M。若M[A,a]中存放着关于X的一个产生式,那么,首先把X弹出STACK栈顶,然后,把产生式的右部符号串按反序一一弹出STACK栈(若右部符号为ε,则不推什么东西进STACK栈)。若M[A,a]中存放着"出错标志",则调用出错诊断程序ERROR。 三、程序结构描述 实验二--LL(1)分析法实验报告全文共11页,当前为第2页。实验二--LL(1)分析法实验报告全文共11页,当前为第2页。 实验二--LL(1)分析法实验报告全文共11页,当前为第2页。 实验二--LL(1)分析法实验报告全文共11页,当前为第2页。 1、定义的变量 初始化预测分析表: LL E[8]={"TG","TG","error","error","error","error","error","error"}; LL G[8]={"error","error","null","+TG","-TG","error","error","null"}; LL T[8]={"FS","FS","error","error","error","error","error","error"}; LL S[8]={"error","error","null","null","null","*FS","/FS","null"}; LL F[8]={"i","(i)","error","error","error","error","error","error"}; const int MaxLen=10; 初始化栈的长度 const int Length=10; 初始化数组长度 char Vn[5]={'E','G','T','S','F'}; 非终结符数组 char Vt[8]={'i','(',')','+','-','*','/','#'}; 终结符数组 char ch,X; /全局变量,ch用于读当前字符,X用于获取栈顶元素 char strToken[Length]; 存储规约表达式 2、定义的函数 class stack 栈的构造及初始化 int length(char *c) 输出字符数组的长度 void print(int i,char*c) 剩余输入串的输出 void run() 分析程序 3、LL(1)预测分析程序流程图 实验二--LL(1)分析法实验报告全文共11页,当前为第3页。实验二--LL(1)分析法实验报告全文共11页,当前为第3页。 实验二--LL(1)分析法实验报告全文共11页,当前为第3页。 实验二--LL(1)分析法实验报告全文共11页,当前为第3页。 四、程序源代码及运行结果 #include<iostream> using namespace std; const int MaxLen=10; //初始化栈的长度 const int Length=10;//初始化数组长度 ch
Logback 可以通过配置文件(logback.xml)来配置日志系统的行为,下面针对配置文件的不同部分进行详细分析。 1. 配置根节点(configuration) 配置根节点包含了整个配置文件的属性和设置,如 debug 属性、上下文名称、日志输出级别等。例如: ```xml <configuration debug="true" scan="true" scanPeriod="30 seconds"> <contextName>myapp</contextName> <property name="logPath" value="/logs"/> <property name="logFile" value="myapp.log"/> <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> <jmxConfigurator /> <shutdownHook /> <include resource="logback-include.xml" /> <logger name="com.example" level="DEBUG" /> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="FILE" /> </root> </configuration> ``` 在这个例子中,配置了 debug 属性为 true,表示启用调试模式;scan 属性为 true,表示启用自动配置文件扫描模式;scanPeriod 属性为 30 秒,表示每隔 30 秒重新扫描一次配置文件。contextName 指定了上下文名称,property 定义了日志文件的路径和名称。statusListener、jmxConfigurator、shutdownHook、include 均为可选设置。 2. 配置日志记录器(logger) 在 Logback 中,通过日志记录器(Logger)来记录日志信息。可以为每个类或包设置不同的日志级别,以控制日志输出的详细程度。例如: ```xml <logger name="com.example.MyClass" level="DEBUG" /> ``` 上述配置表示,com.example.MyClass 类的日志级别为 DEBUG,即只输出 DEBUG 级别及以上的日志信息。如果不指定 level 属性,则默认为 root 节点的级别。 3. 配置日志输出器(appender) 日志输出器(Appender)用于将日志信息输出到指定的目标,如控制台、文件、数据库等。Logback 提供了多种输出器,如 ConsoleAppender、FileAppender、RollingFileAppender 等。例如: ```xml <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> ``` 上述配置表示,定义了一个名为 CONSOLE 的控制台输出器,使用 ConsoleAppender 类实现。encoder 配置了输出格式模板,%d 表示日期时间,%thread 表示线程名,%-5level 表示日志级别(长度为 5),%logger{35} 表示 Logger 名称(长度为 35),%msg 表示日志信息,%n 表示换行符。 4. 配置日志格式化器(layout) 日志格式化器(Layout)用于格式化日志信息,使其易于阅读和理解。Logback 提供了多种格式化器,如 PatternLayout、HTMLLayout、XMLLayout 等。例如: ```xml <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${logPath}/${logFile}</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${logPath}/${logFile}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> ``` 上述配置表示,定义了一个名为 FILE 的文件输出器,使用 RollingFileAppender 类实现。file 属性指定了日志文件的路径和名称,rollingPolicy 配置了按时间滚动的策略,fileNamePattern 指定了滚动后的文件名格式,maxHistory 指定了最多保留的历史文件数。encoder 配置了输出格式模板,与前面的例子相同。 5. 配置日志过滤器(filter) 日志过滤器(Filter)用于过滤和控制日志信息的输出。可以根据不同的条件对日志信息进行过滤,如根据日志级别、Logger 名称、线程名称等。例如: ```xml <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${logPath}/${logFile}</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${logPath}/${logFile}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> ``` 上述配置表示,定义了一个名为 FILE 的文件输出器,使用 RollingFileAppender 类实现。filter 配置了一个 LevelFilter 过滤器,只保留 WARN 级别及以上的日志信息,onMatch 和 onMismatch 分别表示匹配和不匹配时的处理方式。 以上就是 Logback 配置文件的主要部分分析,通过配置根节点、日志记录器、日志输出器、日志格式化器和日志过滤器等组件,可以实现灵活、高效的日志记录功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值