You are on page 1of 4

2020 IEEE International Conference on Advances in Electrical Engineering and Computer Applications (AEECA)

Research on Dynamic Detection of Java


Dependency Conflict

Kefeng Pan Yongzhi Wang


School of Software & Microelectronics School of Software & Microelectronics
Peking University Peking University
Beijing, China Beijing, China
pankefeng@pku.edu.cn wyz_@pku.edu.cn

Abstract—Platform independence is one of the and runs it [3]. Loading the incorrect class is the root cause
characteristics of the Java language. The Java program is of dependency conflicts. Static code detection can be
compiled to generate bytecode files, then the Java runtime performed on this type of dependency conflict problem, and
environment translates the bytecode into machine instructions the function call graphs under different dependency paths
for the corresponding platform and runs them. The JVM can can be analyzed and compared to find possible conflict
load the corresponding classes when needed. Incorrect class problems [4].
loading is the root cause of dependency conflicts. Static code
detection can be performed on this type of dependency conflict However, due to the dynamic nature of the Java language
problem, and the function call graphs under different [5], based on static analysis tools for analysis, there will be
dependency paths can be analyzed and compared to find some problems that cannot be handled. JAVA reflection
possible conflict problems. However, due to the dynamic mechanism is in the running state, for any class, you can
nature of the Java language, based on static analysis tools for know all the properties and methods of this class; for any
analysis, there will be some problems that cannot be handled. object, you can call any of its methods and properties. The
This paper proposes a set of processes and a solution to solve class name of the reflection call may be passed in at runtime,
this kind of problem through bytecode analysis and enhanced and it is only known at runtime which object is called, which
methods. cannot be obtained by static analysis.
Keywords—dependency conflict, dynamic detection, bytecode For this kind of situation, this paper proposes a set of
enhancement processes and an algorithm to solve this kind of problem
through bytecode analysis and enhanced methods.
I. INTRODUCTION
The problem of dependency conflicts has always troubled II. PROCESS AND SOLUTION DESIGN
developers and affected the stability and security of system As mentioned earlier, the Java language has some
operation [1]. For a long time, developers spent a lot of time dynamic features, you can use the reflection mechanism to
and energy to troubleshoot problems. The positioning of this get and call a class’s properties and methods at runtime. The
type of problem often requires developers to have rich class name and the called method are sometimes obtained as
experience. It is difficult for people who have not dealt with parameters from the outside, so it is impossible to analyze
related problems to realize that the problem stems from the the information of the class loaded by reflection during static
conflict of dependence. For the Java language, some analysis. If you need to call a method of this class in
developers and organizations choose to use class isolation operation, and this class loads a conflicting version because
mechanisms [2] to isolate the effects between components. of the JVM’s class loading mechanism. The call to this
But this makes the system must introduce a new framework, method will fail, resulting in an exception at runtime, which
resulting in the system become bloated, must rely on the in turn will cause the system to degrade or lose response. In
class isolation framework to function properly, increasing the order to be able to report this kind of dependency conflict,
complexity of the system. This approach usually requires we need to handle it before the method is called and perform
some mandatory development specifications, but also puts a check function. If you find that the called method is not in
forward higher requirements for developers. When a project the actually loaded class method, you can immediately detect
is used as a component, it often needs to be simple enough. If the dependency conflict. To this end, we need to be able to
the introduced component itself has a complicated modify the class method at the time of the reflection call, that
framework or because the newly introduced component is, to modify the source code or byte code.
needs to change the existing project’s architecture or even
reconstruct some technologies, this is unrealistic. Therefore, The dynamic enhancement process of the dependency
using a class isolation framework is not a general solution. In conflict that may exist in the reflection call is shown in Fig. 1.
most systems, there is a problem of dependency conflicts. First, get the bytecode files involved in the system, parse
Therefore, it is of great value and significance to study such these bytecode files, and generate the corresponding
problems. bytecode objects. Secondly, analyze whether there are
reflection method calls in the constant pool of these bytecode
The Java program is compiled to generate a bytecode file, objects. If it exists, further analyze the method content of the
and the Java runtime environment translates the bytecode bytecode object to find the specific location of the reflection
into the machine instructions of the corresponding platform method call. Then, the bytecode file with the reflection call is

978-1-7281-6521-9/20/$31.00 ©2020 IEEE 711 Dalian, China•August 25-27, 2020

Authorized licensed use limited to: Corporacion Universitaria de la Costa. Downloaded on August 26,2021 at 01:22:22 UTC from IEEE Xplore. Restrictions apply.
subjected to bytecode enhancement, and the detection of the file. The modified bytecode file adds a check to the calling
reflection call method is added before the reflection call. method at runtime, and if there is a dependency conflict
Finally replace the previous file with the modified bytecode problem, it can actively report it.

Bytecode file Bytecode file Bytecode file Bytecode file


acquisition& analysis enhancement replacement
interpretation
Fig. 1. Bytecode dynamic detection design.

bytecode modification tools. These tools have the function of


A. Bytecode File Acquisition and Interpretation parsing bytecode files. But ASM has better performance and
Maven is the most common package management tool in faster speed, and its implementation and design are as small
the Java language. By parsing the pom.xml file of the Maven and faster as possible.
project, we can obtain all the component jar packages used in
the system, and then get all the .class files. Since .class files The process of modifying the bytecode using the ASM
are closely arranged binary stream files, these .class files are framework is shown in Fig. 2. Use ClassReader to read the
parsed according to certain rules to generate corresponding bytecode file first, and then use Visitors such as ClassVisitor,
class objects, so that the objects can be analyzed. MethodVisitor, etc. to modify the class and method through
the visitor mode, and finally use ClassWriter to modify The
BCEL, SERP, ASM, Javaassit are some common bytecode file is converted back into a binary stream.

ClassReader Visitor ClassWriter

read generate

ClassVisitor
MethodVisitor

Bytecode Bytecode
Fig. 2. ASM modified byte code flow chart.

existing method in time, the detection purpose can be


B. Bytecode File Analysis achieved.
There is a method called getMethod() and a descriptor of
Ljava/lang/Class and a method descriptor beginning with It can be seen that before the reflection method is called,
(Ljava/lang/String; and ending with the first three elements on the top of the stack are the
Ljava/lang/reflect/Method; At the same time, there is a reference of the java.lang.Class[] object array, the name of
NameAndType definition of this method and a Methodref the reflection method, and the java.lang.Class object that
structure of this method. Then by analyzing the inside of the calls the reflection method. If the top element of the stack is
method body, we can find out the program location where popped in sequence, we can get the parameter type of the
the Methodref is called. reflective call method, the name of the reflective call method,
and the object of the reflective call. By checking these
parameters, we can find whether the class loaded in the
C. Bytecode File Enhancement
system has a method to be called. If it does not exist, we can
In the foregoing, through the analysis of the bytecode, the find the problem and report it in time. In summary, the
location of the reflection calls in the system is found. Since general steps of bytecode enhancement are given:
the class name, method name, and parameters of the
reflection call may only be passed in at runtime, static 1) Add three local variables in the local variable table,
analysis cannot analyze the exact function call relationship. which are used to represent the object of the reflection call,
If the runtime can perform some verification work before the the name of the reflection call method and the parameter
method is called by reflection and find and report the non- type of the reflection call method. The indexes in the local

712

Authorized licensed use limited to: Corporacion Universitaria de la Costa. Downloaded on August 26,2021 at 01:22:22 UTC from IEEE Xplore. Restrictions apply.
variable table are n, n+1, and n+2, respectively, where n Push the local variable with index n in the local variable
represents the number of local variables stored in the local table onto the stack, and the corresponding bytecode
variable table. Their types are java.lang.Class, instruction is aload n+2.
java.lang.String, java.lang.Class[], and the corresponding 5) Bytecode modification performs the function call
descriptors are Ljava.lang.Class, Ljava.lang.String, operation, the corresponding bytecode instruction shows
[Ljava.lang.Class. like INVOKEVIRTUAL com/wyz/aaa/A.invokeCheck
2) Bytecode modification performs a stack operation: (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)V
Pop the top element of the stack and store it in the local 6) Restore the previous execution environment, that is,
variable represented by index n+2. The corresponding put the previously saved parameters back on the stack. The
bytecode instruction is astore n+2.
corresponding bytecode instructions are aload n, aload n+1,
Pop the top element of the stack and store it in the local and aload n+2 in this order.
variable represented by index n+1. The corresponding 7) Increase the MAXLOCALS variable of the local
bytecode instruction is astore n+1. variable table by 3 and the MAXSTACK variable by 1. The
Pop the top element of the stack and store it in the local MAXLOCALS variable indicates the number of local
variable represented by index n, and the corresponding variables in the method, and MAXSTACK indicates the
bytecode instruction is astore n. maximum depth of the stack used. The bytecode operation
for the reflection call check adds the operation of pushing
3) Bytecode modification performs the new function
this on the original basis, which may cause the maximum
operation, and adds a method checkCheck() to the current
stack depth to change.
class to detect the previous variable. The parameters of the
method correspond to the parameter types at n, n+1, n+2 in D. Bytecode File Replacement
the index of the local variable table. There are two alternatives for bytecode enhancements to
4) Bytecode modification is performed on the stack: classes and methods of reflection calls that may have
Push the local variable with index 0 in the local variable dependency conflict issues. The first is to modify the original
table onto the stack (usually this), and the corresponding jar package file and repackage the enhanced bytecode file.
bytecode instruction is aload 0. The second is to modify it dynamically at runtime, trying to
replace it before the class loads. The first method will affect
Push the local variable with index n in the local variable
the original jar package file, resulting in unpredictable
table onto the stack, and the corresponding bytecode
consequences when referenced by other projects, and the
instruction is aload n.
files in the local warehouse are inconsistent with the files in
Push the local variable with index n in the local variable the remote warehouse. The problem is still not solved when
table onto the stack, and the corresponding bytecode redeploying on a new machine, so this section mainly
instruction is aload n+1. discusses the second approach, byte code replacement at
runtime.

Execute agent Execute


Load Java
premain system main
agent
function function

Bytecode
Instrumentation enhancem
ent
addTransformer()
Monitor bytecode Callback before
reading loading class
ClassLoader

Fig. 3. Dynamically enhanced bytecode replacement scheme

Based on Java instrumentation technology [6], we can (2) Enhance the bytecode file and insert the context of
design a dynamic enhancement framework as shown in Fig. the reflection call into the newly added check function.
3. Proceed as follows:
(3) Read the class that needs to be modified.
(1) Obtain the program entry that reflection may affect.
(4) Monitor the loading process of classes that need to be

713

Authorized licensed use limited to: Corporacion Universitaria de la Costa. Downloaded on August 26,2021 at 01:22:22 UTC from IEEE Xplore. Restrictions apply.
modified in the system during operation. related to the design of the Java program, especially when
the bytecode is enhanced, it is closely combined with the
(5) When the loading action is monitored, the byte code structure of the Java file and the mechanism of the JVM.
of this class is replaced. When there is no such design for other languages, how to
perform dynamic detection is still a problem that needs to be
III. CONCLUSIONS considered.
In this article we mainly discussed the design and
solution to the dynamic detection of Java language REFERENCES
dependency conflicts . For some problems that cannot be [1] J. Businge, A. Serebrenik and M. V. D. Brand, “Compatibility
solved by static analysis, the positioning-bytecode Prediction of Eclipse Third-Party Plug-ins in New Eclipse Releases,”
enhancement-dynamic replacement scheme is adopted, and 12th IEEE International Working Conference on Source Code
the bytecode enhancement is performed at runtime based on Analysis and Manipulation. IEEE, 2012.
Java agent technology, so that when conflicts occur, they can [2] A. L. C. Tavares and M. T. Valente, “A gentle introduction to OSGi,”
be actively reported. ACM SIGSOFT Software Engineering Notes, vol. 33, no. 5, pp 8,
2008.
There are two interesting future directions for this work. [3] F. Robert, S. Joachim and B. Egon, “Java and the Java virtual
First, The dependency conflict detection tool implemented in machine: definition, verification, validation,” Springer Science &
Business Media, 2012.
this article is only applicable to the Java language, especially
the Java components under the management of Maven [4] Y. Wang, et al., “Do the dependency conflicts in my project matter?”
Proceedings of the 2018 26th ACM Joint Meeting on European
management tools. But in the actual project, first of all, each Software Engineering Conference and Symposium on the
language has the problem of dependency conflict, not just Foundations of Software Engineering, 2018.
Java. Secondly, the management tool of each language is not [5] T. Jensen, M. D. Le, T. Thorn, “Security and dynamic class loading in
a kind. Java alone also has package management tools such Java: A formalisation,” 1998 International Conference on Computer
as Gradle. How to get rid of the limitation of management Languages, Proceedings. pp. 4-15, 1998.
tools and language and realize a universal detection [6] W. Binder, J. Hulaas and P. Moret, “Advanced Java bytecode
technology still needs further study and summary. Second, instrumentation”, Proceedings of the 5th international symposium on
Principles and practice of programming in Java, pp. 135-144, 2007.
The dynamic detection method in this article is closely

714

Authorized licensed use limited to: Corporacion Universitaria de la Costa. Downloaded on August 26,2021 at 01:22:22 UTC from IEEE Xplore. Restrictions apply.

You might also like