I am a beginner in programming. I am still learning about threads and more of them. But now I have quite a big idea to write my first program (I mean bigger than simple calculator). I want it to sort files, integrate in one (many copies of one file in different localization - the idea of it is of no importance now).
But I want to create threads, or anything else (what is your advice). I mean. When I start the program, the console starts up, and e.g I have to write "my_programm run" or "my_program stop" or "my_program status" or "my_magic_tricks be_done". I mean how can i create a program working in the background like in threads with real time string control over it.
I tried to find out on Google for anything which could be useful for me, but i didn't find it out.
Please give me just a name of libraries or methods, which I can use. I will read out, what it is about and finally I will move forward with it.
If it is a dumbass question. I am really sorry for disapointing the programmer group. But it would be nice to be given of any signpost or clue.
A simple way to do it using the standard library :
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class Example {
private static final int POOL_SIZE = 5;
private static final ExecutorService WORKERS = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 1, MILLISECONDS, new LinkedBlockingDeque<>());
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("> ");
String cmd = sc.nextLine();
switch (cmd) {
case "process":
WORKERS.submit(newExpensiveTask());
break;
case "kill":
System.exit(0);
default:
System.err.println("Unrecognized command: " + cmd);
}
}
}
private static Runnable newExpensiveTask() {
return () -> {
try {
Thread.sleep(10000);
System.out.println("Done processing");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
};
}
}
This code lets you run heavy tasks asynchronously while the user terminal remains available and reactive.
I would recommend reading up on specific tutorials, such as the Java Language Tutorial (available as a book - at least, it used to be - as well as on the Java website https://docs.oracle.com/javase/tutorial/essential/concurrency/)
However as others have cautioned, getting into threading is a challenge and requires good knowledge of the language quite apart from the aspects of multithreading and synchronization. I'd be tempted to recommend you read some of the other tutorials - working through IO and so on - first of all.
Related
I tried a code.
Well, the first part is the main method that basically lays down the directory structure. I tried to delete a directory that contains other directories using the rmdirs method I wrote below.
public static void rmdirs(File k)
{
String[] y= k.list();
int i;
File f;
for(i=0;i<y.length;i++)
{
f= new File(k,y[i]);
if(f.isDirectory() && f.list().length>0)
{
rmdirs(f);
}
else
{
f.delete();
}
}
k.delete();
}
The rmdirs method is working and seems to be doing what I expected, but how do I add this program to a library, so that I can repeatedly use it by importing something.
Also, the above program does something like
rmdirs(f2);
to delete a file.
I would like it to be something like
f2.rmdirs();
And I am wondering how I can do it. I tried somehting like
import java.io.*;
public class RFile extends File
{
public RFile(String p)
{
super(p);
}
public RFile(File f1,String p1)
{
super(f1,p1);
}
public void rmdirs()
{
RFile k=this;
String[] y= k.list();
int i;
RFile f;
for(i=0;i<y.length;i++)
{
f= new RFile(k,y[i]);
if(f.isDirectory() && f.list().length>0)
{
f.rmdirs();
}
else
{
f.delete();
}
}
k.delete();
}
}
But then, the tester class or main class becomes one in which I have to use RFile and not File.
This is a problem; Also, like I asked before, how do I add all these to a library so that importing java.io.RFile or something like that will do the job?
You don't extend java.io.File (unless you have a very good reason and this is not such a reason)
One solution is to create a class like "FileUtils" which has a static method "remove" so you can call:
FileUtils.remove(myFile);
It's a general design philosophy that you can find in for example apache libraries (e.g. http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html)
UPDATE
A library is simply a reusable collection of code with a specific purpose.
Apache is a foundation that manages a lot of open source projects (a lot if not all of it java-based). They provide high quality (though in a few cases outdated) software that can be reused. While you're at it you might want to take a peek at "apache maven" which handles the lifecycle of a project and makes library management easy (believe it or not there is a whole repository with more than 600.000 libraries in it for you to use: http://mvnrepository.com/
And this is just one (although the largest) repository...
Design philosophy is an enormous subject with as many opinions as there are coders. However there are some best practices that everyone adheres to.
Apache usually has pretty high quality code so you can check them if not for code, at least for a good way to write libraries. Other than that I can only point you towards books and google to find your way.
Writing maintainable code is more of an art than a science and it takes a lot of reading and practice to master it.
I don't know very much about Java's MIDI function. In fact, it utterly bewilders me. what I'd like to do however is just build a simple application that will play one note.
How to play a single MIDI note using Java Sound?
The support for this out on the web is almost nonexistent, and I am totally at a loss.
I know this is a really old question, but, as a novice programmer, I had a very difficult time figuring out how to do this, so I thought I would share the following hello-world-style program that gets Java to play a single midi note in order to help anyone else getting started.
import javax.sound.midi.*;
public class MidiTest{
public static void main(String[] args) {
try{
/* Create a new Sythesizer and open it. Most of
* the methods you will want to use to expand on this
* example can be found in the Java documentation here:
* https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/Synthesizer.html
*/
Synthesizer midiSynth = MidiSystem.getSynthesizer();
midiSynth.open();
//get and load default instrument and channel lists
Instrument[] instr = midiSynth.getDefaultSoundbank().getInstruments();
MidiChannel[] mChannels = midiSynth.getChannels();
midiSynth.loadInstrument(instr[0]);//load an instrument
mChannels[0].noteOn(60, 100);//On channel 0, play note number 60 with velocity 100
try { Thread.sleep(1000); // wait time in milliseconds to control duration
} catch( InterruptedException e ) {
e.printStackTrace();
}
mChannels[0].noteOff(60);//turn of the note
} catch (MidiUnavailableException e) {
e.printStackTrace();
}
}
}
The above code was primarily created by cutting, pasting, and messing around with code found in several online tutorials. Here are the most helpful tutorials that I found:
http://www.ibm.com/developerworks/library/it/it-0801art38/
This is a great tutorial and probably has everything you are looking for; however, it may be a little overwhelming at first.
http://patater.com/gbaguy/javamidi.htm
Features nonworking code written by a 15 year old. This was - surprisingly - the most helpful thing I found.
Here you go :
MIDI Tag Info on stackoverflow
UnderStanding MIDI
Tutorial on Oracle
Accessing MIDI
MIdi Synthesis
i'm a beginner and i try to code very simple java programs and
here i have two java programs.
the first program for selecting recent files from a folder.
the second program for concatenating these recents files.
what i want is to create a third java program that
-will launch the first program.
-then wait for 10s
-launch the second java program.
i want to keep separately the first and second program.
because i want to use them for a further application.
is it that possible?
Do i have to use Process method like if i want to launch notepad.exe through java?
or else?
Thank you
There is nothing special about the main method. You can call it directly from your third program if you like.
public static void main(String[] args) throws Exception {
Program1.main(args);
Thread.sleep(10000);
Program2.main(args);
}
If you want to launch them as separate java processes, you should use the ProcessBuilder. You can also do this in groovy, very simply as:
"java <arguments>".execute()
Otherwise you can "launch" it by calling the main method as suggested by #Heathen, though they would both be running in the same JVM with that method.
You can use Process method as you described, but it isn't a wise solution to rely on an arbitrary timeout for the first program finishing. Instead you should wait for the first one exiting.
By the way, you could generate two jar files, one for each job. You then can easily create one application out each one of them and you can easily combine them to create a third application for the combined job. This is much better than creating processed from Java.
ProcessBuilder builder1 = new ProcessBuilder("firstProgram", "arg1", "arg2", ...);
ProcessBuilder builder2 = new ProcessBuilder("secondProgram", "arg1", "arg2", ...);
Process proc1 = builder1.start();
//Pauses for 10 seconds
Thread.sleep(10000);
Process proc2 = builder2.start();
//This next part is necessary to wait for the programs to finish. If you want them to
//run independently of the main thread, you can omit this part
int exitVal1 = proc1.waitFor();
int exitVal2 = proc2.waitFor();
You can get to the input, output, and error streams of a Process object, useful if you want to interact with the running process.
You can find more information about the Process object at
http://download.oracle.com/javase/6/docs/api/java/lang/Process.html
For example my code is:
import java.io.IOException;
public class Launcher
{
public static void main(String args[]) throws IOException, InterruptedException
{
try {
Process[] proc = new Process[2];
proc[0] = new ProcessBuilder("calc.exe").start();
Thread.sleep(3000);
proc[1] = new ProcessBuilder("D:\\NetBeansProjects\\GetIPAddress\\dist\\GetIPAddress.jar").start();
try {
Thread.sleep(3000);
}
catch (InterruptedException ex)
{
}
proc[0].destroy();
Thread.sleep(3000);
proc[1].destroy();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
If i replace the proc[1] by notepad.exe it's working well
thank you
I would like to get to query Windows Vista Search service directly ( or indirectly ) from Java.
I know it is possible to query using the search-ms: protocol, but I would like to consume the result within the app.
I have found good information in the Windows Search API but none related to Java.
I would mark as accepted the answer that provides useful and definitive information on how to achieve this.
Thanks in advance.
EDIT
Does anyone have a JACOB sample, before I can mark this as accepted?
:)
You may want to look at one of the Java-COM integration technologies. I have personally worked with JACOB (JAva COm Bridge):
http://danadler.com/jacob/
Which was rather cumbersome (think working exclusively with reflection), but got the job done for me (quick proof of concept, accessing MapPoint from within Java).
The only other such technology I'm aware of is Jawin, but I don't have any personal experience with it:
http://jawinproject.sourceforge.net/
Update 04/26/2009:
Just for the heck of it, I did more research into Microsoft Windows Search, and found an easy way to integrate with it using OLE DB. Here's some code I wrote as a proof of concept:
public static void main(String[] args) {
DispatchPtr connection = null;
DispatchPtr results = null;
try {
Ole32.CoInitialize();
connection = new DispatchPtr("ADODB.Connection");
connection.invoke("Open",
"Provider=Search.CollatorDSO;" +
"Extended Properties='Application=Windows';");
results = (DispatchPtr)connection.invoke("Execute",
"select System.Title, System.Comment, System.ItemName, System.ItemUrl, System.FileExtension, System.ItemDate, System.MimeType " +
"from SystemIndex " +
"where contains('Foo')");
int count = 0;
while(!((Boolean)results.get("EOF")).booleanValue()) {
++ count;
DispatchPtr fields = (DispatchPtr)results.get("Fields");
int numFields = ((Integer)fields.get("Count")).intValue();
for (int i = 0; i < numFields; ++ i) {
DispatchPtr item =
(DispatchPtr)fields.get("Item", new Integer(i));
System.out.println(
item.get("Name") + ": " + item.get("Value"));
}
System.out.println();
results.invoke("MoveNext");
}
System.out.println("\nCount:" + count);
} catch (COMException e) {
e.printStackTrace();
} finally {
try {
results.invoke("Close");
} catch (COMException e) {
e.printStackTrace();
}
try {
connection.invoke("Close");
} catch (COMException e) {
e.printStackTrace();
}
try {
Ole32.CoUninitialize();
} catch (COMException e) {
e.printStackTrace();
}
}
}
To compile this, you'll need to make sure that the JAWIN JAR is in your classpath, and that jawin.dll is in your path (or java.library.path system property). This code simply opens an ADO connection to the local Windows Desktop Search index, queries for documents with the keyword "Foo," and print out a few key properties on the resultant documents.
Let me know if you have any questions, or need me to clarify anything.
Update 04/27/2009:
I tried implementing the same thing in JACOB as well, and will be doing some benchmarks to compare performance differences between the two. I may be doing something wrong in JACOB, but it seems to consistently be using 10x more memory. I'll be working on a jcom and com4j implementation as well, if I have some time, and try to figure out some quirks that I believe are due to the lack of thread safety somewhere. I may even try a JNI based solution. I expect to be done with everything in 6-8 weeks.
Update 04/28/2009:
This is just an update for those who've been following and curious. Turns out there are no threading issues, I just needed to explicitly close my database resources, since the OLE DB connections are presumably pooled at the OS level (I probably should have closed the connections anyway...). I don't think I'll be any further updates to this. Let me know if anyone runs into any problems with this.
Update 05/01/2009:
Added JACOB example per Oscar's request. This goes through the exact same sequence of calls from a COM perspective, just using JACOB. While it's true JACOB has been much more actively worked on in recent times, I also notice that it's quite a memory hog (uses 10x as much memory as the Jawin version)
public static void main(String[] args) {
Dispatch connection = null;
Dispatch results = null;
try {
connection = new Dispatch("ADODB.Connection");
Dispatch.call(connection, "Open",
"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
results = Dispatch.call(connection, "Execute",
"select System.Title, System.Comment, System.ItemName, System.ItemUrl, System.FileExtension, System.ItemDate, System.MimeType " +
"from SystemIndex " +
"where contains('Foo')").toDispatch();
int count = 0;
while(!Dispatch.get(results, "EOF").getBoolean()) {
++ count;
Dispatch fields = Dispatch.get(results, "Fields").toDispatch();
int numFields = Dispatch.get(fields, "Count").getInt();
for (int i = 0; i < numFields; ++ i) {
Dispatch item =
Dispatch.call(fields, "Item", new Integer(i)).
toDispatch();
System.out.println(
Dispatch.get(item, "Name") + ": " +
Dispatch.get(item, "Value"));
}
System.out.println();
Dispatch.call(results, "MoveNext");
}
} finally {
try {
Dispatch.call(results, "Close");
} catch (JacobException e) {
e.printStackTrace();
}
try {
Dispatch.call(connection, "Close");
} catch (JacobException e) {
e.printStackTrace();
}
}
}
As few posts here suggest you can bridge between Java and .NET or COM using commercial or free frameworks like JACOB, JNBridge, J-Integra etc..
Actually I had an experience with with one of these third parties (an expensive one :-) ) and I must say I will do my best to avoid repeating this mistake in the future. The reason is that it involves many "voodoo" stuff you can't really debug, it's very complicated to understand what is the problem when things go wrong.
The solution I would suggest you to implement is to create a simple .NET application that makes the actual calls to the windows search API. After doing so, you need to establish a communication channel between this component and your Java code. This can be done in various ways, for example by messaging to a small DB that your application will periodically pull. Or registering this component on the machine IIS (if exists) and expose simple WS API to communicate with it.
I know that it may sound cumbersome but the clear advantages are: a) you communicate with windows search API using the language it understands (.NET or COM) , b) you control all the application paths.
Any reason why you couldn't just use Runtime.exec() to query via search-ms and read the BufferedReader with the result of the command? For example:
public class ExecTest {
public static void main(String[] args) throws IOException {
Process result = Runtime.getRuntime().exec("search-ms:query=microsoft&");
BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
StringBuffer outputSB = new StringBuffer(40000);
String s = null;
while ((s = output.readLine()) != null) {
outputSB.append(s + "\n");
System.out.println(s);
}
String result = output.toString();
}
}
There are several libraries out there for calling COM objects from java, some are opensource (but their learning curve is higher) some are closed source and have a quicker learning curve. A closed source example is EZCom. The commercial ones tend to focus on calling java from windows as well, something I've never seen in opensource.
In your case, what I would suggest you do is front the call in your own .NET class (I guess use C# as that is closest to Java without getting into the controversial J#), and focus on making the interoperability with the .NET dll. That way the windows programming gets easier, and the interface between Windows and java is simpler.
If you are looking for how to use a java com library, the MSDN is the wrong place. But the MSDN will help you write what you need from within .NET, and then look at the com library tutorials about invoking the one or two methods you need from your .NET objects.
EDIT:
Given the discussion in the answers about using a Web Service, you could (and probably will have better luck) build a small .NET app that calls an embedded java web server rather than try to make .NET have the embedded web service, and have java be the consumer of the call. For an embedded web server, my research showed Winstone to be good. Not the smallest, but is much more flexible.
The way to get that to work is to launch the .NET app from java, and have the .NET app call the web service on a timer or a loop to see if there is a request, and if there is, process it and send the response.
I need to prevent users from starting my Java application (WebStart Swing app) multiple times. So if the application is already running it shouldn't be possible to start it again or show a warning / be closed again.
Is there some convenient way to achieve this? I thought about blocking a port or write sth to a file. But hopefully you can access some system properties or the JVM?
btw. target platform is Windows XP with Java 1.5
I think your suggestion of opening a port to listen when you start your application is the best idea.
It's very easy to do and you don't need to worry about cleaning it up when you close your application. For example, if you write to a file but someone then kills the processes using Task Manager the file won't get deleted.
Also, if I remember correctly there is no easy way of getting the PID of a Java process from inside the JVM so don't try and formulate a solution using PIDs.
Something like this should do the trick:
private static final int PORT = 9999;
private static ServerSocket socket;
private static void checkIfRunning() {
try {
//Bind to localhost adapter with a zero connection queue
socket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1}));
}
catch (BindException e) {
System.err.println("Already running.");
System.exit(1);
}
catch (IOException e) {
System.err.println("Unexpected error.");
e.printStackTrace();
System.exit(2);
}
}
This sample code explicitly binds to 127.0.0.1 which should avoid any firewall warnings, as any traffic on this address must be from the local system.
When picking a port try to avoid one mentioned in the list of Well Known Ports. You should ideally make the port used configurable in a file or via a command line switch in case of conflicts.
As the question states that WebStart is being used, the obvious solution is to use javax.jnlp.SingleInstanceService.
This service is available in 1.5. Note that 1.5 is currently most of the way through its End Of Service Life period. Get with Java SE 6!
I think that the better idea would be to use file lock (quite an old idea :) ). Since Java 1.4 a new I/O library was introduced, that allows file locking.
Once the application starts it tries to acquire lock on a file (or create it if does not exist), when the application exits the lock is relased. If application cannot acquire a lock, it quits.
The example how to do file locking is for example in Java Developers Almanac.
If you want to use file locking in Java Web Start application or an applet you need to sing the application or the applet.
You can use JUnique library. It provides support for running single-instance java application and is open-source.
http://www.sauronsoftware.it/projects/junique/
See also my full answer at How to implement a single instance Java application?
We do the same in C++ by creating a kernal mutex object and looking for it at start up. The advantages are the same as using a socket, ie when the process dies/crashes/exits/is killed, the mutex object is cleaned up by the kernel.
I'm not a Java programmer, so I am not sure whether you can do the same kind of thing in Java?
I've create the cross platform AppLock class.
http://mixeddev.info/articles/2015/02/01/run-single-jvm-app-instance.html
It is using file lock technique.
Update. At 2016-10-14 I've created package compatible with maven/gradle https://github.com/jneat/jneat and explained it here http://mixeddev.info/articles/2015/06/01/synchronize-different-jvm-instances.html
You could use the registry, although this halfheartedly defeats the purpose of using a high-level language like java. At least your target platform is windows =D
Try JUnique:
String appId = "com.example.win.run.main";
boolean alreadyRunning;
try {
JUnique.acquireLock(appId);
alreadyRunning = false;
} catch (AlreadyLockedException e) {
alreadyRunning = true;
}
if (alreadyRunning) {
Sysout("An Instance of this app is already running");
System.exit(1);
}
I've seen so many of this questions and I was looking to solve the same problem in a platform independent way that doesn't take the chance to collide with firewalls or get into socket stuff.
So, here's what I did:
import java.io.File;
import java.io.IOException;
/**
* This static class is in charge of file-locking the program
* so no more than one instance can be run at the same time.
* #author nirei
*/
public class SingleInstanceLock {
private static final String LOCK_FILEPATH = System.getProperty("java.io.tmpdir") + File.separator + "lector.lock";
private static final File lock = new File(LOCK_FILEPATH);
private static boolean locked = false;
private SingleInstanceLock() {}
/**
* Creates the lock file if it's not present and requests its deletion on
* program termination or informs that the program is already running if
* that's the case.
* #return true - if the operation was succesful or if the program already has the lock.<br>
* false - if the program is already running
* #throws IOException if the lock file cannot be created.
*/
public static boolean lock() throws IOException {
if(locked) return true;
if(lock.exists()) return false;
lock.createNewFile();
lock.deleteOnExit();
locked = true;
return true;
}
}
Using System.getProperty("java.io.tmpdir") for the lockfile path makes sure that you will always create your lock on the same place.
Then, from your program you just call something like:
blah blah main(blah blah blah) {
try() {
if(!SingleInstanceLock.lock()) {
System.out.println("The program is already running");
System.exit(0);
}
} catch (IOException e) {
System.err.println("Couldn't create lock file or w/e");
System.exit(1);
}
}
And that does it for me. Now, if you kill the program it won't delete the lock file but you can solve this by writing the program's PID into the lockfile and making the lock() method check if that process is already running. This is left as an assingment for anyone interested. :)