Java process problem in Eclipse - eclipse

This is my code:
final String run_tool ="cmd.exe /C pelda.exe";
final Process tool_proc = null;
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
InputStream toolstr = tool_proc.getInputStream();
After the eclipse gives this warning message fot the tool_proc variable:
The final local variable tool_proc
cannot be assigned, since it is
defined in an enclosing type
I dont't know why my code doesn't work
please help me

The final modifier forbids changing the variable once it has been set. Kevin gives an excellent explanation of why you can't use it in this context.
The construction you have chosen for requires you to introduce a field in the parent class and set it via run():
class MyClass {
Process tool_proc = null;
void myFunction() {
final String run_tool ="cmd.exe /C pelda.exe";
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
// tool_proc will be null at this point!
InputStream toolstr = tool_proc.getInputStream();
}
}
In the above code I have demonstrated that tool_proc will always be null on the last line, as the thread has in all liklihood not finished its execution by this time!
You can expect NullPointerExceptions!
It seems what you are trying to do is very similar to this article about capturing application output asynchronously. It's a good read, and explains why conventional approaches can cause problems. I have an implementation very similar to their StreamGobbler (article page 4).

I know a good trick since i'm C++ coder and always want pointers in java :
final String run_tool ="cmd.exe /C pelda.exe";
final Process tool_proc[] = new Process[1];
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc[0] = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
InputStream toolstr = tool_proc.getInputStream();

The tool_proc variable is final - final variables can only be assigned once, and you already assigned it the value null in the declaration. Removing the null assignment won't work because the runnable can be called more than once, resulting in multiple assignment. So your best option is to remove the final keyword and it should compile, at least
Edit
As noted in my comment to my answer, I neglected to account for the fact that tool_proc is a local variable, and without the final modifier it cannot be accessed from the anonymous Runnable subclass. As Paul first noted in his answer, you'll have to use a non-final field to store the Process object.

Initial value of final field cannot be changed. Remove final modificator from tool_proc:
Process tool_proc = null;

Related

FlatFileItemWriter not generating the file when using Tasklet approach

I wrote the following code using tasklet approach to generate a file with data.
public class PersonInfoFileWriter implements Tasklet {
#Autowired
PersonInfoFileUtil personInfoFileUtil;
public void write(ExecutionContext executionContext) throws IOException {
List<PersonInfo> personInfoList = null;
FlatFileItemWriter<PersonInfo> flatFileWriter = new FlatFileItemWriter<PersonInfo>();
flatFileWriter.setResource(new FileSystemResource("C:\\test\\"
+ LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + ".txt"));
try {
flatFileWriter.open(executionContext);
String personName = (String) executionContext.get("personInfo");
//gets the details of the person by name from the database and assign the values to PersonInfo
personInfoList = personInfoFileUtil.setDataForPersonInfoFile(personName);
flatFileWriter.setName("Person-Detail-File");
flatFileWriter.setShouldDeleteIfEmpty(true);
flatFileWriter.setAppendAllowed(true);
flatFileWriter.setLineSeparator("\n");
flatFileWriter.setHeaderCallback(new FlatFileHeaderCallback() {
#Override
public void writeHeader(Writer writer) throws IOException {
writer.write(
"PersonId^Name^Program^ProgramType");
}
});
flatFileWriter.setLineAggregator(new DelimitedLineAggregator<PersonInfo>() {
{
setDelimiter("^");
setFieldExtractor((FieldExtractor<PersonInfo>) new BeanWrapperFieldExtractor<PersonInfo>() {
{
setNames(new String[] { "personId", "name", "program", "programType" });
}
});
}
});
String lines = flatFileWriter.doWrite((List<? extends PersonInfo>) personInfoList);
logger.info(lines); //this prints the information correctly
} finally {
flatFileWriter.close();
}
}
#Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
ExecutionContext executionContext = contribution.getStepExecution().getJobExecution().getExecutionContext();
write(executionContext);
return RepeatStatus.FINISHED;
}
}
The above code compiles and runs without errors but it is not generating any file on to the disk.
I tried debugging to check if the fileName and etc values are getting created on to a buffer to write to a disk and everything works as intended except generating and writing the data to a file.
If I write the code using chunk based approach it is working fine.
Please let me know if I am doing any mistake. Thanks for the help in advance.
EDIT: after adding the changes that were suggested the file is getting created on the disk but the file is missing out the header that I have set using setHeaderCallback()
In your write method, you create an instance of FlatFileItemWriter, set some properties on it and then call close on it.
You did not call open() and write() methods, that's why it is not generating an file.

NUnit & MOQ: Testing a try catch that calls another method when an Exception is caught

I understand that the MOQ framework wasn't really designed to help in this instance, but perhaps you might be able to help...
I have a method that uses a try/catch that calls a notification method whenever an exception is thrown. What I am trying to do is create an integration/unit test that checks to make sure SendNotification is called when any exception is thrown.
Method Under Test:
public virtual void MonitorIntradayBuilds(IIntradayBuilds intradayBuilds)
{
try
{
var intradayBuildFound = intradayBuilds.CheckForIntradayBuilds();
if (intradayBuildFound && !IntradayBuildsComplete && !DailyBuildsFound)
{
IntradayBuildsComplete = intradayBuilds.StartIntradayBuilds();
//should start daily builds?
}
}
catch (Exception ex)
{
SendNotification("MonitorIntradayBuilds threw an exception", ex);
}
}
Test Case:
[Test]
public void it_should_notify_developers_immediately_if_there_is_a_problem_when_checking_for_intraday_builds()
{
//Arrange
var mockDua = new Mock<DUA>();
var mockIB = new Mock<IIntradayBuilds>();
//Act
mockIB.Setup(x => x.CheckForIntradayBuilds()).Throws(new Exception());
mockDua.Object.MonitorIntradayBuilds(mockIB.Object);
//Assert
mockDua.Verify(x => x.SendNotification(It.IsAny<string>(), It.IsAny<Exception>()), Times.Once);
}
I keep hitting a Moq.MockException and then see that SendNotification "expected an invocation on the mock once, but was 0 times..."
I've tried using the [ExpectedException] attribute on the test case, but to no avail. It makes the test pass, but still doesn't call the SendNotification method.
Any ideas?
Solved it.
Turns out you need to set the CallBase property on the System Under Test that you are mocking up.
Test case is now:
[Test]
public void it_should_notify_developers_immediately_if_there_is_a_problem_when_checking_for_intraday_builds()
{
//Arrange
var mockDua = new Mock<DUA>();
var mockIB = new Mock<IIntradayBuilds>();
mockDua.CallBase = true; // <<<< Added this line!
//Act
mockIB.Setup(x => x.CheckForIntradayBuilds()).Throws(new Exception());
mockDua.Object.MonitorIntradayBuilds(mockIB.Object);
//Assert
mockDua.Verify(x => x.SendNotification(It.IsAny<string>(), It.IsAny<Exception>()), Times.Once);
}
Hopefully someone else finds it helpful :)

How can I correctly update a progress bar for an operation of unknown duration within an Eclipse wizard?

I have implemented a wizard for my Eclipse plug-in, showing several pages. One of these pages needs some lengthy initialization, that means it consists of a SWT table, which needs to be populated by information coming from an external source. This source needs to be activated first (one single method call that returns after a couple of seconds - I can not know in advance how long it will take exactly), before it can be used as input for for the table viewer. This initialization is currently done by the table model provider when it needs to access the external source for the first time.
Therefore, when I enter the wizard page, I would like to show a dummy progress bar that just counts up for a while. My approach was the following, but unfortunately does not work at all:
private void initViewer() {
IRunnableWithProgress runnable = new IRunnableWithProgress() { // needed to embed long running operation into the wizard page
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
SubMonitor progress = SubMonitor.convert(monitor);
Thread thread = new Thread() {
#Override
public void run() {
Display.getDefault().syncExec(new Runnable() {
public void run() {
viewer.setInput(ResourcesPlugin.getWorkspace().getRoot()); // this will make the table provider initialize the external source.
}
});
}
};
thread.start();
while(thread.isAlive()) {
progress.setWorkRemaining(10000);
progress.worked(1);
}
progress.done();
}
};
try {
getContainer().run(false, false, runnable);
} catch(Exception e) {
throw new Exception("Could not access data store", e);
}
}
This method gets then invoked when the wizard page's setVisible()-method is called and should, after a couple of seconds, set the viewer's input. This, however, never happens, because the inner-most run()-method never gets executed.
Any hints on how to deal with long-running (where an exact estimate is not available) initializations in Eclipse wizards would be very appreciated!
I have given below a simple example on how to use IRunnableWithProgress along with a ProgressMonitorDialog to perform a task of unknown quantity. To start with, have an implementation to IRunnableWithProgress from where the actual task is performed. This implementation could be an inner class.
public class MyRunnableWithProgress implements IRunnableWithProgress {
private String _fileName;
public MyRunnableWithProgress(String fileName) {
_fileName = fileName;
}
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
int totalUnitsOfWork = IProgressMonitor.UNKNOWN;
monitor.beginTask("Performing read. Please wait...", totalUnitsOfWork);
performRead(_fileName, monitor); // This only performs the tasks
monitor.done();
}
}
Now, a generic implementation to ProgressMonitorDialog can be created as below which could be used for other places where a progress monitor dialog is required.
public class MyProgressMonitorDialog extends ProgressMonitorDialog {
private boolean cancellable;
public MyProgressMonitorDialog(Shell parent, boolean cancellable) {
super(parent);
this.cancellable = cancellable;
}
#Override
public Composite createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
setCancelable(cancellable);
return container;
}
}
Having got the required implementation, the task can be invoked as below to get it processed with a progress dialog.
boolean cancellable = false;
IRunnableWithProgress myRunnable = new MyRunnableWithProgress(receivedFileName);
ProgressMonitorDialog progressMonitorDialog = new MyProgressMonitorDialog(getShell(), cancellable);
try {
progressMonitorDialog.run(true, true, myRunnable);
} catch (InvocationTargetException e) {
// Catch in your best way
throw new RuntimeException(e);
} catch (InterruptedException e) {
//Catch in your best way
Thread.currentThread().interrupt();
}
Hope this helps!
I assume the reason why it's "not working" for you is that the preparation of input is done in UI thread meaning that the progress bar cannot be updated. A better approach is to prepare input in advance and only set input to viewer after that.

Calling organize imports programmatically

I'm trying to execute 'OrganizeImports' programmatically on files that I'm editing programmatically.
My code looks like this:
final ICommandService cmdService = (ICommandService)PlatformUI.getWorkbench().getService (ICommandService.class);
if (cmdService != null) {
final Command cmd = cmdService.getCommand(IJavaEditorActionDefinitionIds.ORGANIZE_IMPORTS);
final ExecutionEvent execEvt = new ExecutionEvent(cmd, Collections.EMPTY_MAP, compileationUnit, null);
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
ResourcesPlugin.getWorkspace().
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
try {
//cmd.executeWithChecks(execEvt);
cmd.execute(execEvt);
} catch (Exception e) {
getLogger().severe("organize imports failed: " + e.getMessage());
}
}
My problem is that OrganizeImportsAction executes on the current selection which is not the same as the compilation unit I'm editing. I would like to set the selection programmatically on the compilation unit but I don't know how to do that. Or maybe there is another way to trigger OrganizeImports.
thanks,
stefan
May be this test ui.org.eclipse.jdt.ui.tests.quickfix.CleanUpTest class could offer some clue.
It is based on the enable method in ui.org.eclipse.jdt.ui.tests.quickfix.CleanUpTestCase and on the org.eclipse.ltk.core.refactoring.PerformChangeOperation class.
You can see PerformChangeOperation invoked ink the class org.eclipse.ltk.ui.refactoring.RefactoringWizard.

Using yield to iterate over a datareader might not close the connection?

Here is a sample code to retrieve data from a database using the yield keyword that I found in a few place while googling around :
public IEnumerable<object> ExecuteSelect(string commandText)
{
using (IDbConnection connection = CreateConnection())
{
using (IDbCommand cmd = CreateCommand(commandText, connection))
{
connection.Open();
using (IDbDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
yield return reader["SomeField"];
}
}
connection.Close();
}
}
}
Am I correct in thinking that in this sample code, the connection would not be closed if we do not iterate over the whole datareader ?
Here is an example that would not close the connection, if I understand yield correctly..
foreach(object obj in ExecuteSelect(commandText))
{
break;
}
For a db connection that might not be catastrophic, I suppose the GC would clean it up eventually, but what if instead of a connection it was a more critical resource?
The Iterator that the compiler synthesises implements IDisposable, which foreach calls when the foreach loop is exited.
The Iterator's Dispose() method will clean up the using statements on early exit.
As long as you use the iterator in a foreach loop, using() block, or call the Dispose() method in some other way, the cleanup of the Iterator will happen.
Connection will be closed automatically since you're using it inside "using" block.
From the simple test I have tried, aku is right, dispose is called as soon as the foreach block exit.
#David : However call stack is kept between call, so the connection would not be closed because on the next call we would return to the next instruction after the yield, which is the while block.
My understanding is that when the iterator is disposed, the connection would also be disposed with it. I also think that the Connection.Close would not be needed because it would be taken care of when the object is disposed because of the using clause.
Here is a simple program I tried to test the behavior...
class Program
{
static void Main(string[] args)
{
foreach (int v in getValues())
{
Console.WriteLine(v);
}
Console.ReadKey();
foreach (int v in getValues())
{
Console.WriteLine(v);
break;
}
Console.ReadKey();
}
public static IEnumerable<int> getValues()
{
using (TestDisposable t = new TestDisposable())
{
for(int i = 0; i<10; i++)
yield return t.GetValue();
}
}
}
public class TestDisposable : IDisposable
{
private int value;
public void Dispose()
{
Console.WriteLine("Disposed");
}
public int GetValue()
{
value += 1;
return value;
}
}
Judging from this technical explanation, your code will not work as expected, but abort on the second item, because the connection was already closed when returning the first item.
#Joel Gauvreau : Yes, I should have read on. Part 3 of this series explains that the compiler adds special handling for finally blocks to trigger only at the real end.