Skip to content

Commit 78d22fb

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#2763 from diffblue/classpath
unify jar list and classpath
2 parents b7c430d + 53b3c4a commit 78d22fb

File tree

4 files changed

+83
-55
lines changed

4 files changed

+83
-55
lines changed

jbmc/src/java_bytecode/java_bytecode_language.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ bool java_bytecode_languaget::parse(
185185
const std::string &path)
186186
{
187187
PRECONDITION(language_options_initialized);
188+
189+
java_class_loader.clear_classpath();
190+
191+
for(const auto &p : config.java.classpath)
192+
java_class_loader.add_classpath_entry(p);
193+
188194
java_class_loader.set_message_handler(get_message_handler());
189195
java_class_loader.set_java_cp_include_files(java_cp_include_files);
190196
java_class_loader.add_load_classes(java_load_classes);
@@ -232,7 +238,7 @@ bool java_bytecode_languaget::parse(
232238
main_jar_classes.push_back(kv.first);
233239
}
234240
else
235-
java_class_loader.add_jar_file(path);
241+
java_class_loader.add_classpath_entry(path);
236242
}
237243
else
238244
UNREACHABLE;

jbmc/src/java_bytecode/java_bytecode_language.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,14 @@ class java_bytecode_languaget:public languaget
123123
lazy_methods_mode(lazy_methods_modet::LAZY_METHODS_MODE_EAGER),
124124
string_refinement_enabled(false),
125125
pointer_type_selector(std::move(pointer_type_selector))
126-
{}
126+
{
127+
}
127128

128129
java_bytecode_languaget():
129130
java_bytecode_languaget(
130131
std::unique_ptr<select_pointer_typet>(new select_pointer_typet()))
131-
{}
132-
132+
{
133+
}
133134

134135
bool from_expr(
135136
const exprt &expr,

jbmc/src/java_bytecode/java_class_loader.cpp

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ Author: Daniel Kroening, [email protected]
1313

1414
#include <util/suffix.h>
1515
#include <util/prefix.h>
16-
#include <util/config.h>
1716

1817
#include "java_bytecode_parser.h"
1918

@@ -69,6 +68,19 @@ java_class_loadert::parse_tree_with_overlayst &java_class_loadert::operator()(
6968
return class_map.at(class_name);
7069
}
7170

71+
void java_class_loadert::add_classpath_entry(const std::string &path)
72+
{
73+
if(has_suffix(path, ".jar"))
74+
{
75+
classpath_entries.push_back(classpath_entryt(classpath_entryt::JAR, path));
76+
}
77+
else
78+
{
79+
classpath_entries.push_back(
80+
classpath_entryt(classpath_entryt::DIRECTORY, path));
81+
}
82+
}
83+
7284
optionalt<java_bytecode_parse_treet> java_class_loadert::get_class_from_jar(
7385
const irep_idt &class_name,
7486
const std::string &jar_file,
@@ -124,55 +136,44 @@ java_class_loadert::get_parse_tree(
124136
return parse_trees;
125137
}
126138

127-
// First add all given JAR files
128-
for(const auto &jar_file : jar_files)
139+
// Rummage through the class path
140+
for(const auto &cp_entry : classpath_entries)
129141
{
130-
jar_index_optcreft index = read_jar_file(jar_file);
131-
if(!index)
132-
continue;
133-
optionalt<java_bytecode_parse_treet> parse_tree =
134-
get_class_from_jar(class_name, jar_file, *index);
135-
if(parse_tree)
136-
parse_trees.emplace_back(std::move(*parse_tree));
137-
}
138-
139-
// Then add everything on the class path
140-
for(const auto &cp_entry : config.java.classpath)
141-
{
142-
if(has_suffix(cp_entry, ".jar"))
143-
{
144-
jar_index_optcreft index = read_jar_file(cp_entry);
145-
if(!index)
146-
continue;
147-
optionalt<java_bytecode_parse_treet> parse_tree =
148-
get_class_from_jar(class_name, cp_entry, *index);
149-
if(parse_tree)
150-
parse_trees.emplace_back(std::move(*parse_tree));
151-
}
152-
else
142+
switch(cp_entry.kind)
153143
{
154-
// Look in the given directory
155-
const std::string class_file = class_name_to_file(class_name);
156-
const std::string full_path =
157-
#ifdef _WIN32
158-
cp_entry + '\\' + class_file;
159-
#else
160-
cp_entry + '/' + class_file;
161-
#endif
162-
163-
if(!class_loader_limit.load_class_file(class_file))
164-
continue;
165-
166-
if(std::ifstream(full_path))
144+
case classpath_entryt::JAR:
167145
{
168-
debug()
169-
<< "Getting class `" << class_name << "' from file " << full_path
170-
<< eom;
146+
jar_index_optcreft index = read_jar_file(cp_entry.path);
147+
if(!index)
148+
continue;
171149
optionalt<java_bytecode_parse_treet> parse_tree =
172-
java_bytecode_parse(full_path, get_message_handler());
150+
get_class_from_jar(class_name, cp_entry.path, *index);
173151
if(parse_tree)
174152
parse_trees.emplace_back(std::move(*parse_tree));
175153
}
154+
break;
155+
156+
case classpath_entryt::DIRECTORY:
157+
{
158+
// Look in the given directory
159+
const std::string class_file = class_name_to_file(class_name);
160+
const std::string full_path =
161+
#ifdef _WIN32
162+
cp_entry.path + '\\' + class_file;
163+
#else
164+
cp_entry.path + '/' + class_file;
165+
#endif
166+
167+
if(std::ifstream(full_path))
168+
{
169+
debug() << "Getting class `" << class_name << "' from file "
170+
<< full_path << eom;
171+
optionalt<java_bytecode_parse_treet> parse_tree =
172+
java_bytecode_parse(full_path, get_message_handler());
173+
if(parse_tree)
174+
parse_trees.emplace_back(std::move(*parse_tree));
175+
}
176+
}
176177
}
177178
}
178179

@@ -234,12 +235,13 @@ void java_class_loadert::load_entire_jar(
234235
if(!jar_index)
235236
return;
236237

237-
jar_files.push_front(jar_path);
238+
classpath_entries.push_front(
239+
classpath_entryt(classpath_entryt::JAR, jar_path));
238240

239241
for(const auto &e : jar_index->get())
240242
operator()(e.first);
241243

242-
jar_files.pop_front();
244+
classpath_entries.pop_front();
243245
}
244246

245247
java_class_loadert::jar_index_optcreft java_class_loadert::read_jar_file(

jbmc/src/java_bytecode/java_class_loader.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,19 @@ class java_class_loadert:public messaget
7474
for(const auto &id : classes)
7575
java_load_classes.push_back(id);
7676
}
77-
void add_jar_file(const std::string &f)
77+
78+
/// Clear all classpath entries
79+
void clear_classpath()
7880
{
79-
jar_files.push_back(f);
81+
classpath_entries.clear();
8082
}
8183

84+
/// Appends an entry to the class path, used for loading classes. The
85+
/// argument may be
86+
/// 1) The name of a directory, used for searching for .class files
87+
/// 2) The name of a JAR file
88+
void add_classpath_entry(const std::string &);
89+
8290
static std::string file_to_class_name(const std::string &);
8391
static std::string class_name_to_file(const irep_idt &);
8492

@@ -111,10 +119,21 @@ class java_class_loadert:public messaget
111119
/// information.
112120
std::string java_cp_include_files;
113121

114-
/// List of filesystem paths to .jar files that will be used, in the given
115-
/// order, to find and load a class, provided its name (see \ref
116-
/// get_parse_tree).
117-
std::list<std::string> jar_files;
122+
/// An entry in the classpath
123+
struct classpath_entryt
124+
{
125+
using kindt = enum { JAR, DIRECTORY };
126+
kindt kind;
127+
std::string path;
128+
129+
classpath_entryt(kindt _kind, const std::string &_path)
130+
: kind(_kind), path(_path)
131+
{
132+
}
133+
};
134+
135+
/// List of entries in the classpath
136+
std::list<classpath_entryt> classpath_entries;
118137

119138
/// Classes to be explicitly loaded
120139
std::vector<irep_idt> java_load_classes;

0 commit comments

Comments
 (0)