How do you set a breakpoint before executing - jdi

I would like to set a breakpoint in an application before it starts to run, so that I can make sure the application does not pass the breakpoint on startup.
In order to set a breakpoint you need to do something like:
EventRequestManager reqMan = vm.eventRequestManager();
BreakpointRequest bpReq = reqMan.createBreakpointRequest(locationForBreakpoint);
bpReq.enable();
In order to get the Location for the breakpoint, you can do something like:
Method method = location.method();
List<Location> locations = method.locationsOfLine(55);
Location locationForBreakpoint = locations.get(0);
In order to get a Method you can do something like:
classType.concreteMethodByName(methodNname, String signature)
However in order to get that classType you seem to require an ObjectReference which seems to require a running JVM.
Is there any way to set the breakpoint before the application JVM runs, to be sure the breakpoint is not passed during application startup?

First of all start you target program using a LaunchingConnector to get back the target virtual machine.
VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
LaunchingConnector lc = vmm.launchingConnectors().get(0);
// Equivalently, can call:
// LaunchingConnector lc = vmm.defaultConnector();
Map<String, Connector.Argument> env = lc.defaultArguments();
env.get("main").setValue("p.DebugDummy");
env.get("suspend").setValue("true");
env.get("home").setValue("C:/Program Files/Java/jdk1.7.0_51");
VirtualMachine vm = lc.launch(env);
(change environment values according to your needs,but remember to start target VM with suspended=true).
With this VM in you hand intercept a ClassPrepareEvent using a ClassPrepareRequest.
ClassPrepareRequest r = reqMan.createClassPrepareRequest();
r.addClassFilter("myclasses.SampleClass");
r.enable();
Create a ClassPrepareEvent handler
executor.execute(()-> {
try {
while(true)
{
EventQueue eventQueue = vm.eventQueue();
EventSet eventSet = eventQueue.remove();
EventIterator eventIterator = eventSet.eventIterator();
if (eventIterator.hasNext()) {
Event event = eventIterator.next();
if(event instanceof ClassPrepareEvent) {
ClassPrepareEvent evt = (ClassPrepareEvent) event;
ClassType classType = (ClassType) evt.referenceType();
List<Location> locations = referenceType.locationsOfLine(55);
Location locationForBreakpoint = locations.get(0);
vm.resume();
}
}
}
} catch (InterruptedException | AbsentInformationException | IncompatibleThreadStateException e) {
e.printStackTrace();
}
}
then resume target VM with a call to vm.resume() to run program.
I hope this solve your problem.

Related

How do I force rebuild of all snapshot dependencies in my teamcity build trigger?

I have a list of build types in my settings.kts:
val buildChain = listOf(build1, build2, build3, ...)
I define the following chain of snapshot dependencies:
for ((previous, current) in buildChain.zip(buildChain.drop(1))) {
current.dependencies {
snapshot(previous) {
reuseBuilds = ReuseBuilds.NO
onDependencyFailure = FailureAction.FAIL_TO_START
onDependencyCancel = FailureAction.FAIL_TO_START
}
}
}
With that, build<N> depends on build<N-1>. Then I define the following build type that runs the whole build chain:
val buildChainRunner = BuildChainRunner(headOfBuildChain = buildChain.last())
where
class BuildChainRunner(
headOfBuildChain: BuildType,
) : BuildType({
name = "Build Chain Runner"
dependencies {
snapshot(headOfBuildChain) {
reuseBuilds = ReuseBuilds.NO
onDependencyFailure = FailureAction.ADD_PROBLEM
onDependencyCancel = FailureAction.ADD_PROBLEM
}
}
triggers {
schedule {
schedulingPolicy = daily {
hour = 2
minute = 0
timezone = "Europe/Amsterdam"
}
branchFilter = "+:<default>"
triggerBuild = always()
withPendingChangesOnly = false
}
}
[...]
}
Now, when the build gets triggered by the schedule trigger, it doesn't necessarily rebuilds all builds from the chain. What I would like to do is the very same as this:
I thought that would be automatically the case because of
reuseBuilds = ReuseBuilds.NO
but unfortunately, it doesn't work. When I trigger the build manually and set "rebuild snapshot dependencies" to "all", then it works as I expect. What am I doing wrong in my kotlin DSL configuration?

EPiServer 9 - Add block to new page programmatically

I have found some suggestions on how to add a block to a page, but can't get it to work the way I want, so perhaps someone can help out.
What I want to do is to have a scheduled job that reads through a file, creating new pages with a certain pagetype and in the new page adding some blocks to a content property. The blocks fields will be updated with data from the file that is read.
I have the following code in the scheduled job, but it fails at
repo.Save((IContent) newBlock, SaveAction.Publish);
giving the error
The page name must contain at least one visible character.
This is my code:
public override string Execute()
{
//Call OnStatusChanged to periodically notify progress of job for manually started jobs
OnStatusChanged(String.Format("Starting execution of {0}", this.GetType()));
//Create Person page
PageReference parent = PageReference.StartPage;
//IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
//var repository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
//var slaegtPage = repository.GetDefault<SlaegtPage>(ContentReference.StartPage);
IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();
IContentTypeRepository contentTypeRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentTypeRepository>();
SlaegtPage slaegtPage = contentRepository.GetDefault<SlaegtPage>(parent, contentTypeRepository.Load("SlaegtPage").ID);
if (slaegtPage.MainContentArea == null) {
slaegtPage.MainContentArea = new ContentArea();
}
slaegtPage.PageName = "001 Kim";
//Create block
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var newBlock = repo.GetDefault<SlaegtPersonBlock1>(ContentReference.GlobalBlockFolder);
newBlock.PersonId = "001";
newBlock.PersonName = "Kim";
newBlock.PersonBirthdate = "01 jan 1901";
repo.Save((IContent) newBlock, SaveAction.Publish);
//Add block
slaegtPage.MainContentArea.Items.Add(new ContentAreaItem
{
ContentLink = ((IContent) newBlock).ContentLink
});
slaegtPage.URLSegment = UrlSegment.CreateUrlSegment(slaegtPage);
contentRepository.Save(slaegtPage, EPiServer.DataAccess.SaveAction.Publish);
_stopSignaled = true;
//For long running jobs periodically check if stop is signaled and if so stop execution
if (_stopSignaled) {
return "Stop of job was called";
}
return "Change to message that describes outcome of execution";
}
You can set the Name by
((IContent) newBlock).Name = "MyName";

Sense/net using content query in console application

I try to use content query in console application but it throw an exception "Object reference not set to an instance of an object".
Please give help me resolve that problem.
var startSettings = new RepositoryStartSettings
{
Console = Console.Out,
StartLuceneManager = false,
IsWebContext = false,
PluginsPath = AppDomain.CurrentDomain.BaseDirectory,
};
using (Repository.Start(startSettings))
{
try
{
string path = "/Root/Sites/Default_Site/workspaces/Document/HACCP/Document_Library/SanXuat/ChonLocChuanBiDiaDiemSXRau";
string fieldName1 = "Name";
var content = Content.Load(path);
int count = ContentQuery.Query(".AUTOFILTERS:OFF .COUNTONLY Infolder:" + path).Count;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
if you want to execute a content query, you have to enable LuceneManager when you start the repository, because that component is responsible for querying.
new RepositoryStartSettings
{
Console = Console.Out,
StartLuceneManager = true, // <-- this is necessary
IsWebContext = false,
PluginsPath = AppDomain.CurrentDomain.BaseDirectory,
}
Please make sure that all the config values are in place (e.g. index directory path, enable outer search engine). You can copy them from the Export or Import tool's config file.
A few more notes:
in a content query please always enclose path expressions in quotes, because if there is a space in the path, it causes a query error that is hard to find (because it would return a different result set). For example:
InTree:'/Root/My Folder'
Or you can use the built-in parameter feature that makes sure the same:
// note the #0 parameter, which is a 0-based index
ContentQuery.Query("+TypeIs:Article +InTree:#0", null, containerPath);

How to to read input stream from Magnetic stripe reader with keyboard support in Windows 10 universal app

We have tried the approach suggested at:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn312121(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/hardware/dn303343(v=vs.85).aspx
We are able to find out list of all the magneticDevices using below code snippet
var magneticDevices = await DeviceInformation.FindAllAsync(aqsFilter);
but we are not able to get HidDevice object from the below code. It is giving null.
HidDevice device = await HidDevice.FromIdAsync(magneticDevices[0].Id
We have also set device capabilities in the app manifest file like below.
<DeviceCapability Name="humaninterfacedevice">
<Device Id="vidpid:0ACD 0520">
<Function Type="usage:0001 0006"/>
</Device>
</DeviceCapability>
<DeviceCapability Name="usb">
<Device Id="vidpid:0ACD 0520">
<Function Type="winUsbId:4d1e55b2-f16f-11cf-88cb-001111000030"/>
</Device>
</DeviceCapability>
Code for the complete Function
private async Task<bool> HasCardReader()
{
bool hasCardReader = false;
ushort usagePage = 0x0001;
ushort usageId = 0x0006;
ushort vendorId = 0x0ACD;
ushort productId = 0x0520;
var aqsFilter = HidDevice.GetDeviceSelector(usagePage, usageId, vendorId, productId);
var magneticDevices = await DeviceInformation.FindAllAsync(aqsFilter);
try
{
if (magneticDevices != null && magneticDevices.Count > 0)
{
HidDevice device = await HidDevice.FromIdAsync(magneticDevices[0].Id, Windows.Storage.FileAccessMode.Read);
inputReportEventHandler = new TypedEventHandler<HidDevice, HidInputReportReceivedEventArgs>(this.OnInputReportEvent);
device.InputReportReceived += inputReportEventHandler;
var watcher = DeviceInformation.CreateWatcher(aqsFilter);
watcher.Added += WatcherAdded;
watcher.Removed += WatcherRemoved;
watcher.Start();
hasCardReader = true;
}
else
{
}
}
catch (Exception ex)
{
Logging.LoggingSessionScenario.LogMessageAsync(ex.Message, LoggingLevel.Error);
}
return hasCardReader;
}
There are several reasons for the null return value, but I don't think there is something wrong with your code, since you can find the device by calling FindAllAsync. I will suggest you to troubleshoot this issue using this official HIDDevice sample on GitHub.
I successfully connected to my external hid device with that sample by changing the vid & pid & usagepage & usageid to my device.
In EventHandlerForDevice.cs, find the function OpenDeviceAsync, and you will notice the following possible reasons when null is returned by FromIdAsync.
else
{
successfullyOpenedDevice = false;
notificationStatus = NotifyType.ErrorMessage;
var deviceAccessStatus = DeviceAccessInformation.CreateFromId(deviceInfo.Id).CurrentStatus;
if (deviceAccessStatus == DeviceAccessStatus.DeniedByUser)
{
notificationMessage = "Access to the device was blocked by the user : " + deviceInfo.Id;
}
else if (deviceAccessStatus == DeviceAccessStatus.DeniedBySystem)
{
// This status is most likely caused by app permissions (did not declare the device in the app's package.appxmanifest)
// This status does not cover the case where the device is already opened by another app.
notificationMessage = "Access to the device was blocked by the system : " + deviceInfo.Id;
}
else
{
// Most likely the device is opened by another app, but cannot be sure
notificationMessage = "Unknown error, possibly opened by another app : " + deviceInfo.Id;
}
}
Have a try with that sample(Scenario1) and change the ids in both appxmanifest and SampleConfiguration.cs(class Device). If you cannot see your device in the device list, that means the configuration is incorrect for your device.

Using Rx to Geocode an address in Bing Maps

I am learning to use the Rx extensions for a Silverlight 4 app I am working on. I created a sample app to nail down the process and I cannot get it to return anything.
Here is the main code:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
var gsc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService") as IGeocodeService;
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var myFunc = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(gsc.BeginGeocode, gsc.EndGeocode);
gcResp = myFunc(gcr) as GeocodeResponse;
if (gcResp.Results.Count > 0 && gcResp.Results[0].Locations.Count > 0)
{
returnLocation = gcResp.Results[0].Locations[0];
}
return returnLocation as IObservable<Location>;
}
gcResp comes back as null. Any thoughts or suggestions would be greatly appreciated.
The observable source you are subscribing to is asynchronous, so you can't access the result immediately after subscribing. You need to access the result in the subscription.
Better yet, don't subscribe at all and simply compose the response:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
IGeocodeService gsc =
new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var factory = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(
gsc.BeginGeocode, gsc.EndGeocode);
return factory(gcr)
.Where(response => response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
.Select(response => response.Results[0].Locations[0]);
}
If you only need the first valid value (the location of the address is unlikely to change), then add a .Take(1) between the Where and Select.
Edit: If you want to specifically handle the address not being found, you can either return results and have the consumer deal with it or you can return an Exception and provide an OnError handler when subscribing. If you're thinking of doing the latter, you would use SelectMany:
return factory(gcr)
.SelectMany(response => (response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
? Observable.Return(response.Results[0].Locations[0])
: Observable.Throw<Location>(new AddressNotFoundException())
);
If you expand out the type of myFunc you'll see that it is Func<GeocodeRequest, IObservable<GeocodeResponse>>.
Func<GeocodeRequest, IObservable<GeocodeResponse>> myFunc =
Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>
(gsc.BeginGeocode, gsc.EndGeocode);
So when you call myFunc(gcr) you have an IObservable<GeocodeResponse> and not a GeocodeResponse. Your code myFunc(gcr) as GeocodeResponse returns null because the cast is invalid.
What you need to do is either get the last value of the observable or just do a subscribe. Calling .Last() will block. If you call .Subscribe(...) your response will come thru on the call back thread.
Try this:
gcResp = myFunc(gcr).Last();
Let me know how you go.
Richard (and others),
So I have the code returning the location and I have the calling code subscribing. Here is (hopefully) the final issue. When I call GetGPSCoordinates, the next statement gets executed immediately without waiting for the subscribe to finish. Here's an example in a button OnClick event handler.
Location newLoc = new Location();
GetGPSCoordinates(this.Input.Text).ObserveOnDispatcher().Subscribe(x =>
{
if (x.Results.Count > 0 && x.Results[0].Locations.Count > 0)
{
newLoc = x.Results[0].Locations[0];
Output.Text = "Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
}
else
{
Output.Text = "Invalid address";
}
});
Output.Text = " Outside of subscribe --- Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
The Output.Text assignment that takes place outside of Subscribe executes before the Subscribe has finished and displays zeros and then the one inside the subscribe displays the new location info.
The purpose of this process is to get location info that will then be saved in a database record and I am processing multiple addresses sequentially in a Foreach loop. I chose Rx Extensions as a solution to avoid the problem of the async callback as a coding trap. But it seems I have exchanged one trap for another.
Thoughts, comments, suggestions?