Question

"Determining unique id of a JVM..."

Asked by: diakov

Hello experts,

Imagine the following situation:

Several machines are running several system processes each, that happen to be JVMs. Each JVM runs the same software, that writes a file in a network directory somewhere. This file have to be assigned unique name, so that only one file exists per JVM and no files get overwritten. Let us assume that when a JVM is shutting down, it will delete it's corresponding file and even if it has crashed, there is a way to determine whether the particular file is "an orphan" without a running JVM. So forget about the reliability stuff.

The question is, how to generate the name of these files so it is 100% unique. The solution has to be 100% Pure Java. I have reached as far as putting the IP address of the machine in the name, but then I have to concatenate something else to distinguish the JVMs running on one machine. For machines with several network cards and IPs, we use one of them, as long as it won't change during runtime of any of the JVMs on that machine.

Cheers,
  Nik

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2000-07-14 at 06:22:38ID10700021
Tags

java

,

unique

,

jvm

,

id

Topic

Java Programming Language

Participating Experts
6
Points
300
Comments
92

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. JVM
    How to implement a JAVA Virtual Machine? May I get the source files of JVM in JAVA or C(C++)?
  2. JVM
    when I install Nescape Communicator it should already include JVM rite ? what about classpath ? if I do have JVM how to set the classpath ?
  3. on jvm
    hello anybody can answer the following qn below. when jvm gets the class file from where it cheks in the program. like whether jvm checks from the first or from the main method of the program... waiting for the answer bye deepak
  4. JVM PID
    How do i get the jvm process id, or any other id that identifies the JVM uniquely. // peyman

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: diakovPosted on 2000-07-14 at 06:26:00ID: 3370246

Note that using random generator is not 100% unique between the JVMs. I imagine it is allowed to use a constant (for example one) amount of small shared helper files to store some information on the network drive along with the unique files.

Cheers,
  Nik

 

by: Sasha_MapaPosted on 2000-07-14 at 10:02:22ID: 3375692

Nik, you describe an imaginary situation - is that the desired situation and you want to find a way to achieve it or do you already have this implemented and only need a way to uniquely name the files?

Sasha.

 

by: diakovPosted on 2000-07-14 at 10:06:16ID: 3375850

The latter.

"...only need a way to uniquely name the files..."

Cheers,
  Nik

 

by: KoboldPosted on 2000-07-14 at 10:12:34ID: 3376032

Create a RMI server that generate unique ID, so you can keep all generated ID in a vector (Serialized into a file) and always validate that the generated number is unique!

 

by: Sasha_MapaPosted on 2000-07-14 at 10:13:05ID: 3376035

Why not just numerate them 1,2,3,4 and write these numbers in a shared file. Each JVM will look up the first available number and that will be the name of the file...

Am I missing something?

Sasha.

 

by: diakovPosted on 2000-07-14 at 10:14:18ID: 3376055

Yes, synchronization.

 

by: KoboldPosted on 2000-07-14 at 10:15:39ID: 3376095

With the RMI server, you can add all the synchro you want!!

 

by: diakovPosted on 2000-07-14 at 10:18:38ID: 3376136

I cannot use a centralized program, it was the first thing I had in mind.

Do you think if I use RMI to generate IDs in each one of the JVMs, they will be unique?

Cheers,
  Nik

 

by: KoboldPosted on 2000-07-14 at 10:26:28ID: 3376350

Why dont you pass a paramters to java.exe to identify the JVM and use this parameters to generate the filename, is this because you dont control the startup of your JVM?

I just got a idea, you may use multicasting socket to notify the other JVM of your subnet that the filename XXX is now reserved, so the others JVM put the name in a array!

To use multicasting you need to add a address to your server between 224.0.0.0 and 239.255.255.255. We are using Multicasting for a similar problem!

If you need info on multicasting just ask!

 

by: Sasha_MapaPosted on 2000-07-14 at 10:43:50ID: 3376710

Well, have just one program running that will be allowed to access the file and it will receive requests to write and remove from the file through a Socket...

Is that the same Kobold is suggesting?

Sasha.

 

by: KoboldPosted on 2000-07-14 at 10:57:48ID: 3376931

Not really, my proposed mechanisism is only to notify other JVM that the current JVM is taking the name contain in the message sent! The problem with my solution is: With multicasting you cannot receive ACK because you dont know how many will receive the UDP packet!

I still think that a RMI server that provide unique ID is the best solution.

I want to know the solution that you will use Nik!!

 

by: diakovPosted on 2000-07-14 at 12:21:51ID: 3378636

I do not control the starting up of the JVM.
As I mentioned above, I can use the IP of the machine to distinguish between JVMs on different machines. Now, how can I distinguish between the JVMs on the same machine? They all run my code plus some custom code.

I was hoping on a miracle, somebody to give a 'secret' property ID of the JVM, but helaas, these things a pretyy much standartized.

One solution I have in mind is to use a Random generator, that does the following: generate a number, then generate a file name (using IP for example) and then look up whether any of the other file names for the same IP (if any) matches. If yes, generate another name. The only problem with this solution is again, the synchronization, since another JVM might be starting up at this moment checking for the name. The chances are pretty small for a name collision, but I want the best :-) (and meet the requirements).

May be a strategy like having two files (keys) per JVM, both unique, that are created with some time in between, so another JVM that is checking up file names at the same moment, can do this while the other one is delaying the creation of the second file (key).

Did you follow? What do you think?

Cheers,
  Nik

 

by: KoboldPosted on 2000-07-14 at 12:41:23ID: 3379090

Can you use a Semaphore file, when a JVM want to create a file its open the semaphore write something in it and let the file open so it is lock) when the file id create, the JVM release its lock n the semaphore file, so other JVM can create file!

 

by: KoboldPosted on 2000-07-14 at 12:41:58ID: 3379112

By the way, do you need a pure java solution?

 

by: diakovPosted on 2000-07-14 at 13:39:00ID: 3380255

Yes, a pure Java solution. I've heard that file locking schemes don't work in some OSes, and my code will run in god knows what OS. You may be right that opening a file exclusively may be used as an independend locking scheme. Any other ideas, similar to the two-phase file generation? I'll have a look to some transactional systems, how they implement the two phase commit.

Cheers,
  Nik

 

by: omry_yPosted on 2000-07-14 at 15:17:29ID: 3381771

OK Nik, how about that :

int RuntimeID = Runtime.getRuntime().hashCode();
int ThreadID =  Thread.currentThread().hashCode();


take the ip (how do u get it, anyway?)
along with those two id`s, and u are almost 100% sure u got your uniqe ID.

running my code on several netscapes, explorers, java and applet viewers simultaniously, and I never saw both of them beeing identical.


 

by: Sasha_MapaPosted on 2000-07-14 at 15:38:54ID: 3382152

>>I've heard that file locking schemes don't work in some OSes
Yes, I believe that's true...

Ok, Nik, how about this: Make a singleton class such as this:

public class Test{

  private long jvmID = (long)(Math.random()*Long.MAX_VALUE);
 
  private static Test instance = null;

  private Test(){}

  public static Test getTest(){
    if (instance==null)
      instance = new Test();
    return instance;
  }

  public static String getJVM_ID(){
    return Test.getTest().jvmID;
  }

}

 
and use getJVM_ID as the unique value for the JVM?

It looks like it should work... no?

Sasha.

 

by: Sasha_MapaPosted on 2000-07-14 at 15:50:20ID: 3382275

WOW omry... great minds think alike -- I just spent the last 2 hours testing with the hashcode of Runtime. Unfortunately my tests showed it doesn't work. The hashCode returned by Runtime.hashCode includes its location in the internal memory of the JVM. What comes from my tests is that it is not very random...

Here is an example:


---- Test.java ----

import java.io.*;

public class Test{

 public static void main(String [] args){
    try{
      InputStream in = new FileInputStream("jvmids.txt");
      OutputStream out = new FileOutputStream("jvmids1.txt");
      int b = 0;
      while ((b = in.read()) != -1)
        out.write(b);
      in.close();
      PrintStream pout = new PrintStream(out);
      pout.println(Runtime.getRuntime().hashCode());
      pout.flush();
      pout.close();
      new File("jvmids.txt").delete();
      new File("jvmids1.txt").renameTo(new File("jvmids.txt"));
    } catch (IOException e){
        e.printStackTrace();
      }
  }

}


---- end of Test.java ----


---- Run.java ----

import java.io.*;

public class Run{

  public static void main(String [] args){
    try{
      for (int i=0;i<100;i++){
        Runtime.getRuntime().exec("java Test").waitFor();
        System.out.println(i);
      }
    } catch (IOException e){
        e.printStackTrace();
      }
      catch (InterruptedException e){
        e.printStackTrace();
      }
  }

}

---- end of Run.java ----


---- Check.java ----

import java.io.*;

public class Check{

  public static void main(String [] args){
    try{
      DataInputStream in = new DataInputStream(new FileInputStream("jvmids.txt"));
      String [] jvmids = new String [10000];
      int length = 0;
      String jvmid;
      while ((jvmid = in.readLine())!=null)
        jvmids[length++] = jvmid;

      for (int i=0;i<length;i++)
        for (int j=i+1;j<length;j++)
          if (jvmids[i].equals(jvmids[j]))
            System.out.println("The JVM ID in line "+(i+1)+" equals the JVM ID in line "+(j+1));

      in.close();
    } catch (IOException e){
        e.printStackTrace();
      }
  }

}


---- end of Check.java ----


Run the Run.java file first and then Check.java -- you will see many matches...

Sasha.

 

by: omry_yPosted on 2000-07-14 at 17:14:04ID: 3383050

Sasha, looks like u are right about that.

btw : your getTest() function should be synchronized.

 

by: Sasha_MapaPosted on 2000-07-14 at 17:24:30ID: 3383130

agreed :-)

 

by: omry_yPosted on 2000-07-14 at 18:53:55ID: 3384054

stupid me!
your code does the wrong test!
it proves that two virual machines that run one after the other can return the same result for
Runtime.getRuntime().hashCode()
not that two jvm`s running simultaniously can!
in your test, at any given momemnt, maximum of two jvms are runing :
the one running Run.class, and the one running Test.class.
and what it checks is only the id for Test.class, for this instance.
Test.class exists and run opens a new jvm for the Test.class.

it means it does not proves me wrong!


...//..//..//..//..//..//..//..//..//..//

one hour later, I have proven I was wrong.
this modified code prove that even for jvm that running at the same time,
Runtime.getRuntime().hashCode()
can return the same value, and that the same value actualy come from diferent jvm`s (and its not because of some cache magic of the os or java.exe)



here it is (your Check.java will not work, but its easy enough to spot dupes with bare eyes).

--- jvm_id.java

public class jvm_id{

  private long jvmID = (long)(Math.random()*Long.MAX_VALUE);
 
  private static jvm_id instance = null;

  private jvm_id(){}

  public static jvm_id getJVMID(){
    if (instance==null)
      instance = new jvm_id();
    return instance;
  }

  public static String getJVM_ID(){
    return String.valueOf(getJVMID().jvmID);
  }

}



---- Run.java


import java.io.*;

public class Run{

  public static void main(String [] args){
      for (int i=0;i<100;i++)
      {
        new Runner(i).start();
      }
  }

}

class Runner extends java.lang.Thread
{
int n;
        Runner(int n)
        {
           System.out.println("new Runner"+n);
           this.n = n;
        }

        public void run()
        {
           try
           {
                Runtime.getRuntime().exec("java Test jvm#" +String.valueOf(n)).waitFor();
                System.out.println("done with jvm #"+n);
           }
           catch (Exception e)
           {
              e.printStackTrace();
           }

        }
}




------  Test.java


import java.io.*;

public class Test{

 public static void main(String [] args){
    try{

      InputStream in = new FileInputStream("jvmids.txt");
      OutputStream out = new FileOutputStream("jvmids1.txt");

      int b = 0;
      while ((b = in.read()) != -1)
        out.write(b);
      in.close();
      PrintStream pout = new PrintStream(out);
      pout.println(args[0] + " : " + Runtime.getRuntime().hashCode() + " JVMID : " +jvm_id.getJVM_ID());
      pout.flush();
      pout.close();
      new File("jvmids.txt").delete();
      new File("jvmids1.txt").renameTo(new File("jvmids.txt"));
    } catch (IOException e){
        e.printStackTrace();
      }

      try{Thread.sleep(200);}catch(Exception e){}
  }

}






 

by: omry_yPosted on 2000-07-14 at 18:56:52ID: 3384092

stupid me!
your code does the wrong test!
it proves that two virual machines that run one after the other can return the same result for
Runtime.getRuntime().hashCode()
not that two jvm`s running simultaniously can!
in your test, at any given momemnt, maximum of two jvms are runing :
the one running Run.class, and the one running Test.class.
and what it checks is only the id for Test.class, for this instance.
Test.class exists and run opens a new jvm for the Test.class.

it means it does not proves me wrong!


...//..//..//..//..//..//..//..//..//..//

one hour later, I have proven I was wrong.
this modified code prove that even for jvm that running at the same time,
Runtime.getRuntime().hashCode()
can return the same value, and that the same value actualy come from diferent jvm`s (and its not because of some cache magic of the os or java.exe)



here it is (your Check.java will not work, but its easy enough to spot dupes with bare eyes).

--- jvm_id.java

public class jvm_id{

  private long jvmID = (long)(Math.random()*Long.MAX_VALUE);
 
  private static jvm_id instance = null;

  private jvm_id(){}

  public static jvm_id getJVMID(){
    if (instance==null)
      instance = new jvm_id();
    return instance;
  }

  public static String getJVM_ID(){
    return String.valueOf(getJVMID().jvmID);
  }

}



---- Run.java


import java.io.*;

public class Run{

  public static void main(String [] args){
      for (int i=0;i<100;i++)
      {
        new Runner(i).start();
      }
  }

}

class Runner extends java.lang.Thread
{
int n;
        Runner(int n)
        {
           System.out.println("new Runner"+n);
           this.n = n;
        }

        public void run()
        {
           try
           {
                Runtime.getRuntime().exec("java Test jvm#" +String.valueOf(n)).waitFor();
                System.out.println("done with jvm #"+n);
           }
           catch (Exception e)
           {
              e.printStackTrace();
           }

        }
}




------  Test.java


import java.io.*;

public class Test{

 public static void main(String [] args){
    try{

      InputStream in = new FileInputStream("jvmids.txt");
      OutputStream out = new FileOutputStream("jvmids1.txt");

      int b = 0;
      while ((b = in.read()) != -1)
        out.write(b);
      in.close();
      PrintStream pout = new PrintStream(out);
      pout.println(args[0] + " : " + Runtime.getRuntime().hashCode() + " JVMID : " +jvm_id.getJVM_ID());
      pout.flush();
      pout.close();
      new File("jvmids.txt").delete();
      new File("jvmids1.txt").renameTo(new File("jvmids.txt"));
    } catch (IOException e){
        e.printStackTrace();
      }

      try{Thread.sleep(200);}catch(Exception e){}
  }

}






 

by: omry_yPosted on 2000-07-14 at 18:58:07ID: 3384111

to summerize, a static random number, preferably in a singleton, like Sasha suggested is probebly your best choice.

 

by: Sasha_MapaPosted on 2000-07-15 at 01:27:52ID: 3386775

Omry, my test DOES work, it just doesn't do what you thought it does. I didn't try to prove that 2 JVMs running concurrently can return the same Runtime.getRuntime().hashCode() (which is still true according to your test) -- my program proves that the hashCode of the Runtime (the location of the only Runtime object in the internal JVM memory) is not random enough between JVMs to be used as an ID... It is quite obvious that 2 JVMs running concurrently can return the same hashCode - but the chance of that happening is the same as the chance of ANY 2 JVMs running (concurrently or not). I just tested them non-concurrently - the concurrent version that you wrote just proves the same thing I already did :-)

Sasha.

 

by: heyhey_Posted on 2000-07-15 at 02:25:17ID: 3387117

listening ...

 

by: Sasha_MapaPosted on 2000-07-15 at 03:23:04ID: 3387710

heyhey is listening - wow :-)

 

by: omry_yPosted on 2000-07-15 at 07:38:22ID: 3389530

only thing u are forgeting, Sasha, is that two JVM`s runnign at the same time are not using the same physical memory, so the actual memory address of each Runtime is different.
unfortunetly, Java wont let us know that address, even indirectly through hashCode(), so it does not matter.
and btw : a whole singleton is just too much for such a simple thing.

this is simplier, and will also work fine :

class jvm_id
{
   private static long id = 0;
   public static long getID()
   {
      if(id == 0)
      {
         id = (long)(Math.random()*Long.MAX_VALUE) + 1/*to make sure its not 0 again*/;

      }
      return id;
   }
}

 

by: Sasha_MapaPosted on 2000-07-15 at 10:22:38ID: 3391170

>> two JVM`s runnign at the same time are not using the same physical memory
Yes, but if you KNOW the fact that the hashCode is just the internal memory location, you know that it doesn't matter :-)

I agree that the static number is simpler, but you need to use Long.MAX_VALUE-1 so that you don't overflow :-)

Sasha.

 

by: omry_yPosted on 2000-07-15 at 10:43:11ID: 3391392

hashCode is a native function, u dont know what the f it does.
and by concept, it has nothing to do with the location of the memory, just its content.


even if it overflows, it will still be random.

 

by: Sasha_MapaPosted on 2000-07-15 at 11:17:43ID: 3391753

This of course doesn't prove anything, but from the documentation on Object.hashCode:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

Sasha.

 

by: Sasha_MapaPosted on 2000-07-15 at 11:23:09ID: 3391778

Omry - relax.

 

by: diakovPosted on 2000-07-15 at 12:15:52ID: 3392332

I agree that two JVMs can return the same hashCode() for the Runtime object.
Anyway, for the first approach 3 days ago, for something relatively random I used java.util.Random.nextLong() that is a random generator initialized with the current time in milliseconds. Apparently, if the two random generators in each JVM, have been  initialized with the same time, they would get colliding IDs. How is Omry's suggestion better than this?


Cheers,
  Nik

 

by: Sasha_MapaPosted on 2000-07-15 at 12:33:37ID: 3392452

Sorry Nik, I didn't get your last post, could you rephrase?

Sasha.

 

by: Sasha_MapaPosted on 2000-07-15 at 12:52:34ID: 3392610

Hmm, I thought the random number generator was implemented in native code that would allow accessing better time resolution than 55 ms on win95/98 - it isn't. What this means is that my solution isn't random enough either - on win95/98, 2 JVMs that get started within 55 ms of each other can easily return the same ID. The two comforting things I can think of are that the time of creation of my singleton is more random and that it takes much longer than 55ms to start a JVM (but still they can be run concurrently). What do you do with random numbers to get a more random number? :-) You combine them somehow. What I suggest is that you use both the random number trick and the memory address of more than one object (not singleton - just a static array of Objects that you instantiate at your will). You can run some tests either by yourself or by modifing the testing code given above to check whether that is random enough, but I guess that if after creating some objects, you create yet another java.util.Random and use that TOO, it should be very random.

As for a magic solution - the JVMs aren't aware of each other, so in theory they can be completely identical (except from outside one of them, where you can actually look at their location in the memory), which eliminates the possibility to positively uniquely identify a JVM.

Just wish that the random generator was better in Java (using time resolution in cpu ticks for example)...

Sasha.

 

by: ranakPosted on 2000-07-15 at 14:09:17ID: 3393414

Hi Nik,

   Why don't you use this
   java.rmi.dgc.VMID.
This is being used by JINI, which is not limited to RMI.
I hope it will return a differentId if the JVM restarts on any machine.

If you want to identify any Object across multiple JVMs than use
java.rmi.server.ObjID

Ranak


 

by: omry_yPosted on 2000-07-15 at 14:42:30ID: 3393730

what version of the jdk are u using? because this dgc does not apear in the JDK 1.2 API Documentation.

 

by: omry_yPosted on 2000-07-15 at 14:49:39ID: 3393811

btw Sasha, your statment :

"As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects"

is wrong.

hashCode may return the same ID for two diferent objects.
u may want to learn how a hashtable works internaly, and u`ll figure out why u are wrong.

 

by: Sasha_MapaPosted on 2000-07-15 at 14:55:52ID: 3393870

Umm, Omry - it's not my statement, it's from the docs.

How about this idea - set up a server that would allow to connect to it and ask for an ID, the getID method would be synchronized and then it can just return 1,2,3,4 etc. Each time it's first run, your code will connect to that server and ask it for an ID - that ID will be the JVM ID.

The only problem that I can think of with that approach is that the server may not be able to handle that much load. However this is easy to solve - just divide the IPs into ranges and each range will connect to a different server (you'll set up more than 1 server), making sure each JVM gets a unique number...

Sasha.

 

by: Sasha_MapaPosted on 2000-07-15 at 22:11:30ID: 3397550

Hehe, ranak - here is the source code that calculates this so called unique ID:

private static byte[] computeAddressHash() {
  /** Get the local host's IP address. */
  byte[] addr = (byte[]) java.security.AccessController.doPrivileged(
    new PrivilegedAction() {
      public Object run() {
        try {
          return InetAddress.getLocalHost().getAddress();
        } catch (Exception e) {}
         return new byte[] { 0, 0, 0, 0 };
      }
   });
  byte[] addrHash;
  final int ADDR_HASH_LENGTH = 8;
  try {
     /** Calculate message digest of IP address using SHA. */                    MessageDigest md = MessageDigest.getInstance("SHA");           ByteArrayOutputStream sink = new ByteArrayOutputStream(64);           DataOutputStream out = new DataOutputStream(new     DigestOutputStream(sink, md));
    out.write(addr, 0, addr.length);
    out.flush();
    byte digest[] = md.digest();
    int hashlength = Math.min(ADDR_HASH_LENGTH, digest.length);
    addrHash = new byte[hashlength];
    System.arraycopy(digest, 0, addrHash, 0, hashlength);
  } catch (IOException ignore) {
       /* can't happen, but be       deterministic anyway. */
       addrHash = new byte[0];}
     catch (NoSuchAlgorithmException complain) {
       throw new InternalError(complain.toString());
     }
  return addrHash;
}


What it essentially does is take the IP address of the host and apply SHA to it. I'm not sure how SHA exactly works, but since it doesn't have an access to a better random number generator - it can't give you a more random number than what I proposed (I think SHA is deterministic anyway...).

Sasha.

 

by: Sasha_MapaPosted on 2000-07-15 at 22:16:31ID: 3397590

Sorry about the broken alignment - the pasting into these EE text areas doesn't work very well, especially since the font isn't monospaced...

Sasha.

 

by: Sasha_MapaPosted on 2000-07-15 at 22:19:20ID: 3397595

And here is the first line of the documentation on java.rmi.server.ObjID:
"An ObjID is used to identify remote objects uniquely in a VM over time."

That wouldn't be distinct between 2 JVMs.

Sasha.

 

by: omry_yPosted on 2000-07-15 at 23:09:07ID: 3397752

how about that?
each new jvm will look for the first free port, and will open it and use it as an ID along with the IP ?

Sasha, Nik said he cant use a centralized program.

 

by: Sasha_MapaPosted on 2000-07-15 at 23:52:20ID: 3398010

>>each new jvm will look for the first free port
Well, you'd better use the last free port and not the first one. Otherwise, I think it's a possible solution, but still needs to be tested, because I'm not quite sure what happens when you try to listen on a port that someone is already listening on, but I think it would throw an IOException. But overall, the solution sounds like it will work (what about the case when you aren't allowed to open a ServerSocket?).

Nik, why can't you use the server solution I gave?

Sasha.

 

by: omry_yPosted on 2000-07-16 at 00:05:24ID: 3398110

"Sorry about the broken alignment - the pasting into these EE text areas doesn't work very well, especially since the font isn't monospaced..."

your code always looks that way :-)
(atleast to me).

 

by: diakovPosted on 2000-07-16 at 00:39:33ID: 3398310

Sasha, I do not want to use a server, as somone has to take care of starting it up on the host. Also, I do not want to use a fixed common resource (port) to resolve the reference (socket) to this server, since I do not know how many JVM the client may start, which first, etc. For example, in case of a socket application for the uniqueness generator, if the port is occupied for some reason, and the first free port is used, how the other JVMs are going to know about it?

My JVM can be 1.2 and higher.

ranak's suggestion java.rmi.dgc.VMID

"Create a new VMID. Each new VMID returned from this constructor is unique for all Java virtual machines under the following conditions: a) the conditions for uniqueness for objects of the class java.rmi.server.UID are satisfied, and b) an address can be obtained for this host that is unique and constant for the lifetime of this object."

lead me to

http://java.sun.com/products/jdk/1.1/docs/api/java.rmi.server.UID.html#UID()

"Create a pure identifier that is unique with respect to the host on which it is generated. This UID is unique under the following conditions: a) the machine takes more than one second to reboot, and b) the machine's clock is never set backward. In order to construct a UID that is globally unique, simply pair a UID with an InetAddress. "

Sasha, Omry_y, I have the feeling that this is it. What do you think? I'll give it a try on Monday... I hope the toString() for this UID will always produce something that I can put in a name of a file (e.g. a number)

Cheers,
  Nik

 

by: diakovPosted on 2000-07-16 at 00:39:54ID: 3398311

Adjusted points from 200 to 300

 

by: heyhey_Posted on 2000-07-16 at 00:42:40ID: 3398316

> I'm not quite sure what happens when you try to listen on a port that someone is already listening on, but I think it would throw an IOException'

well - the same problem as with file locking - it may work on some systems / JVM and not work on other (but it's better than files locking - I've used it several times)

 

by: heyhey_Posted on 2000-07-16 at 00:57:02ID: 3398410

> Create a pure identifier that is unique with respect to the host

and how exactly does it create this unique identifier ? pure magic ? :)

 

by: Sasha_MapaPosted on 2000-07-16 at 01:40:10ID: 3398582

Source code:

public UID() {

  synchronized (mutex) {
    if (lastCount == Short.MAX_VALUE) {
       boolean done = false;
       while (!done) {
          time = System.currentTimeMillis();
          if (time < lastTime+ONE_SECOND) {
           // pause for a second to wait for time to change
              try {
                Thread.currentThread().sleep(ONE_SECOND);
              } catch (java.lang.InterruptedException e) {} // ignore exception
              continue;
          } else {
             lastTime = time;
             lastCount = Short.MIN_VALUE;
            done = true;
          }
       }
   } else {
      time = lastTime;
   }
    unique = hostUnique;
    count = lastCount++;
  }

}


Same randomness as Math.random() ran on 2 JVMs simultaneously. It just uses the time making sure that the method never returns twice in the same second.

Sasha.

 

by: heyhey_Posted on 2000-07-16 at 02:01:02ID: 3398692

>  that the method never returns twice in the same second.

in one JavaVM :)

 

by: Sasha_MapaPosted on 2000-07-16 at 02:11:18ID: 3398732

Right, sorry, I'm not familiar with RMI, but Omry explained me some general stuff about it, so I think I get it :-)

I think we gave enough random solutions that combined together will be very random :-)

Sasha.

 

by: Sasha_MapaPosted on 2000-07-16 at 02:20:03ID: 3398767

Nik, you said you don't want a centralized program, but an RMI server is such (no?)... so why do you think the UID will work for you?

Sasha.

 

by: omry_yPosted on 2000-07-16 at 02:21:52ID: 3398769

two programs running on the same computer cannot listen to the same port.
a tcp ip implementation that does not enforce it is not a valid implementation.

its a behaivour specified by a common standard (TCP IP), not by some descisions made by some os designers (like file lock handling).
 

 

by: omry_yPosted on 2000-07-16 at 02:31:41ID: 3398852

two programs running on the same computer cannot listen to the same port.
a tcp ip implementation that does not enforce it is not a valid implementation.

its a behaivour specified by a common standard (TCP IP), not by some descisions made by some os designers (like file lock handling).
 

 

by: heyhey_Posted on 2000-07-16 at 06:08:56ID: 3400430

> two programs running on the same computer cannot listen to the same port.

ABSOLUTELY NOT TRUE (on all kinds of Unix-es and as far as I know on Windows).

you can bind() (BSD sockets) more than socket to the same IP / port pair (using the appropriate socket options).

but all the Java implementations that I've seen won't bind ServerSocket to some port if some other Socket already listens there.

 

by: omry_yPosted on 2000-07-16 at 06:40:55ID: 3400830

correct me if I am wrong, but such a thing (two programs listening to the same port) is only available for applications with speciel needs, and should not be possible by default, without requesing for it specificly.

 

by: heyhey_Posted on 2000-07-16 at 10:18:48ID: 3403330

>  is only available for applications with speciel needs,

well - BSD Sockets support multiple applications (even different processes) listening on the same socket (IP address / port) (the one that will handle first incoming socket connection is chosen randomly ??).
I'm not sure what 'special needs' is :) but as I already said, all Java implementations that I've been working with does not support this behaviour.

 

by: diakovPosted on 2000-07-16 at 11:42:42ID: 3404145

Also, I heard a rumour that MS is planning on releasing a new TCP stack version that allows multiple uses of the same sockets.

I had another idea, that I used to create usefull timestamps for distributed messages. I used NTP (there a lots of servers) which basically means sending some UDP packets to a server. The results is a very accurate time (in microsecond), so if I ask the time host of the current intranet (there is one in almost any intranet) or a well know host on the internet, it'll give me a good initializer for the Random. If all JVM (running my code) on the same machine use the same server, they have a good chance of having different initializers for their Randoms. Do you think this'll work?

Note that the delay that ievitably is there is kind of predicted and removed from the NTP, but some error is always there. I think this is insignificant when I would use NTP to get values for initializing the Random (however gnificant for the timestamps in the events that I produced, so I used some other techniques too - logical clocks).

Cheers,
  Nik

 

by: mbormannPosted on 2000-07-16 at 20:32:58ID: 3409853

>>>Each JVM runs the same software, that writes a file in a network directory somewhere. This file have to be assigned unique name, so that only one file exists per JVM and no files get overwritten.

Pardon me if I am wrong but can't you do a list of the current files and then form your unique file name somehow ?

 

by: diakovPosted on 2000-07-16 at 23:27:03ID: 3411671

mbormann, I do not want to do that. One of the reasons is that listitng won't be synchronized, thus I do not need whether some JVM is not making the file with the same name I would choose at the moment. Another reason is, that the files may be too many.

Cheers,
  Nik

 

by: omry_yPosted on 2000-07-16 at 23:46:44ID: 3411938

I still dont see why using network ports is not good enough.

"Also, I do not want to use a fixed common resource (port) to resolve the reference (socket) to this server, since I do not know how many JVM the client may start, which first, etc. For example, in case of a socket application for the uniqueness generator, if the port is occupied for some reason, and the first free port is used, how the other JVMs are going to know about it?"

ports are virutualy unlimited in that context.
u have thousends of them, and only that so meny jvm`s one computer can handle, so using a "fixed common resource" is not a problem here".
you know enough to be sure he will not have more then 1,000 jvm on the same machine,right?
which stats first is not a problem.
u can state that your jvm`s uses ports 233000 up to 234000.
each jvm will look for the first available slot in this range, starting with 233000, and increading if someone is listening.
a listener may be one of your jvm`s, or just another program. it does not really matter.
and besides, using network comunication u can find out if its ont of your jvm`s (just ask through the socketu just opened, who is it).
I dont see any problem with this approach.

 

by: diakovPosted on 2000-07-16 at 23:56:39ID: 3412012

OK, how about synchronization then? After finished scanning, I wil do a row or two in the source code of calculations of the next id, and try to alloccted the next port. What if it is occupied by that time already? Just continue with the next port? Won't there be finer synch problems that will pop up later?

For the moment Random + init via NTP time is the runner up for the solution.

Cheers,
  Nik

 

by: omry_yPosted on 2000-07-17 at 00:06:40ID: 3412170

test

 

by: omry_yPosted on 2000-07-17 at 00:12:14ID: 3412271

I dont see any problems with going to the next port if the one u are trying to open is already busy.

it looks like it will work for me.
ofcourse, negative aspects includes depening on existence of a tcp ip stack, but then again, so does your NTP server solution.


 

by: diakovPosted on 2000-07-17 at 00:23:38ID: 3412490

FYI, NTP uses datagaram sockets.

I'm going to try some of the stuff and will tell you about the results.

Cheers,
 Nik

 

by: omry_yPosted on 2000-07-17 at 00:31:45ID: 3412630

10x for the info.

it still depends on a network protocol that supports datagrams beeing installed.

 

by: heyhey_Posted on 2000-07-17 at 01:41:29ID: 3413710

I would rather use ServerSocket based locking too

 

by: Sasha_MapaPosted on 2000-07-17 at 02:07:35ID: 3414257

>>I would rather use ServerSocket based locking too
I thought that's what was meant from the beginning, you don't try to connect to ports (scanning, as Nik said - is that what he meant?) but instead try opening ServerSockets until you don't get an IOException when trying to open one... That should be pretty synchronized - you don't need any calculations, you decide on the port and open the socket in the same operation (which is done by the OS, so it should be synched, except for the BSD sockets heyhey described)...

Sasha.

 

by: KoboldPosted on 2000-07-17 at 06:19:52ID: 3420510

Nic, i have one question, how can you share a directory to your application when you dont know what OS will be running your Application!

Also, to solve this OS problem, and the unique file ID, you can use an FTP server to serve your file!

 

by: diakovPosted on 2000-07-17 at 06:22:54ID: 3420612

Abstract from the details on the file system. Lets assume you have a system property set to a directory somewhere.

I do not use an ftp.

Cheers,
  Nik

 

by: ranakPosted on 2000-07-17 at 10:23:21ID: 3429270

Just FYI
multiple processes can't bind to single port.
This is allowed in case of Multicast.
Multicast is in between uniCast and Broadcast, where all the members subscribed to this multicast group can listen at that port.

So many classes in the rmi package are not just for RMI , which is also used by CORBA , distributed computing.
For more info on Multicast and using RMI pacakges look at the JINI docs .

java.rmi.server.ObjID is unique in VM.
It is to be used in assciation with java.rmi.dgc.VMID to identify any object uniquely across JVMs

java.rmi.server.UID is  unique id on a host.



 

by: heyhey_Posted on 2000-07-17 at 14:47:38ID: 3436597

> java.rmi.server.ObjID is unique in VM.

so you hav ONE number that is UNIQUE in ONE VM ? I would rather use 0 instead :)

> multiple processes can't bind to single port.

any proof ?

 

by: mbormannPosted on 2000-07-17 at 16:25:32ID: 3438010

heyhey ,
as you said some flavors of UNIX allow multiple processes to bind to a single port if I recall correctly instead of INADDR_ANY they can use REUSEPORT (similar to REuSEADDRESS)flag but the caveat is all users must specify the flag. I thik that Solaris 2.6 does too.

ranak is right that this is mostly used alongwith Multicast and is not possible unless all processes use the REUSEPORT option.

 

by: ranakPosted on 2000-07-17 at 17:26:04ID: 3438777

using MultiCast multiple Sockets(process) can bind to a single port.

You can refer to any unix network programming like Recard steven's book

Multiple sockets are not allowed to bind to the same port for security reason.

They can do that if all sockets set the option of SO_REUSEADDR and other stuffs.
This was provided to support Multicast.

Ref:
http://www.cs.ucl.ac.uk/staff/c.perkins/MM-Briefing-Day/slides-isidor/tsld005.htm

http://www.lcg.org/sock-faq/detail.php3?id=50

http://foldoc.doc.ic.ac.uk/man.cgi?bind

 

by: heyhey_Posted on 2000-07-17 at 23:48:32ID: 3441432

> Multiple sockets are not allowed to bind to the same port for security reason.


The SO_REUSEPORT flag allows multiple processes to bind to the same address provided all of them use the SO_REUSEPORT option.

 

by: diakovPosted on 2000-07-18 at 00:03:15ID: 3441553

ranak, VMID uses uid, and you saw the source code of its constructor. It uses random, the way I use it. This means the granularity is around several millisecond, and if two JVMs are ran within 1 ms, they'll get the same id's.

heyhey, this is exactly why I am reluctant to use sockets. Different OSes, different sockets. Anyway, I'll try this too.

Cheers,
  Nik

 

by: omry_yPosted on 2000-07-18 at 00:23:19ID: 3441734

Nik, what I understand from mbormann and heyhey discussion, u cant really no program can share a port accidently, if it wasnt intended too.
and java wont event let you specify you want it to share ports.

 

by: Sasha_MapaPosted on 2000-07-18 at 01:15:25ID: 3442214

>>This means the granularity is around several millisecond
Isn't time resolution on windows much lower than that (55 ms on win95/98 and 5 on NT)? It would be very good if it was 1ms.

Sasha.

 

by: Sasha_MapaPosted on 2000-07-18 at 01:17:08ID: 3442234

Besides, wasn't it explained that the constructor is ran on the RMI server and not on the JVMs, so it is synchronized. Am I missing something about RMI?

Sasha.

 

by: diakovPosted on 2000-07-18 at 01:20:42ID: 3442294

In NT/2000 there is a thing called high-resolution cocks. It is an API that can deliver callbacks in microsecond, depending on the speed of the machine. Anyway, Java doesn't use that. The JMF does, when the native supoport is installed.

The UID() can be instantiated from anywhere I think, what do you mean with the 'server' stuff, Sasha? If I would use UID, I would only instantiate it, without any other RMI shtuff.

Cheers,
  Nik

 

by: diakovPosted on 2000-07-18 at 01:22:48ID: 3442333

Omry, yes, I agree with you, I will try this approach too. Right now I'm trying to run my programs. I will incorporate the test for the unique ID's after that :-)

Cheers,
  Nik

 

by: Sasha_MapaPosted on 2000-07-18 at 01:43:41ID: 3442531

>In NT/2000 there is a thing called high-resolution cocks.
I thought you wanted your app to be platform independent...

Well, the RMI stuff proposed (as I understand it, maybe I'm wrong) is that you ask the RMI server to give you your ID, not create one yourself.

Sasha.

 

by: diakovPosted on 2000-07-18 at 02:41:11ID: 3443233

Sasha, isn't the constructor of UID public? This means I can use it directly and explicitly. I do not really care whether the RMI server will use it internally to generate it's uids, the problem is that this uid, under some circumstenses will not be unique between two JVMs running on the same machine. I want this to happen as rarely as possible.

Remember, I do not want a centralized server, that will give me ids, as it is a bottleneck and a single point of failure.

Cheers,
  nik

 

by: Sasha_MapaPosted on 2000-07-18 at 03:19:23ID: 3443533

>>Sasha, isn't the constructor of UID public? This means I can use it directly and explicitly
I think we'd better wait for heyhey to answer that... I don't know RMI and I'd hate to make such assumptions, but I think that in order for that method to work, your app needs to be an RMI server.

Sasha.

 

by: diakovPosted on 2000-07-18 at 03:23:27ID: 3443614

From the docs, I do not see any dependencies of UID class with anything that is RMI. No constructor parameter, no nothing :-)

Just the package name contains 'rmi' and 'server' but this is not important.

Cheers,
  nik

 

by: heyhey_Posted on 2000-07-18 at 23:30:10ID: 3459014

UID will work only INSIDE THE SAME JavaVM instance. it won't work for you if you have started several JavaVM's on the same physical machine (same IP), but ServerSockets will work most of the time  (I'd say 'always' :)

 

by: diakovPosted on 2000-07-20 at 00:19:18ID: 3475975

It has been a good discussion. I close it now. Since I already had in mind all the random related stuff I won't be grading these ideas, and I believe omry_y has passed on the idea about the server sockets that is perfectly usable with Java.

Thanks you all for the ideas, I hope you learned new things too.

ranak, I am rejecting your answer, as it turns out UID is used by VMID, and UID uses random stuff again.

Cheers,
  Nik

 

by: diakovPosted on 2000-07-20 at 00:23:28ID: 3475999

Comment accepted as answer

 

by: diakovPosted on 2000-07-20 at 00:23:28ID: 3476000

Kobold spoke about sockets first, but omry_y stated it using server sockets. This is the distributed solution I am looking for.

Cheers,
  Nik

 

by: omry_yPosted on 2000-07-20 at 01:08:22ID: 3476314

10x.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...