nashorn call java from script 4 hour I did not expect to waste - nashorn

This works:
interpreter.eval("var myCls = Java.type('java.io.File');\n"+"myCls.createTempFile('nashorn','.tmp');", sc1 );
But this does not:
interpreter.eval("var myCls = Java.type('mypkg.MyClass');\n"+"myCls.play('misty');", sc1 );
Why?
P

Okay after 6 or so hours of faffing, it turns out that
not only does the method need to be public and static, the
class itself needs to be public.
More relevant error messages would be nice.

Related

Locking thread conditionally and processing each time only one code

Firstly, new thread born independently of my code by external factory.
I have something integer key variable - "CODE". This variable "CODE" I received as result of a lot of calculating and request to DB (and maybe I need multi-threading protection of this "CODE").
I need lock thread only for the same "CODE", if currently "CODE" is handling now, thread with other "CODE" can not locking and handling without obstacle.
Thread with "CODE" now handling and locking need to immediately finish.
Also all this function must be working asynchronously with ASYNC/AWAIT.
I am using .NET Core 6.
It looks like a very common task, but what mechanism do I need to use?
Does code template for this task exist in inet?
This is my solution, but I'm not sure how it working with high uploading. I only try to test this code with high concurrency. If anybody has advice for me, please.
I realize solution with ConcurrentDictionary and locking critical section. To unlock main locker and using secondary locker I created new task.
This is schema of my solution.
Public Sub New(ByVal logger As ILogger(...)
....
WorkingServer = New ConcurrentDictionary(Of Integer, BashJob)()
WorkingVm = New ConcurrentDictionary(Of Integer, BashJob)()
End Sub
Private WorkingServer As ConcurrentDictionary(Of Integer, BashJob)
Private RequestNextJob As New Object
Public Async Function Execute(context As IJobExecutionContext) As Task Implements IJob.Execute
_logger.LogInformation($"Time {Now}")
Interlocked.Increment(Counter)
SyncLock RequestNextJob
' calculate CODE hidden in NextJob
...
Dim NextJob As BashJob = Res1.Result.Item1(0)
Dim Val1 As BashJob
Dim ServerWorking As Boolean = WorkingServer.TryGetValue(NextJob.toServer, Val1)
If Not ServerWorking Then
Dim AddSucess1 = WorkingServer.TryAdd(NextJob.toServer, NextJob)
If AddSucess1 Then
Dim ServerThread = New Thread(Sub() ServerJob(NextJob, New ServerClosure))
ServerThread.Start()
Else
Exit Function
End If
Else
Exit Function
End If
End SyncLock
End Function
Async Sub ServerJob(ByVal Prm As BashJob, ByVal Closure As ServerClosure)
Try
Closure.Res = Sql.ExecNonQuery(...)
...
'main processor
...
WorkingServer.TryRemove(Prm.toServer, Prm)
Catch ex As Exception
_logger.LogInformation($"ServerSsh ({Counter.ToString}) {Now.ToString} Server:{Prm.toServer} {Prm.i}:[{Prm.Command}] GettingError {ex.Message}")
Finally
WorkingServer.TryRemove(Prm.toServer, Prm)
End Try
End Sub
End Class
Public Class ServerClosure
Property Res As Integer
Property Server As ServerBashAsync
Property Connect As Tuple(Of Renci.SshNet.SshClient, Exception, Exception)
Property BashRet As Task(Of String)
Property IsCompleted As Integer
Property IsCompletedWithErr As Integer
End Class

Advanced Edit of TDocument locks up the UI

My Caliburn Micro UI gets locked up because of a rather advanced set of controls contained in a TDocument. I have tried several different Async approaches to move the activity to another thread, but without success. Here is a simplified view of the code. You may recognize it because it is taken from the Hello Screens sample application.
To see briefly how the Document Conductor Works, here is the interface:
Public MustInherit Class DocumentWorkspace(Of TDocument As {Class, INotifyPropertyChanged, IDeactivate, IHaveDisplayName})
Inherits Conductor(Of TDocument).Collection.OneActive
Implements IDocumentWorkspace
Protected Sub New()
Public MustOverride ReadOnly Property Icon As String Implements IWorkspace.Icon
Public MustOverride Property IconName As String Implements IWorkspace.IconName
Public Property PixelLabTransitions As BindableCollection(Of Transition)
Public Property ScreenTransition As Transition
Public Property State As DocumentWorkspaceState
Public Property Status As String Implements IWorkspace.Status
Protected ReadOnly Property Conductor As IConductor
Public Overrides Sub ActivateItem(item As TDocument)
Public Sub Edit(child As TDocument)
Public Sub Hide()
Public Sub Show() Implements IWorkspace.Show
End Class
Here is the offending code:
_SelectedDesignerElement = value
'adjust Count located next to Icon
vm.DisplayName = value.DesignerDisplayText
count += 1
vm.IsDirty = True
'the next line of code works but
'disables the UI for a long time
Edit(vm)
So the simplest way I can show the problem is to try to move this long activity to another thread:
'Plan to show a Busy indicator here
'Below I have tried to move the edit to another thread
'but this simply does not work
Dim t As Task = Task.Factory.StartNew(Sub()
Edit(vm)
End Sub)
t.Wait()
'Plan to remove Busy indicator here
Does anyone have a better idea how to free up the UI for this long winded process?
BTW The problem is clearly the fact that the Edit(VM) is not happy on another thread, because I tested the same approach with a Busy indicator using just a counter to create a delay and the Start Busy / End Busy work just fine and the UI remains responsive.
The epiphany happened after I awoke in the middle of the night.
The Hello Screens Project was imported into a current version of Visual Studio (2015) but it never dawned on me that the targeted Framework would remain the same as the original project. So the Framework was pointing to a version prior to Async and Await support.
I have completed adding a Public Domain Busy Indicator to the Caliburn.Micro Hello Screens sample project. There are several different situations where you may incur the need for a Busy indicator and there are several different ways to activate the control. For example I found that the place to Activate Busy in my original question is: in the DocumentWorkspace as shown here.
Public Async Sub ShowAsync() Implements HelloScreensWPF.Framework.IWorkspace.ShowAsync
'Notice that this Sub is Async and the Name is changed from Show (In the CM Sample) to Show Async
'Not sure this is the very best way but it works pretty good
'Anytime the user clicks an icon at the bottom of the UI this sub is called
Dim haveActive = TryCast(Parent, IHaveActiveItem)
If haveActive IsNot Nothing AndAlso haveActive.ActiveItem Is Me Then
DisplayName = IconName
State = DocumentWorkspaceState.Master
Else
'We need to have access to the ShellViewModel
Dim Svm = CType(Parent, ShellViewModel)
'Activate the Busy indicator
'The BusyIndicatorViewModel has a built in '200 µ Sec Delay
'So if it is Deactivated before it 'fires' the user will not see a
'flash of an unnecessary Busy Indicator
Svm.ShellBusyIndicator.ShowBusyIndicator(True, True, "Loading", IconName)
'You will need to push the conductor ActivateItem off to another thread for a real application and
'get rid of the Sample Task.Delay here
Await Task.Delay(4000)
Conductor.ActivateItem(Me)
Dim list = CType(Parent, IConductor).GetChildren
'Deactivate Busy Indicator
Svm.ShellBusyIndicator.ShowBusyIndicator(False)
End If
End Sub
If anyone would like a copy of the HelloScreens with Busy Solution, just send me an email ranck at aqsi.net with an #.

How to intercept and replace Quartz.NET's default logging at runtime?

In order to eliminate human error and avoid the tedium of maintaining who-knows-how-many App.config files, I've decided to set all of my Quartz.NET jobs' Log4Net configurations at runtime, completely in code. No App.config files allowed. I've been successful in getting a standalone console app to do this, as demonstrated here.
However, it's a different story in the scheduler itself. For some reason it's not using the configuration that I'm specifying:
Dim oProperties As New NameValueCollection
' ... Set Quartz.NET properties here
BasicConfigurator.Configure(New Logger.DbAppender)
With New StdSchedulerFactory(oProperties)
Manager.Scheduler = .GetScheduler
End With
I'm running it as a TopShelf service and I'd like the Scheduler's logs to go to the same destination as each of the IJobs. Here, Quartz.NET stubbornly continues to send its output to TopShelf's debugging console window (STDOUT).
This construct works in the console app (linked above); why isn't it working here?
OK, got it. (That didn't take long!)
For some reason, the TopShelf/Quartz.NET combo insists on suppressing logging output if the requisite App.config entries are missing.
In this case, since it's the central scheduler we're dealing with and not a plethora of jobs, I'll bite the bullet and go ahead and use an App.config file for this one.
So the root problem remains unsolved; this is just a workaround for the time being. If you know the answer I'd still be pleased to hear from you. Thanks.
OK, got it. (For REAL this time.)
Clarification: the suppression of logging in the absence of a .config file occurs in Common.Logging when run under the TopShelf/Quartz.NET combination. For some reason it consistently refuses to recognize a runtime-loaded Appender, even when the first line of code in the service configures logging. Still a mystery, but not important. (At least not for me, with this latest discovery—YMMV.)
The only logging that's suppressed is that which follows the buildup and teardown of the Common.Logging library itself; everything that occurs in the service itself is still logged.
I was able to get it to work using the code below (in combination with the code linked to above, of course).
As I said, YMMV.
[Service]
Public Module Main
Sub Main()
Try
BasicConfigurator.Configure(New Logger.DbAppender("ConnectionString"))
Logger = LogManager.GetLogger(GetType(Main))
Environment.ExitCode = HostFactory.Run(Sub(Configurator)
Configurator.Service(Of Manager)(Sub(Service)
Service.ConstructUsing(Function(Factory) As ServiceControl
Return New Manager
End Function)
Service.WhenStarted(Function(Manager, HostControl) As Boolean
Return Manager.StartService(HostControl)
End Function)
Service.WhenStopped(Function(Manager, HostControl) As Boolean
Return Manager.StopService(HostControl)
End Function)
End Sub)
Configurator.SetDescription(ServiceInfo.Description)
Configurator.SetServiceName(ServiceInfo.Product)
Configurator.SetDisplayName(ServiceInfo.Title)
Configurator.StartAutomatically()
Configurator.RunAsLocalSystem()
End Sub)
Catch ex As Exception
EventLog.WriteEntry(ServiceInfo.Product, ex.Message, EventLogEntryType.Error, 1, 1, ex.ToBytes)
End Try
End Sub
Public Property Logger As ILog
End Module
[DbAppender] (updated w/add'l constructor that accepts a connection string)
Public Class DbAppender
Inherits AdoNetAppender
Public Sub New()
Me.New(String.Empty)
End Sub
Public Sub New(ConnectionString As String)
If Trim(ConnectionString) <> String.Empty Then
MyBase.ConnectionString = ConnectionString
End If
MyBase.CommandText = Me.CommandText
MyBase.BufferSize = 1
Me.Parameters.ForEach(Sub(Parameter As DbParameter)
MyBase.AddParameter(Parameter)
End Sub)
Me.ActivateOptions()
End Sub
Protected Overrides Function CreateConnection(ConnectionType As Type, ConnectionString As String) As IDbConnection
Return MyBase.CreateConnection(GetType(System.Data.SqlClient.SqlConnection), MyBase.ConnectionString)
End Function
Private Overloads ReadOnly Property CommandText As String
Get
Dim _
sColumns,
sValues As String
sColumns = Join(Me.Parameters.Select(Function(P As DbParameter) P.DbColumn).ToArray, ",")
sValues = Join(Me.Parameters.Select(Function(P As DbParameter) P.ParameterName).ToArray, ",")
Return COMMAND_TEXT.ToFormat(sColumns, sValues)
End Get
End Property
Private ReadOnly Property Parameters As List(Of DbParameter)
Get
Parameters = New List(Of DbParameter)
Parameters.Add(Me.Date)
Parameters.Add(Me.Thread)
Parameters.Add(Me.Level)
Parameters.Add(Me.Source)
Parameters.Add(Me.Message)
Parameters.Add(Me.Exception)
End Get
End Property
Private ReadOnly Property [Date] As DbParameter
Get
Return New DbParameter("Date", New DbPatternLayout(PATTERN_DATE), DbType.Date, 0)
End Get
End Property
Private ReadOnly Property Thread As DbParameter
Get
Return New DbParameter("Thread", New DbPatternLayout(PATTERN_THREAD), DbType.String, 255)
End Get
End Property
Private ReadOnly Property Level As DbParameter
Get
Return New DbParameter("Level", New DbPatternLayout(PATTERN_LEVEL), DbType.String, 50)
End Get
End Property
Private ReadOnly Property Source As DbParameter
Get
Return New DbParameter("Source", New DbPatternLayout(PATTERN_SOURCE), DbType.String, 255)
End Get
End Property
Private ReadOnly Property Message As DbParameter
Get
Return New DbParameter("Message", New DbPatternLayout(PATTERN_MESSAGE), DbType.String, 4000)
End Get
End Property
Private ReadOnly Property Exception As DbParameter
Get
Return New DbParameter("Exception", New DbExceptionLayout)
End Get
End Property
Private Const PATTERN_MESSAGE As String = "%message"
Private Const PATTERN_THREAD As String = "%thread"
Private Const PATTERN_SOURCE As String = "%logger.%M()"
Private Const PATTERN_LEVEL As String = "%level"
Private Const PATTERN_DATE As String = "%date{yyyy-MM-dd HH:mm:ss.fff}"
Private Const COMMAND_TEXT As String = "INSERT INTO Log ({0}) VALUES ({1})"
'======================================================================================
' Available patterns:
' http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout.html
'======================================================================================
End Class

How to set the one section timer to the Dialog derived from CProperty sheet using VC++ 2005

Anyone, could you please help me in display in the One sec timer, this my context:
I derived a class from CPropertySheet. Now the thing is that I want to display the current time in the sheet. So for normal dialogs I'm using ON Timer function to set the one section timer here how can I set the one second timer
Thanks to all ,
I found the Solution for the above problem. this is related to One Second timer for CProperty Sheet.
I Derived Class CReview Sheet so for that I declare a member function OnTimer
void CReviewSheet::OnTimer(UINT_PTR nIDEvent)
{
if(bTimerStatus == true)
{
CTime t1;
t1=CTime::GetCurrentTime();
m_StBar.SetPaneText(2,t1.Format("%H:%M:%S"));
bTimerStatus = false;
}
else
{
bTimerStatus = true;
}
CPropertySheet::OnTimer(nIDEvent);
}
So this is working fine. And I am able to display the Current time in my review Sheet.

Scope of a variable from Form to Class Module VBA

I have a Form UserForm1 having two command buttons command 1 and command 2. The variable var = 1 when command1 is pressed and var=2 if command 2 is pressed. Var is a global variable in UserForm1. expDate and textRecDate are two textboxes in UserForm1
I have a class module clsMod and I am trying to do something like this
If UserForm1.var= 1 Then
UserForm1.expDate.Text = SelectedDate
If UserForm1.var= 2 Then
UserForm1.textRecDate.Text = SelectedDate
I want to extend the scope of var to the class module. Is there a way I can do that.
thanks
You don't really want to "extend" the scope - you want to restrict the scope to the Form level and then use Public methods to access/control the form.
eg - In UserForm1...
Private Var As Integer
Public Function GetVar() As Integer
GetVar = Var
End Function
Public Sub SetTextRecDate(d as Date)
textRecDate.Text = SelectedDate
End Sub
And in clsMod..
If UserForm1.GetVar = 2 Then
UserForm1.SetTextRecDate(SelectedDate)
'The line above may actually want to be...
'UserForm1.SetTextRecDate SelectedDate
'VBA is strange about parenthesised arguments
Endif
etc etc
Oh and if the naming is not just for demonstration / example purposes please don't get in the habit of calling your buttons Command1 and Command2 and your variables Var :D ...

Resources