@@ -78,72 +78,136 @@ def investigate_test(test_name: str, release_mode: bool):
7878
7979 # Handle the case where no custom target JSON is used ('use_target_json.flag' doesn't exist)
8080 if not os .path .exists (use_target_json ):
81- print ("|---- Found 'use_target_json.flag', searching for JAR in standard deps folder..." )
82- deps_dir = os .path .join (test_dir , "target" , target_dir , "deps" )
81+ print ("|---- No 'use_target_json.flag' found , searching for JAR in standard deps folder..." )
82+ deps_dir_temp = os .path .join (test_dir , "target" , target_dir , "deps" )
8383 jar_file_name = None
84- if os .path .isdir (deps_dir ):
85- for file in os .listdir (deps_dir ):
84+ if os .path .isdir (deps_dir_temp ):
85+ for file in os .listdir (deps_dir_temp ):
8686 if file .startswith (test_name ) and file .endswith (".jar" ):
8787 jar_file_name = file
8888 break
8989
90- if jar_file_name is None :
91- print (f"|---- ❌ No JAR file found in { deps_dir } . Cannot continue." )
92- return
93-
94- # Move the jar to the location expected by the rest of the script for consistency
95- src_path = os .path .join (deps_dir , jar_file_name )
96- dest_dir = os .path .join (test_dir , "target" , "jvm-unknown-unknown" , target_dir )
97- os .makedirs (dest_dir , exist_ok = True )
98- dest_path = os .path .join (dest_dir , f"{ test_name } .jar" )
99- shutil .move (src_path , dest_path )
100- print (f"|---- Moved JAR to { dest_path } " )
90+ if jar_file_name is not None :
91+ # Move the jar to the location expected by the rest of the script for consistency
92+ src_path = os .path .join (deps_dir_temp , jar_file_name )
93+ dest_dir = os .path .join (test_dir , "target" , "jvm-unknown-unknown" , target_dir )
94+ os .makedirs (dest_dir , exist_ok = True )
95+ dest_path = os .path .join (dest_dir , f"{ test_name } .jar" )
96+ shutil .move (src_path , dest_path )
97+ print (f"|---- Moved JAR to { dest_path } " )
98+ else :
99+ print (f"|---- ⚠️ No JAR file found in { deps_dir_temp } . Will attempt to use raw classfiles later." )
101100
102101 jar_path = os .path .join (test_dir , "target" , "jvm-unknown-unknown" , target_dir , f"{ test_name } .jar" )
103102
103+ # Check if JAR exists, if not fall back to using raw classfiles from deps
104+ use_raw_classfiles = False
105+ deps_dir = None
106+
104107 if not os .path .exists (jar_path ):
105- print (f"|---- ❌ JAR file not found at expected path: { jar_path } " )
106- print ("|---- Investigation cannot proceed without a JAR file. Exiting." )
107- return
108+ print (f"|---- ⚠️ JAR file not found at expected path: { jar_path } " )
109+ print ("|---- Attempting to use raw .class files from deps directory..." )
108110
109- print (f"|---- ✅ Found JAR: { jar_path } " )
110-
111- # 6. Analyze the JAR file
112- # 6a. `jar tf` - List JAR contents
113- print ("|-- 🔍 Listing JAR contents (jar tf)..." )
114- proc = run_command (["jar" , "tf" , jar_path ])
115- write_to_file (os .path .join (investigation_dir , "jar_contents.txt" ), proc .stdout )
116-
117- # 6b. `jar xf` - Extract JAR
118- print ("|-- 📦 Extracting JAR contents for analysis..." )
119- run_command (["jar" , "xf" , os .path .abspath (jar_path )], cwd = extracted_jar_dir )
120-
121- # 6c. `javap -v -p` on all .class files
122- print ("|-- 뜯 Decompiling .class files (javap -v -p)..." )
123- class_count = 0
124- for root , _ , files in os .walk (extracted_jar_dir ):
125- for file in files :
111+ # Fall back to using the deps directory
112+ deps_dir = os .path .join (test_dir , "target" , target_dir , "deps" )
113+ if os .path .exists (deps_dir ):
114+ main_class = os .path .join (deps_dir , f"{ test_name } .class" )
115+ if os .path .exists (main_class ):
116+ print (f"|---- ✅ Found main class file: { main_class } " )
117+ print (f"|---- Continuing investigation with raw classfiles from: { deps_dir } " )
118+ use_raw_classfiles = True
119+ else :
120+ print (f"|---- ❌ Main class file not found: { main_class } " )
121+ print ("|---- Investigation cannot proceed. Exiting." )
122+ return
123+ else :
124+ print (f"|---- ❌ Deps directory not found: { deps_dir } " )
125+ print ("|---- Investigation cannot proceed. Exiting." )
126+ return
127+ else :
128+ print (f"|---- ✅ Found JAR: { jar_path } " )
129+
130+ # 6. Analyze the class files
131+ if use_raw_classfiles and deps_dir is not None :
132+ # Using raw classfiles from deps directory
133+ print ("|-- 📋 Listing class files from deps directory..." )
134+ class_files = []
135+ for file in os .listdir (deps_dir ):
126136 if file .endswith (".class" ):
127- class_count += 1
128- class_file_path = os .path .join (root , file )
129- relative_path = os .path .relpath (class_file_path , extracted_jar_dir )
130-
131- # Create a mirrored directory structure for the output
132- output_path_dir = os .path .join (javap_dir , os .path .dirname (relative_path ))
133- output_file_path = os .path .join (output_path_dir , os .path .basename (relative_path ).replace (".class" , ".javap.txt" ))
134-
135- # Run javap on the .class file
136- proc = run_command (["javap" , "-v" , "-p" , class_file_path ])
137- output_content = f"--- COMMAND ---\n javap -v -p { class_file_path } \n \n --- STDOUT ---\n { proc .stdout } \n \n --- STDERR ---\n { proc .stderr } "
138- write_to_file (output_file_path , output_content )
139-
140- print (f"|---- ✅ Decompiled { class_count } class file(s)." )
137+ class_files .append (file )
138+
139+ contents_txt = "\n " .join (sorted (class_files ))
140+ write_to_file (os .path .join (investigation_dir , "class_files_list.txt" ), contents_txt )
141+ print (f"|---- Found { len (class_files )} class file(s)" )
142+
143+ # Copy class files to extracted_jar_dir for consistency
144+ print ("|-- 📦 Copying class files for analysis..." )
145+ for file in class_files :
146+ src = os .path .join (deps_dir , file )
147+ dst = os .path .join (extracted_jar_dir , file )
148+ shutil .copy (src , dst )
149+
150+ # 6c. `javap -v -p` on all .class files
151+ print ("|-- 뜯 Decompiling .class files (javap -v -p)..." )
152+ class_count = 0
153+ for file in class_files :
154+ class_count += 1
155+ class_file_path = os .path .join (extracted_jar_dir , file )
156+ output_file_path = os .path .join (javap_dir , file .replace (".class" , ".javap.txt" ))
157+
158+ # Run javap on the .class file
159+ proc = run_command (["javap" , "-v" , "-p" , class_file_path ])
160+ output_content = f"--- COMMAND ---\n javap -v -p { class_file_path } \n \n --- STDOUT ---\n { proc .stdout } \n \n --- STDERR ---\n { proc .stderr } "
161+ write_to_file (output_file_path , output_content )
162+
163+ print (f"|---- ✅ Decompiled { class_count } class file(s)." )
164+ else :
165+ # Using JAR file
166+ # 6a. `jar tf` - List JAR contents
167+ print ("|-- 🔍 Listing JAR contents (jar tf)..." )
168+ proc = run_command (["jar" , "tf" , jar_path ])
169+ write_to_file (os .path .join (investigation_dir , "jar_contents.txt" ), proc .stdout )
170+
171+ # 6b. `jar xf` - Extract JAR
172+ print ("|-- 📦 Extracting JAR contents for analysis..." )
173+ run_command (["jar" , "xf" , os .path .abspath (jar_path )], cwd = extracted_jar_dir )
174+
175+ # 6c. `javap -v -p` on all .class files
176+ print ("|-- 뜯 Decompiling .class files (javap -v -p)..." )
177+ class_count = 0
178+ for root , _ , files in os .walk (extracted_jar_dir ):
179+ for file in files :
180+ if file .endswith (".class" ):
181+ class_count += 1
182+ class_file_path = os .path .join (root , file )
183+ relative_path = os .path .relpath (class_file_path , extracted_jar_dir )
184+
185+ # Create a mirrored directory structure for the output
186+ output_path_dir = os .path .join (javap_dir , os .path .dirname (relative_path ))
187+ output_file_path = os .path .join (output_path_dir , os .path .basename (relative_path ).replace (".class" , ".javap.txt" ))
188+
189+ # Run javap on the .class file
190+ proc = run_command (["javap" , "-v" , "-p" , class_file_path ])
191+ output_content = f"--- COMMAND ---\n javap -v -p { class_file_path } \n \n --- STDOUT ---\n { proc .stdout } \n \n --- STDERR ---\n { proc .stderr } "
192+ write_to_file (output_file_path , output_content )
193+
194+ print (f"|---- ✅ Decompiled { class_count } class file(s)." )
141195
142196 # 7. Run with Java and capture output
143197 print ("|-- 🤖 Running with Java and capturing logs..." )
144198 # This classpath is copied from the original script. It assumes the script is run from the project root.
145- classpath = f"library/build/distributions/library-0.1.0/lib/library-0.1.0.jar:library/build/distributions/library-0.1.0/lib/kotlin-stdlib-2.1.20.jar:{ jar_path } "
146- java_cmd = ["java" , "-cp" , classpath , test_name ]
199+ runtime_libs = "library/build/distributions/library-0.1.0/lib/library-0.1.0.jar:library/build/distributions/library-0.1.0/lib/kotlin-stdlib-2.1.20.jar"
200+
201+ if use_raw_classfiles and deps_dir is not None :
202+ # Use deps directory in classpath instead of JAR
203+ # Use -noverify because stackmap frames aren't generated yet
204+ classpath = f"{ runtime_libs } :{ deps_dir } "
205+ print (f"|---- Using deps directory in classpath: { deps_dir } " )
206+ java_cmd = ["java" , "-noverify" , "-cp" , classpath , test_name ]
207+ else :
208+ # Use JAR file
209+ classpath = f"{ runtime_libs } :{ jar_path } "
210+ java_cmd = ["java" , "-cp" , classpath , test_name ]
147211
148212 proc = run_command (java_cmd )
149213
0 commit comments