SSJS to call a method in java class (in java library) - xpages

I've created a java library (named: invoke) with a java class (Invoke). Its seen when expanding Script libraries under code in the designer navigation pane.
The code is:
package com.kkm.vijay;
public class Invoke {
public static void main(String[] args) {
Runtime r = Runtime.getRuntime();
Process p = r.exec("C://some.exe");
}
}
Used the following ssjs to an onclick event of a button shows Error:500 when previewed in browser.
importPackage(com.kkmsoft.vijay);
var v=new Invoke();
v.main();
Even i used a function inside the class and changed the last line of ssjs to v.fn(). Yet the same problem.

There are a number of things wrong, and as Fredrik mentions you should switch on the standard Error page.
Your first code won't run because it is not correctly capturing the Exception. You are also using a main() method, which is normally used to execute a program. But you are calling it without any arguments. Avoid using that method unless it is for executing an application.
So change it to this:
package com.kkm.vijay;
import java.io.IOException;
public class Invoke {
public void mainCode() {
Runtime r = Runtime.getRuntime();
try {
Process p = r.exec("C://WINDOWS//notepad.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
You should put that code in the new Java view in Designer.
Next your button code needs to change.
var v=new com.kkm.vijay.Invoke();
v.mainCode();
Testing that it should work fine. The issue next is, as it is SSJS the application will execute on the server. There may be security implications in this, and it may need you to modify the java.policy file in order to do this.
The related permission will be java.io.FilePermission.

Related

How can I execute code from the Release / Release All buttons in the Release AR Documents screen

I've got a customization to the Invoice & Memo screen where I execute some custom code (web service calls) when the Release action is activated. This works fine - I knew how to replace the PXAction code and proceeded from there. Now I want to use the Release AR Documents processing screen to do the same thing, but I'm having trouble understanding where / what to override, or where to place my code.
I see the ARDocumentRelease graph constructor with the SetProcessDelegate in the source code, but I'm not sure how to proceed - whether this is where I need to be looking or not. I need to execute my code for each line being released, using the RefNbr in my code.
Since it's an static method, you can't override it. Also, you can't do like it's done in the T300, because you are in processing graph and you can't override the release button with your own. I was able to achieve it by passing callback for each AR document that have been processed.
You can call the Initialize method of the ARDocumentRelease graph to override the logic like you said. After you just have to call ReleaseDoc that uses a callback parameter instead of using the default one.
Here's the code that I came with:
public class ARDocumentRelease_Extension : PXGraphExtension<ARDocumentRelease>
{
public override void Initialize()
{
ARSetup setup = Base.arsetup.Current;
Base.ARDocumentList.SetProcessDelegate(
delegate (List<BalancedARDocument> list)
{
List<ARRegister> newlist = new List<ARRegister>(list.Count);
foreach (BalancedARDocument doc in list)
{
newlist.Add(doc);
}
AddAdditionalLogicToRelease(newlist);
}
);
Base.ARDocumentList.SetProcessCaption("Release");
Base.ARDocumentList.SetProcessAllCaption("Release All");
}
public delegate void PostPorcessing(ARRegister ardoc, bool isAborted);
private void AddAdditionalLogicToRelease(List<ARRegister> newlist)
{
ARDocumentRelease.ReleaseDoc(newlist, true, null, delegate(ARRegister ardoc, bool isAborted) {
//Add your logic to handle each document
//Test to check if it was not aborted
});
}
}
Please note that you must always call static methods from within long running process and create necessary objects there.
Processing delegate logic is implemented as long running process which creates worker thread to execute the processing logic.
You have AddAdditionalLogicToRelease() method which requires object instance in order to call and will fail during thread context switches and hence the issue. So, you must have create object instance inside the thread context and then call instance method.
In general, method that gets called from long running processes are declared static and required objects/graphs are created inside this static method to do some work. See below example how to properly override ARDocumentRelease graph for this purpose:
public class ARDocumentRelease_Extension : PXGraphExtension<ARDocumentRelease>
{
public override void Initialize()
{
Base.ARDocumentList.SetProcessDelegate(
delegate (List<BalancedARDocument> list)
{
List<ARRegister> newlist = new List<ARRegister>(list.Count);
foreach (BalancedARDocument doc in list)
{
newlist.Add(doc);
}
// use override that allows to specify onsuccess routine
ARDocumentRelease.ReleaseDoc(newlist, true, null, (ardoc, isAborted) =>
{
//Custom code here, such as create your GL
});
}
);
}
}
I think it's the function
public static void ReleaseDoc(List<ARRegister> list, bool isMassProcess, List<Batch> externalPostList, ARMassProcessDelegate onsuccess)
under ARDocumentRelease businesss logic.

BeforeFeature/AfterFeature does not work using SpecFlow and Coded UI

I am not able to define a [BeforeFeature]/[AfterFeature] hook for my feature file. The application under test is WPF standalone desktop applications.
If I use [BeforeScenario]/[AfterScenario] everything works fine, the application starts without any problem, the designed steps are performed correctly and the app is closed.
Once I use the same steps with [BeforeFeature]/[AfterFeature] tags the application starts and the test fails with:
The following error occurred when this process was started: Object reference not set to an instance of an object.
Here is an example:
[Binding]
public class Setup
{
[BeforeScenario("setup_scenario")]
public static void BeforeAppScenario()
{
UILoader.General.StartApplication();
}
[AfterScenario("setup_scenario")]
public static void AfterAppScenario()
{
UILoader.General.CloseApplication();
}
[BeforeFeature("setup_feature")]
public static void BeforeAppFeature()
{
UILoader.General.StartApplication();
}
[AfterFeature("setup_feature")]
public static void AfterAppFeature()
{
UILoader.General.CloseApplication();
}
}
StartApplication/CloseApplication were recorded and auto-generated with Coded UI Test Builder:
public void StartApplication()
{
// Launch '%ProgramFiles%\...
ApplicationUnderTest Application = ApplicationUnderTest.Launch(this.StartApplicationParams.ExePath, this.StartApplicationParams.AlternateExePath);
}
public class StartApplicationParams
{
public string ExePath = "C:\\Program Files..."
public string AlternateExePath = "%ProgramFiles%\\..."
}
Noteworthy: I'm quite new with SpecFlow.
I can't figure it out why my test fails with [BeforeFeature] and works fine with [BeforeScenario].
It would be great if somebody could help me with this issue. Thanks!
I ran into a similar problem recently. Not sure if this can still help you, but it may be of use for people who stumble upon this question.
For BeforeFeature\AfterFeature to work, the feature itself needs to be tagged, tagging just specific scenarios will not work.
Your feature files should start like this:
#setup_feature
Feature: Name Of Your Feature
#setup_scenario
Scenario: ...

Exception when trying to show a form created in another (background) thread on .netCF with OAC

In a multi form .NetCF 3.5 application I'm trying create the forms in the background while the user is occupied with the previous form.
We're using Orientation Aware Control in the project
We use a wrapper class (FormController) (please let me know if I'm using the wrong terminology) to keep static references to the different forms in our application. Since we only want to create them once.
At the moment the Forms are created the first time they are used. But since this is a time consuming operation we'd like to do this in the background while the user
Application.Run(new FormController.StartUI());
class FormController{
private static object lockObj = new object();
private static bool secIsLoaded = false;
private static StartForm startForm = new StartForm();
private static SecForm m_SecForm;
static SecForm FormWorkOrderList
{
get
{
CreateSecForm();
return m_SecForm;
}
}
private static void StartUI(){
startForm.Show();
ThreadStart tsSecForm = CreateSecForm;
Thread trSecForm = new Thread(tsSecForm);
trSecForm.Priority = ThreadPriority.BelowNormal;
trSecForm.IsBackground = true;
trSecForm.Start();
return startForm;
}
private static void CreateSecForm()
{
Monitor.Enter(lockObj);
if(!secIsLoaded){
m_SecForm = new SecForm();
secIsLoaded = true;
}
Monitor.Exit(lockObj);
}
private static void GotoSecForm()
{
SecForm.Show();
StartForm.Hide();
}
When I call GotoSecForm() the program throws an excepton on SecForm.Show() with an exection with hResult: 2146233067 and no other valuable information.
The stacktrace of the exception is:
on Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
on System.Windows.Forms.Control.SuspendLayout()
on b..ctor(OrientationAwareControl control)
on Clarius.UI.OrientationAwareControl.ApplyResources(CultureInfo cultureInfo, Boolean skipThis)
on Clarius.UI.OrientationAwareControl.ApplyResources()
on Clarius.UI.OrientationAwareControl.OnLoad(EventArgs e)
on Clarius.UI.OrientationAwareControl.c(Object , EventArgs )
on System.Windows.Forms.Form.OnLoad(EventArgs e)
on System.Windows.Forms.Form._SetVisibleNotify(Boolean fVis)
on System.Windows.Forms.Control.set_Visible(Boolean value)
on System.Windows.Forms.Control.Show()
I'm quite qlueless about what's going wrong here. Can anyone help me out?
Or are there some better ways to load the forms in the background?
Let me know if any more information is needed.
You can't create forms (or safely do any manipulation of controls or forms) in background threads. They need to be created on the same thread that the message pump is running on - its just the way that Windows Forms work.
Creating the form itself shouldn't be in itself an expensive task. My advice would be to perform any expensive computations needed to display the form in a background thread, and then pass the result of those computations back to the main message pump in order to create and display the form itself.
(Half way through writing this I realised that this question is about windows mobile, however I'm 99% sure that the above still applies in this situation)

Multiple instances of j2me midlet problem

I have a j2me midlet running on a cell phone. The code works fine, but the issue that comes up is that the program seems to be running more than one instance of itself. I have code at the beginning of the application inside the appStart() method that runs twice when the application starts. During the lifetime of the program, the code can be seen running twice when text is written to the screen.
The code looks like this:
public MyClass()
{
form = new Form("MyProgram");
cmdClose = new Command("EXIT", Command.EXIT, 1);
form.addCommand(cmdClose);
form.setCommandListener(this);
display = Display.getDisplay(this);
display.setCurrent(form);
}
public void startApp()
{
form.append("App starting\n");
// Rest of program
}
I have no idea why the code is being called twice.
I'm coding on the i290.
This is definitely a JVM bug. startApp() should be called only once at startup and can't be called again until pauseApp() is called or you call notifyPaused() yourself.
What I suggest is the following code:
private boolean midletStarted = false;
public void startApp() {
if (!midletStarted) {
midletStarted = true;
//Your code
}
}
This way you can track midlet state changes. But in fact it is better that you don't use this method at all and use constructor instead.
Oh, by the way, I don't think that there are some multiple instances or something like that, this is merely a JVM error.
Maybe you did something that made the runtime call pauseApp() and then when you set the focus to the app the runtime called startApp() again.
Put logging in pauseApp() and see what happens.

DNN 5 - Can't get current ModuleId from nested user control in custom module

I'm writing a custom module for DNN 5, and I need a "Manage" link to be on every control in the module. I created a new UserControl ("ManagerLink") that inherits from PortalModuleBase, put my link into that control, and dropped that control on ALL OF MY MAIN CONTROLS.
The problem is that ModuleId and TabId are always -1 in "ManagerLink" nested control. PortalId works just fine, and I can get a TabId by doing PortalSettings.ActiveTab.TabID.
Why can't I get ModuleId and TabId in from "ManagerLink" control, even though it inherits from PortalModuleBase?
Is there an alternative method to get ModuleId (equivalent of PortalSettings.ActiveTab.TabID)
UPDATE 2014:
Just saw another answer that's way better than the original (and accepted it).
If you're using DNN 6 and earlier, replace ModuleBase with PortalModuleBase
William Severance from DNN forum answered this one for me, I'll post the answer here as well.
Since the child control inherits from PortalModuleBase, I would do the
following in the Page_Load handler of
the parent control
Note: ManagerLink is assumed to be a reference to the child control
VB.NET:
With ManagerLink
.ModuleConfiguration = Me.ModuleConfiguration
.LocalResourceFile = Me.LocalResourceFile
End With
C#:
protected void Page_Load(System.Object sender, System.EventArgs e)
{
ManagerLink.ModuleConfiguration = this.ModuleConfiguration;
ManagerLink.LocalResourceFile = this.LocalResourceFile
}
The above allows the child control to use the parent's ModuleConfiguration (which will include ModuleId) and LocalResourceFile for any localization.
I just wanted to add my 2 cents here, using the answer of #roman-m and extending on it,
I was able to do it in the nested control itself like so:
//fires first in the sequence, calling initialise components
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
//this binds a handler to the parent's init event
this.Parent.Init += new EventHandler(this.Parent_Init);
}
//the handler gets called, at this point we can cast the parent as a module base
//and load the configuration and resource file into the nested control
private void Parent_Init(object sender, System.EventArgs e)
{
this.ModuleConfiguration = ((ModuleBase)this.Parent).ModuleConfiguration;
this.LocalResourceFile = ((ModuleBase)this.Parent).LocalResourceFile;
}
This means that in the Page_Load event of the nested control it will already have the configuration and local resource file on hand.
It also means you don't have to load the configuration and local resource file in on every parent control which uses the child control.
This will only work when the parent is of type ModuleBase of course
And to be even more specific, this works in version 7.00.06

Resources