socket mac os x vs windows java slow - java

Please help me figure out why the Mac OS X Java takes 5 times longer than the Windows XP Java.
I have some code that behaves differently on Mac and PC Java. I have a Java GUI that talks to a number of "servers" on a Windows XP box.
When I run the GUI on another Windows XP machine or a linux machine the LabView receives the messages and responds within 1 second.
When it runs from the Mac OS X box, it takes 5 seconds. The pause seems to be (from all we can tell debugging) between the time I THINK I send the string "pot 7\r\n" and the time it is actually received by LabView.
LabView sees the pot 7 command (we have a display to check) immediately when coming from Windows but according to the LabView programmer the command does not show up on the screen until the 5 seconds has passed when sent from the Mac OS machine.
I'll try to provide enough code here that someone who knows more might say aha!
String IPaddress;
int commPort;
BufferedReader reader;
PrintWriter writer;
Socket sock;
long timeout = 8000;
...
public synchronized void connectCommPort() {
if (commportconnected != true) {
try {
sock = new Socket();
InetSocketAddress endpoint = new InetSocketAddress(IPaddress, commPort);
sock.connect(endpoint, timeout);
sock.setSoTimeout( timeout );
reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
writer = new PrintWriter(sock.getOutputStream());
commportconnected = true;
errorstatus = false;
} catch (IOException ex) {
logwriter("LabV: WARNING - network connection to Labview command port failed."+ex.toString());
commportconnected = false;
errorstatus = true;
}
}
}
...
public synchronized float[] readpots() {
String message = "pot 7";
connectCommPort();
if (commportconnected) {
try {
writer.print(message + "\r\n");
writer.flush();
logwriter("LabV: [sent] " + message);
shortpotvalues = potslistener();
} catch (Exception ex) {
}
disconnectCommPort();
}
potvalues[0] = shortpotvalues[0];
potvalues[1] = shortpotvalues[1];
potvalues[2] = shortpotvalues[2];
potvalues[3] = shortpotvalues[3];
potvalues[4] = shortpotvalues[4];
potvalues[5] = shortpotvalues[5];
potvalues[6] = shortpotvalues[6];
potvalues[7] = 5.0f;
return potvalues;
}
public synchronized float[] potslistener() {
String message = null;
int i = 0;
try {
//while ((message = reader.readLine()) != null && i < shortpotvalues.length) {
while (i < shortpotvalues.length) {
message = reader.readLine();
if ( message != null )
{
logwriter("LabV: [received] " + message);
if (message.contains("."))
{
shortpotvalues[i] = Float.parseFloat(message);
i++;
}
}
else
{
logwriter("LabV: received NULL unexpectedly, may not have all pots correct");
}
} // close reader-ready-while
} catch (ArrayIndexOutOfBoundsException aiofbex) {
logwriter("LabV: in potslistener() Array out of bounds! " + aiofbex.toString());
} catch (Exception ex) {
logwriter("LabV: in potslistener() got exception: " + ex.toString());
}
return shortpotvalues;
}
On Mac OS X 10.8. running java -version gives:
marks-Mac-mini:~ mark$ java -version
java version "1.6.0_43"
Java(TM) SE Runtime Environment (build 1.6.0_43-b01-447-11M4203)
Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01-447, mixed mode)
On Windows XP (the java used when the GUI is run on the windows and works fine) gives:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\gus>java -version
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) Client VM (build 23.3-b01, mixed mode, sharing)
Finally here is part of the log from the PC:
2013-03-19T11:45:22.000 LabV: [sent] pot 7
2013-03-19T11:45:22.921 LabV: [received] 2.310835
2013-03-19T11:45:22.921 LabV: [received] 2.447397
And correspondingly from the Mac (note the 5 seconds between the send and the first received):
2013-03-13T12:13:17.092 LabV: [sent] pot 7
2013-03-13T12:13:22.513 LabV: [received] 2.300508
2013-03-13T12:13:22.514 LabV: [received] 2.112090
Thanks in advance for any help/advice.
Follow-up:
I've since discovered that if I use a 10.7.5 Mac OS machine with the same Java the speed is the same as the Windows XP. I am now looking into problems with 10.8.3 and networking and or security firewall settings. Again, any help is appreciated.

Maye this will help someone else.
When were running on an isolated network, this problem became a show-stopper. After all that work (simulator, outputstream, disabling bonjour, etc), the solution was to edit the hosts file on the Microsoft Windows XP box.
I think this worked because there was no time spent looking for a WINS or DNS server. What is annoying is that on a mac or linux box on the same network, addressing an IP address automatically eliminated any DNS calls that resulted in timeouts. Editing the file removed the strange delay completely. When I have access to the machine again, I will be more specific about what the edits were.
The debugging that led us to this problem was noticing some netbios request that took a long time to respond. I was not there when they saw this. My understanding is that they ran a packet sniffer on the mac os machine and saw these requests. When they edited the Windows machine hosts file, the problem went away (it could find the mac without that netbios broadcast).
"After some packet sniffing we have determined that the delay we've
been experiencing when querying the Agilent from the GUI has been due
to [the Windows XP machine] flailing about looking for the Agilent [a
motor controller] via the WINS service. Can't say that I completely
understand what's going on, but we verified that the delay goes away
when we turn the NetBIOS service off.
Which would be all good, except
that windows file sharing seems to depend on the NetBIOS service, thus
we can't access the disk on [the Windows XP machine] without it.
So we added two lines in the host file"
That is what my colleague sent me. So it was two systems away from my java code... I addressed a LabView app on a Windows XP box. I wrote a simulator for the LabView app. But the network problem was between the LabView app and another piece of equipment. So his solution was to put two lines in Windows\System32\Drivers\etc\hosts to resolve the Mac and the Agilent on the Windows side and the network delay went away!

Related

Why does Java InetAddress.isReachable() not work on JRE 1.8.x like on JRE 1.7.x

I've written a programm a year ago and today I saw that this programm give me some curious output. One kind to detect PC's or notebooks in our network I'm using the InetAddress class. My programm works how it should, until Java 1.8.x runs on the executing machine, than the InetAddress.isReachable() gives me a "TRUE" also if there is no machine on that IP address.
private String ipAddress = "192.168.1.200";
inetAddr = InetAddress.getByName(ipAddress);
inetIsReachable = inetAddr.isReachable(8000);
debug += " INET is reachable: " + inetIsReachable;
System.out.println(debug);
That is really strange, and I don't know how to detect this error.
Kind regards proto
°°°°°EDIT
I tried this code... running on Java 1.7
inetAddr = InetAddress.getByName(ipAddress);
inetIsReachable = inetAddr.isReachable(8000);
// FALSE
byte[] a = new byte[]{(byte) 192,(byte) 168,1,(byte) 200};
inetAddr = InetAddress.getByAddress("192.168.1.200", a);
inetIsReachable = inetAddr.isReachable(8000);
// also FALSE
But a ping on commandline reaches the machine!
°°°°°EDIT-2
Java 1.8
192.168.1.200 - InetAddress true - cmd ping true - there is a machine
192.168.1.202 - InetAddress true - cmd ping false - there is no machine
Java 1.7
192.168.1.200 - InetAddress false - cmd ping true - there is a machine
192.168.1.202 - InetAddress false - cmd ping false- there is no machine
This looks like bug #JDK-8159410, apparently introduced after 8u73.

HP ALM OTAClient.dll is incompatible with 64Bit OS

I Added a code to connect and create a defect in HP ALM through Eclipse(Java) in which it communicates OTAClient and com4j.jar. I successfully able to connect and create a defect in 32 Bit OS but i couldn't able to connect it on 64 bit based OS.
I walkaround some of the solutions posted here and even though following the solution successfully i couldn't achieve a solution.
[1]: com4j on Windows 64 bit ..
Here is My Code
import com.ClassFactory;
import com.IBug;
import com.IBugFactory;
import com.ITDConnection;
import com4j.Variant;
public class AlmQc {
public static void main(String args[])
{
login();
}
public static void createDefect(ITDConnection connection) {
IBugFactory bugFactory = (IBugFactory) connection.bugFactory().queryInterface(IBugFactory.class);
IBug bug = (bugFactory.addItem(new Variant(Variant.Type.VT_NULL))).queryInterface(IBug.class);
bug.assignedTo("Administrator");
bug.detectedBy("Administrator");
bug.status("New");
bug.project("Banking");
bug.summary("Created by Esh");
//bug.priority("Low");
bug.field("BG_SEVERITY", "2-Medium");
bug.field("BG_DETECTION_DATE", "2016-01-27 00:00:00");
bug.post();
}
public static void login()
{
String url = "http://almqc:8080/qcbin";
String username = "Administrator";
String password = "********";
String domain = "DEFAULT";
String project = "Banking";
ITDConnection itdc = ClassFactory.createTDConnection();
itdc.initConnectionEx(url);
itdc.connectProjectEx(domain, project, username, password);
System.out.println(itdc.projectConnected());
createDefect(itdc);
}
While running above code in eclipse i encountered following error.
Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153
at com4j.ComThread.execute(ComThread.java:203)
at com4j.Task.execute(Task.java:25)
at com4j.COM4J.createInstance(COM4J.java:97)
at com4j.COM4J.createInstance(COM4J.java:72)
at com.mercury.qualitycenter.otaclient.ClassFactory.createTDConnection(Unknown Source)
at Sample.main(Sample.java:18)
Caused by: com4j.ComException: 80040154 CoCreateInstance failed : Class not registered : .\com4j.cpp:153
at com4j.Native.createInstance(Native Method)
at com4j.COM4J$CreateInstanceTask.call(COM4J.java:117)
at com4j.COM4J$CreateInstanceTask.call(COM4J.java:104)
at com4j.Task.invoke(Task.java:51)
at com4j.ComThread.run0(ComThread.java:153)
at com4j.ComThread.run(ComThread.java:134)
Please provide any walkaround or solution who got successfully executed on 64 bit Based OS.
You'll have to make a 32-bit version of your program that can use the 32-bit version of OTACLIENT.DLL. I'm not aware of a 64-bit version of OTACLIENT.DLL.
The issue is not with 64 bit OS but with 64 bit JRE. If you are using IDE, point your JRE library (build path) to a 32 bit JRE (bin folder) else you can also install 32 bit JRE in 64 bit machines and run in that environment
OTAClient is pure windows dll, even though you are using java you need to register it on windows machine. Better approach to get most out of it is to use it with .net, in such cases you can create windows/web service exposed over http. With this service you can develop c# code to do operations with OTAClient.dll. Using web/rest/wcf service you can communicate with the developed service. Gr8 part of it is it allows you to run over 64-bit architecture. IIS also allows with option "Enable 32-bit application" at application pool level.

How to programmatically connect internet via datacard with AT commands?

I have a datacard ZTE MF190. I want to use AT commands to register in 2G or 3G and access internet via datacard. Found this article about how to make data call:
AT+cgatt=1
AT+CGDCONT=1,”IP”,”epc.tmobile.com” //I used my operator PDP context
AT+CGACT=1,1
But ping from OS terminal shows 100% package loss.
I've tried on Ubuntu 14 and Windows 7.
How can I connect internet with AT commands using datacard on Ubuntu?
UPDATE
I gave bounty to #tripleee's answer because it's more full than first one and answered all my questions. But I'm not satisfied with answers, so I'll answer my own question in a week.
In my answer I'll show how to handle this process with Java. So, please do not move this question to other Stack Exchange websites.
Creating a connection between the card and your provider is not sufficient. You need some mechanism for creating a network interface out of this connection, and set up your network stack to route packets over this interface.
Traditionally, the pppd daemon has been a popular choice for this task. You would create a "chat script" with the commands for establishing a data call (these days, pppd might come packaged with a suitable canned script) and the daemon would handle the entire process of placing the call, authenticating, setting up a network interface over the circuit, and configuring the system to route packets over it, as well as configuring DNS etc to use it for resolver queries, etc.
I tried to sniff USB port but on this case dashboard can not connect because of busy port
It is certainly possible. See this question
Found this article about how to make data call
What that article is about is how to set up the call, not how to make it.
After you made correct setup, connect to internet with this command:
ATD*99***1#
UPDATE1: After a bit of research I believe that article was written only to promote their software and has no practical use. In reality dialing is made with pppd or wvdial
UPDATE2: We discussed ways to solve the problem in a chat room (in Russian). It turned out cnetworkmanager will be the way to go
As far as I know wvdial uses ppp daemon to connect to the internet using modem. wvdial is preinstalled on desktop version of Ubuntu.
wvdial uses a config file located /etc/wvdial.conf. Let's edit this file. Type in your terminal
sudo nano /etc/wvdial.conf
and you will see something like this
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Stupid Mode = yes
ISDN = 0
Modem Type = Analog Modem
New PPPD = yes
Phone = *99#
Modem = /dev/ttyUSB2
Username = ''
Password = ''
Baud = 9600
Dial Timeout = 30
Dial Attempts = 3
Explanation of all keys you can find in wvdial.conf(5) - Linux man page. If you need to change your provider dial number, username, password or any other information about connection and device you can change file content and save it.
There are 3 serial ports for ZTE MF190. Normally it's ttyUSB0, ttyUSB1 and ttyUSB2. And in my case ttyUSB2 is for internet connection. It would not work on other ports. So you need to find the right serial port for your modem.
There is an automatic configurator which edits wvdial.conf file, sets serial port baud rate etc. Since it is not always configure correctly I would not recommend to use it:
sudo wvdialconf /etc/wvdial.conf
It would be better if you configure wvdial manually.
Now, when your device connected and wvdial configured to work with device, you can execute this line from terminal:
wvdial
You will see a lot of lines. But if you see those lines - you have succeeded.
local IP address XX.XX.XX.XX
remote IP address XX.XX.XX.XX
primary DNS address XX.XX.XX.XX
secondary DNS address XX.XX.XX.XX
Now, how we can use it in programming? I'll provide some code to work with it on Java. You can use this code to dial.
public int dialer() {
// status for debug. If status == 4 then you connected successfully
int status;
// create process of wvdial
ProcessBuilder builder = new ProcessBuilder("wvdial");
try {
// start wvdial
final Process process = builder.start();
// wvdial listener thread
final Thread ioThread = new Thread() {
#Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getErrorStream()));
// wvdial output line
String line;
while ((line = reader.readLine()) != null) {
// if "local IP address" line detected set status 1
if (line.contains("local IP address")) {
status = 1;
}
if (line.contains("remote IP address")) {
status = 2;
}
if (line.contains("primary DNS address")) {
status = 3;
}
if (line.contains("secondary DNS address")) {
status = 4;
}
}
reader.close();
} catch (final Exception e) {
}
}
};
// start listener
ioThread.start();
// wait 6 secs and return status. Some kind of timeout
Thread.sleep(6000);
} catch (Exception e) {
}
return status;
}
And here is a disconnector method. All you need is to kill wvdial process and thread will be destroyed:
public boolean disconnect() {
ProcessBuilder builder = new ProcessBuilder("pkill", "wvdial");
try {
builder.start();
return true;
} catch (IOException e) {
return false;
}
}

check accessibility of all nodes in a network in java

I want to check all of nodes accessibility in a network using java. I have read This and This Questions and I have write my method by helping these questions, I have at least two tested Ips in my network which are accessible, one of them is 192.168.1.1 and another is 192.168.1.102 you can see test of 192.168.1.1 in the below picture:
Odk but when I run my code my app says that 192.168.1.1 is not reachable. here is the image, I have pointed at it with a red arrow:
ok , and here is my java code:
private void checkNetworkAccessibility(){
int timeout = 1000;
String subnet = firstSubnet.getText() + "." + secondSubnet.getText() + "." + thirdSubnet.getText() + ".";
DefaultTableModel model = (DefaultTableModel)networkTable.getModel();
for(int i=1;i<=254;i++){
try {
if(InetAddress.getByName(subnet+i).isReachable(timeout)){
model.addRow(new Object[]{subnet + i, subnet + i, "بله", "بله"});
}
else{
model.addRow(new Object[]{subnet + i, "نامشخص", "خیر", "بله"});
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
what is wrong with my code?
The problem is that .isReachable() is not reliable. Its implementation is totally OS dependent!
Let's take Linux as an example; this method uses the echo TCP service (port 7). Do you actually know of a server which has even that running today? I don't.
It cannot use ping; look at this:
$ ls -l $(which ping)
-rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping
Yes, that's right; the sticky bit. The reason for this is that the ping command sends an ICMP echo request packet along the wire, and this requires that you be able to access raw sockets.
Which you can't do unless you have the necessary privileges, and which you can't do in Java! Except if you use native libraries. And you run with the necessary privileges. Which more often than not means you need to be admin. Which you don't want.
And of course, a sysadmin may even decide to block incoming echo request packets on a host, so even ping is not reliable...

accessing GuestAuthentication object for getting list of processes in guest for Vmware Java API

I am using VMwareExsi APIs that is vijava sdk for accessing some of the VMs which are running in the hypervisor.
I am trying to get list of all processes running in one of the Vms.
I have GuestProcessManager instance with me, and I am calling
GuestProcessManager .listProcessesInGuest(GuestAuthentication gauth,pids).
As evident ,gauth is mandatory parameter for the method.But I am unable to get GuestAuthentication object . How can I retrieve it?
I tried following approach:
Folder rootFolder = si.getRootFolder();
ManagedEntity[] mes = new InventoryNavigator(rootFolder)
.searchManagedEntities("VirtualMachine");
NamePasswordAuthentication auth = null;
auth = new NamePasswordAuthentication();
String username = "xxx";
String password = "xxxxxxx";
long[] pids=null;
auth.setUsername(username);
auth.setPassword(password);
auth.setInteractiveSession(true);
GuestProcessInfo[] processInfo=si.getGuestOperationsManager().getProcessManager((VirtualMachine)mes[1]).listProcessesInGuest(auth,pids);
What am I getting is :Exception caused:::VI SDK invoke exception:com.vmware.vim25.GuestOperationsUnavailable.
If I set interactivesession to false , exception message changes to Exception caused:::VI SDK invoke exception:com.vmware.vim25.GuestComponentsOutOfDate . I am using vijava5.5 .jar for development .
System on host & EXSI version : vmnix-x86VMware ESXi 5.5.0 .
I am attaching below the some of the informations I am fetching from my VM, this information shows VM is in running state .
CPU Allocation Shares ::2000
Memory Allocation Shares ::20480
RunTime Max CPU Usage::5799
RunTime Max Memory Usage::2048
Runtime memory overhead::36024320
Average CPU utilization 1.375237150741635E-4
Listing process for VmVirtualMachine:2 # 10.126.77.45
Exception caused:::VI SDK invoke exception:com.vmware.vim25.GuestOperationsUnavailable
Guest OS:Red Hat Enterprise Linux 5 (64-bit)
VM Version:vmx-10
CPU:4 vCPU
Memory:12288 MB
Memory Overhead:373.0514 MB
VMware Tools:guestToolsRunning
IP Addresses:10.126.77.221
State:running
Can you provide some more details
Vcenter version, Esxi Version, VMware tools version etc.
What I suspect is either vmware tools is not running properly or some version mismatch is blocking the authentication.
I have left java years back. But when I wrote the given below code, it is working fine with me. Can you check this code in your setup !
ServiceInstance si = new ServiceInstance(new URL("https://10.22.10.13/sdk"), "Administrator", "Password", true);
Folder rootFolder = si.getRootFolder();
String name = rootFolder.getName();
ManagedEntity[] mes = new InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");
if(mes==null || mes.length ==0)
{
return;
}
VirtualMachine vm = null;
for (ManagedEntity entity : mes) {
if (entity.getName().equals("Ubuntu12")){
vm = (VirtualMachine)entity;
break;
}
}
NamePasswordAuthentication creds = new NamePasswordAuthentication();
creds.username = "reuben";
creds.password = "reuben";
GuestProcessInfo[] processes = si.getGuestOperationsManager().getProcessManager(vm).listProcessesInGuest(creds, null);
for (GuestProcessInfo process: processes){
System.out.println("Process Name: "+process.name);
}

Categories

Resources