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 {
  47     static  void bkpt() {
  48     }
  49 
  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 {
  65     public static void doit() {
  66         System.out.println("didit1");
  67     }
  68 }
  69 
  70 class LoadedLater2 {
  71     public static void doit() {
  72         System.out.println("didit2");
  73     }
  74 }
  75 
  76 class LoadedLater3 {
  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;
  92     SourceNameFilterTest (String args[]) {
  93         super(args);
  94     }
  95 
  96     public static void main(String[] args)      throws Exception {
  97         new SourceNameFilterTest(args).startTests();
  98     }
  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 
 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 
 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 }