1 /*
2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 4836939 6646613
27  * @summary JDI add addSourceNameFilter to ClassPrepareRequest
28  * @author jjh
29  *
30  * @run build TestScaffold VMConnection TargetListener TargetAdapter
31  * @run compile -g SourceNameFilterTest.java
32  * @run driver SourceNameFilterTest
33  * @run compile -g:none SourceNameFilterTest.java
34  * @run driver SourceNameFilterTest
35  */
36 // The compile -g:none suppresses the lineNumber table to trigger bug 6646613.
37 
38 import com.sun.jdi.*;
39 import com.sun.jdi.event.*;
40 import com.sun.jdi.request.*;
41 
42 import java.util.*;
43 
44     /********** target program **********/
45 
46 class SourceNameFilterTarg {
bkpt()47     static  void bkpt() {
48     }
49 
main(String[] args)50     public static void main(String[] args){
51         System.out.println("Howdy!");
52 
53         LoadedLater1.doit();
54         bkpt();
55 
56         LoadedLater2.doit();
57         bkpt();
58 
59         LoadedLater3.doit();
60         bkpt();
61         System.out.println("Goodbye from SourceNameFilterTarg!");
62     }
63 }
64 class LoadedLater1 {
doit()65     public static void doit() {
66         System.out.println("didit1");
67     }
68 }
69 
70 class LoadedLater2 {
doit()71     public static void doit() {
72         System.out.println("didit2");
73     }
74 }
75 
76 class LoadedLater3 {
doit()77     public static void doit() {
78         System.out.println("didit3");
79     }
80 }
81 
82     /********** test program **********/
83 
84 public class SourceNameFilterTest extends TestScaffold {
85     ReferenceType targetClass;
86     ThreadReference mainThread;
87     boolean gotEvent1 = false;
88     boolean gotEvent2 = false;
89     boolean gotEvent3 = false;
90     ClassPrepareRequest cpReq;
91     boolean shouldResume = false;
SourceNameFilterTest(String args[])92     SourceNameFilterTest (String args[]) {
93         super(args);
94     }
95 
main(String[] args)96     public static void main(String[] args)      throws Exception {
97         new SourceNameFilterTest(args).startTests();
98     }
eventSetComplete(EventSet set)99     public void eventSetComplete(EventSet set) {
100         //System.out.println("jj: resuming, set = " + set);
101         if (shouldResume) {
102             set.resume();
103             shouldResume = false;
104         }
105     }
106 
classPrepared(ClassPrepareEvent event)107     public void classPrepared(ClassPrepareEvent event) {
108         shouldResume = true;
109 
110         ReferenceType rt = event.referenceType();
111         String rtname = rt.name();
112 
113         if (rtname.equals("LoadedLater1")) {
114             gotEvent1 = true;
115         }
116 
117         if (rtname.equals("LoadedLater2")) {
118             gotEvent2 = true;
119         }
120 
121         if (rtname.equals("LoadedLater3")) {
122             gotEvent3 = true;
123         }
124 
125         // debug code
126         if (false) {
127             println("Got ClassPrepareEvent for : " + rtname);
128             try {
129                 println("    sourceName = " + rt.sourceName());
130             } catch (AbsentInformationException ee) {
131                 failure("failure: absent info on sourceName(): " + ee);
132             }
133 
134             String stratum = rt.defaultStratum();
135             println("    defaultStratum = " + stratum);
136 
137             try {
138                 println("    sourceNames = " + rt.sourceNames(stratum));
139             } catch (AbsentInformationException ee) {
140                 failure("failure: absent info on sourceNames(): " + ee);
141             }
142             println("\nAvailable strata:  " + rt.availableStrata());
143         }
144     }
145 
146 
147     /********** test core **********/
148 
runTests()149     protected void runTests() throws Exception {
150         /*
151          * Get to the top of main()
152          * to determine targetClass and mainThread
153          */
154         BreakpointEvent bpe = startToMain("SourceNameFilterTarg");
155         targetClass = bpe.location().declaringType();
156         boolean noSourceName = false;
157         try {
158             targetClass.sourceName();
159         } catch (AbsentInformationException ee) {
160             noSourceName = true;
161         }
162         if (noSourceName) {
163             println("-- Running with no source names");
164         } else {
165             println("-- Running with source names");
166         }
167 
168         mainThread = bpe.thread();
169         EventRequestManager erm = vm().eventRequestManager();
170         addListener(this);
171 
172         /*
173          * Resume the target listening for events
174          * This should cause a class prepare event for LoadedLater1
175          */
176         cpReq = erm.createClassPrepareRequest();
177         cpReq.enable();
178         resumeTo("SourceNameFilterTarg", "bkpt", "()V");
179 
180         /*
181          * This should cause us to not get a class prepared for
182          * LoadedLater2 since it doesn't come from "jj"
183          */
184         cpReq.disable();
185         cpReq.addSourceNameFilter("jj");
186         cpReq.enable();
187         resumeTo("SourceNameFilterTarg", "bkpt", "()V");
188         cpReq.disable();
189 
190         /*
191          * This should cause us to get a class prepare event for
192          * LoadedLater3 except in the case where -g:none
193          * was used to compile so that there is no LineNumberTable
194          * and therefore, no source name for the class.
195          */
196         cpReq = erm.createClassPrepareRequest();
197         cpReq.addSourceNameFilter("SourceNameFilterTest.java");
198         cpReq.enable();
199         resumeTo("SourceNameFilterTarg", "bkpt", "()V");
200 
201         listenUntilVMDisconnect();
202 
203         if (!gotEvent1) {
204             failure("failure: Did not get a class prepare request " +
205                     "for LoadedLater1");
206         }
207 
208         if (gotEvent2) {
209             failure("failure: Did get a class prepare request " +
210                     "for LoadedLater2");
211         }
212 
213         if (gotEvent3 && noSourceName) {
214             failure("failure: Did get a class prepare request " +
215                     "for LoadedLater3");
216         }
217         else if (!gotEvent3 && !noSourceName) {
218             failure("failure: Did not get a class prepare request " +
219                     "for LoadedLater3");
220         }
221 
222         /*
223          * deal with results of test
224          * if anything has called failure("foo") testFailed will be true
225          */
226         if (!testFailed) {
227             println("SourceNameFilterTest: passed");
228         } else {
229             throw new Exception("SourceNameFilterTest: failed");
230         }
231     }
232 }
233