I'm using the JACOB (Java COM Bridge) library to call registered COM Objects from my Windows OS.
It took me a while until I figured out how JACOB works and to set up everything. So my current problem is that:
ActiveXComponent comp = new ActiveXComponent("iTunes.Application");
for example works, my iTunes starts properly etc.
If I want to call a self generated and registered COM Object written in C# JACOB responds the following error:
Exception in thread "main" com.jacob.com.ComFailException: Can't co-create object
That my iTunes started was an indicator for me that everything is set up right, I'm not sure why JACOB can't call my own .dll
Currently I'm using the Visual Studio 2015 on build register for COM interop function which worked pretty good in the past for me. The COM object looks as following:
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
public interface ComClass1Interface
{
}
[Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ComClass1Events
{
}
[ComVisible(true)]
[Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(ComClass1Events))]
[ProgId("test.Application")]
public class ComClass1 : ComClass1Interface
{
}
Is anything wrong with my C# dll or does JACOB require a certain type of structure in this dll?
Unfortunately I could not find any COM examples for JACOB.
Thanks in advance.
EDIT:
If i change my first line to:
ActiveXComponent comp = new ActiveXComponent("CLSID:{C9888A8E-8D23-4185-9D7D-A1E0B812803D}");
I'm getting following Exception:
Exception in thread "main" com.jacob.com.ComFailException: Can't find moniker
My .dll should be registered though.
I would first write a VBS (VB script) program to test your DLL and make sure it runs.
set obj = CreateObject("test.application")
MsgBox TypeName(obj)
Make sure it succeeds. If it fails, then (assuming a 64-bit OS), try running it with c:\windows\syswow64\wscript.exe path\to\your\script.vbs.
Check to see whether your Java process is a 64-bit or 32-bit process. Your C# DLL has to be registered with the same bit-ness as your Java process for it to succeed.
Thanks for the hint, I was able to find a solution:
Visual Studio apparently registered my COM-Object as 32 bit.
I'm not sure if this is a default setting(?).
So two simple steps to solve the problem:
open your windows cmd as admin.
Run the following Command:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /verbose /nologo /codebase "path to your dll"
The command will register the .dll in 64 bit and not 32.
This solved the problem for me and I could use it via JACOB.
Related
Our application is a RoR app, and currently uses JRuby version 1.7.22, and JRE 8_65. Our app is an on-prem solution, so we use JRuby to host our application on JVM at the target, Windows Server 2012 R2 system. We compile our ruby code, using
jruby -S jrubyc
This takes the .rb file and compiles it to a .class file. In the original .rb, it loads in the class file, like so.
load __FILE__.sub(/\.rb$/, ".class")
This all works with JRuby 1.7.22
Now, we want to update JRuby to 9.0.5.0, but are experiencing some problems when it comes to deploying our application. Basically, that line of code above inside of the .rb file is not working anymore, and we get the error when trying to run a rake db:setup
rake aborted!
LoadError: C:/appname/app/models/app_attribute.class is not compiled Ruby; use java_import to load normal classes
C:/appname/app/models/app_attribute.rb:1:in `<top>'
C:/appname/db/seeds.rb:10:in `<top>'
C:/appname/db/seeds.rb:9:in `block in (root)'
Tasks: TOP => db:setup => db:seed
(See full trace by running task with --trace)
Great. So I replace load with java_import
rake aborted!
ArgumentError: not a valid Java identifier: C:/appname/app/models/app_attribute.class
uri:classloader:/jruby/java/core_ext/object.rb:43:in `block in java_import'
uri:classloader:/jruby/java/core_ext/object.rb:34:in `java_import'
C:/appname/app/models/app_attribute.rb:1:in `<top>'
C:/appname/db/seeds.rb:10:in `<top>'
C:/appname/db/seeds.rb:9:in `block in (root)'
Tasks: TOP => db:setup => db:seed
(See full trace by running task with --trace)
Still not working, no matter what I try. I looked at this post: https://github.com/jruby/jruby/issues/3018
I tried to pass the parameter
jruby -Xaot.loadClasses=true
But I get a warning saying that aot.LoadClasses is not recognized. EVEN THOUGH I see it in the properties when I type
jruby -Xproperties
I have done A LOT of research on this, and have probably have looked at everything on the internet regarding this. Any input will be greatly appreciated. Is there something I missing? I am not fully adept in Java.
Thank you.
might be the same issue as https://github.com/jruby/jruby/issues/3651
which means you'll need to wait for 9.1 or use a snapshot http://ci.jruby.org/
since, the error is slightly different you should look into reproducing with snapshot and if it fails (might be Windows related) a step-by-step reproduction might speed-up getting the issue resolved.
jruby -Xaot.loadClasses=true
this is not needed with Warbler
But I get a warning saying that aot.LoadClasses is not recognized. EVEN THOUGH I see it in the properties when I type
hmm, could you reproduce this with an empty script and no JRUBY_OPTS ?
I have done A LOT of research on this, and have probably have looked at everything on the internet regarding this. Any input will be greatly appreciated.
you might want to try looking into the issue next time :) or considering getting some support
Is there something I missing? I am not fully adept in Java.
you shouldn't be missing anything - its not a Java issue ...
I am trying to use autoit with java, and have installed AHK and the jacob bridge to autoitx4java.AutoItx. I have the jacob dll (jacob-1.18-86x.dll) stored in windows/syswow64 . When I try to compile the program (imports are import java.text.SimpleDateFormat; import java.util.Date; import autoitx4java.AutoItX;), I get an error
Exception in thread "main" com.jacob.com.ComFailException: Can't get object clsid from progid
at com.jacob.com.Dispatch.createInstanceNative(Native Method)
at com.jacob.com.Dispatch.<init>(Dispatch.java:99)
at com.jacob.activeX.ActiveXComponent.<init>(ActiveXComponent.java:58)
at autoitx4java.AutoItX.<init>(AutoItX.java:181)
at MainTest.login(MainTest.java:126)
at MainTest.setadmin(MainTest.java:181)
at MainTest.runbasic(MainTest.java:21)
at MainTest.main(MainTest.java:15)
After searching, I thought it might be that the dll wasn't registered, such as at How to create an object using JACOB , but that didn't work. After typing the registering command from there, I get a "RegAsm : error RA0000 : Failed to load 'c:\windows\syswow64\jacob-1.18-x86.dll' because it is not a vaild .NET assembly. Also tried "regsvr32 jacob-1.18-x86.dll" from another way to register outside of the answer above, but that got me a "The module "jacob-1.18-x86.dll" was loaded but the entry-point DllRegisterServer was not found. Make sure that "jacob-1.18-x86.dll" is a valid DLL or OCX file and try again. Any ideas?
Edit: Someone suggested this was for AutoIt and not autohotkey. This is corrected in the question and the tags. Thanks,
By just registering only AutoITX3 DLL, issue has been resolved.
For Win32: AutoItX3.dll and Win64: AutoItX3_x64.dll
Register using command: regsvr32 AbsolutePathOfRequiredDLLFile
I have an eclipse project with two classes. The class "SomeClass1" has a native method:
SomeClass1
public class SomeClass1 {
static {
System.loadLibrary("libname"); // Load the native library.
}
public native void some_method(); // implemented in the library
// .... other non methods ....
}
The other class "SomeClass2" uses the native method of "SomeClass1". Like:
SomeClass2
public class SomeClass2{
public static void main(String[] args) {
SomeClass1 s = new SomeClass1();
s.some_method();
}
// ....other methods....
}
However when it calls that method it throws an error like this:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libname in java.library.path
....
at java.lang.System.loadLibrary(Unknown Source)
at x.x.x.SomeClass1.<clinit>(SomeClass1.java:128)
at SomeClass2.main(SomeClass2.java:10)
I think the error has something to do with java not knowing where to look for the native library.
Question1
When I use: -Djava.library.path="C:\Users.....\libfolder\" as run argument in eclipse and print the value of: System.getProperty("java.library.path"); I see alot of directories printed but not the directory that I specified in the argument. What am I doing wrong?
Question2
When I do: System.loadLibrary("name"); do I need to call the library "name.so" or "libname.so"?
Question3
If the library would be found but was a 64 bit library while the platform it is loaded on is 32 bit, would it also give a unsatisfiedLinkError or would a different error be given?
Question4
Can I specify the path to the library relative to the projects folder or relative to the file in which the library is loaded?
Hope you are able to answer (some of) my questions.
Grtz Stefan
Question 1:
You should not add this as a run argument, but as a VM argument. It's not an argument for your program, but for the JVM.
Question 2:
(Also #IanRoberts ) : The System.loadLibrary(name) call will automatically derive the name of the actual library from the given name. That means that it will append ".dll" on windows, and use "lib" + name + ".so" on linux. Otherwise, loading a native lib would not be possible in a platform-independent way!
Question 3:
In general, the UnsatsfiedLinkError is distressingly common. It's in fact true to say: The UnsatisfiedLinkError does not tell you more than "Something is wrong". You can only hope for the actual error message to be more descriptive, and this would (fortunately) be the case if you had a 32/64bit mismatch - at least on windows:
Trying to load a 32bit lib on a 64bit system will cause the message: "Can't load IA 32-bit .dll on a AMD 64-bit platform"
Trying to load a 64bit lib on a 32bit system will cause the message: "... is not a valid Win32 application"
(I'm not sure about the message for other operating systems, though, but your message indicates that the library is just not found, and not that there's a problem with the library itself)
(Question 4: I'm rather sure that this is possible, but not absolutely sure (and can't try it out) at the moment. In general, the library must be in a path that is visible via the PATH environment variable, or via the java.library.path. In doubt, it should always work then the native libs are in the same directory as where you are starting your program from)
I am using Jacob a Java-COM bridge and I have placed the required dll to -C:\WINDOWS\system32\jacob-1.14.3-x86.dll. I have also added the required jar file to -
C:\Program Files\Java\jdk1.6.0_18\jre\lib\ext\jacob-1.14.3.jar.
Until yesterday I was able to use it, today I uninstalled some unrequired .Net softwares on my machine and suddenly it stopped working and throws following error -
com.jacob.com.ComFailException: Can't co-create object
at com.jacob.com.Dispatch.createInstanceNative(Native Method)
at com.jacob.com.Dispatch.<init>(Dispatch.java:101)
at com.jacob.activeX.ActiveXComponent.<init>(ActiveXComponent.java:58)
My machine belongs to "x86 Family 15 Model 4 Stepping 3". I have tried to de-register/register the dll using regsvr32.exe but to no luck. I have no idea how to bring it to work again..other wise I will have to format my machine..geeks pls hlp me out !
I wonder if anyone faced similar problem by any chance..
Anyways I had no other option than to restore my machine to last working date.
I guess some JAVA-COM class entries would have been accidently deleted from the registry.
Had no idea which was it exactly..
Finally "System Restore" was my solution :)
I have followed the instructions to setup rxtx on windows from http://www.jcontrol.org/download/readme_rxtx_en.html.
What I did exactly was copy rxtxSerial.dll to "C:\Program Files\Java\jdk1.6.0_07\jre\bin"
and copied RXTXcomm.jar to "C:\Program Files\Java\jdk1.6.0_07\jre\lib\ext"
(my JAVA_HOME variable is set to C:\Program Files\Java\jdk1.6.0_07\jre)
I also added RXTXcomm.jar to my eclipse project.
But when I run it, it still says "NoSuchPortException"
Devel Library
=========================================
Native lib Version = RXTX-2.0-7pre1
Java lib Version = RXTX-2.0-7pre1
java.lang.ClassCastException: gnu.io.RXTXCommDriver cannot be cast to gnu.io.CommDriver thrown while loading gnu.io.RXTXCommDriver
gnu.io.NoSuchPortException
at gnu.io.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:218)
at TwoWaySerialComm.connect(TwoWaySerialComm.java:20)
at TwoWaySerialComm.main(TwoWaySerialComm.java:107)
In my java file, I tell it:
try
{
(new TwoWaySerialComm()).connect("COM4");
}
and I've also tried the Java Comm API. Both cannot recognize my serial port but I am sure I followed the instruction correctly. There files are there.
Does anybody have any idea what it could be?
Try putting rxtxSerial.dll in
C:\Program Files\Java\jdk1.6.0_07\jre\lib\bin
^^^
you can use
CommPortIdentifier.getPortIdentifiers()
to identify all possible ports your system finds.
I am not too familiar with RXTX, but is this normal?
java.lang.ClassCastException: gnu.io.RXTXCommDriver cannot be cast to gnu.io.CommDriver thrown while loading gnu.io.RXTXCommDriver
Otherwise maybe the problem is not with the port itself after all, but something with the classes themselves?
Just a guess.
You can also try an alternative solution that was specifically implemented for Windows. There should be plenty available, one of them you can get from http://www.caerustech.com/JCommWin32.php
Shultz
It may be that your system does not have a COM4 defined or it's not accessible. It's hard to guess what may be wrong, because you haven't posted you port init code - what you posted looks like wrapper code.
Here is my working init code using the javax.comm API (but using SerialPort from serialio.com):
// name comes from config and is "COM1", "COM2", ...
SerialPort port=(SerialPort)CommPortIdentifier.getPortIdentifier(name).open("YourPortOwnerIdHere",5000); // owner and ms timeout
port.setSerialPortParams(bau,dtb,stb,par);
port.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN|SerialPort.FLOWCONTROL_RTSCTS_OUT);
port.enableReceiveTimeout(1000);
Hopefully this points you in the right direction.
I agree that you're problem looks like a ClassCastException and not the other.
For windows, I'm using "Windows Java Serial Com Port Driver" at http://www.engidea.com/blog/informatica/winjcom/winjcom.html and it is much easier for me to set up.
In either case, you want the DLL in the BIN directory, not LIB\BIN as was suggested. At least that's what's working for me. I'm using NetBeans and I've also found it helpful to put the jar and dll into various bin and lib\ext folders in the JDK.
Note that if you have multiple versions of the JRE on your machine, you might not be using the one that you think you are using. Also, as a practical matter I've found it more helpful to just copy both the jar and dll into the various bin and lib\ext folders. Makes it just a paste, paste, paste operation.
For windows, I recommend "Windows Java Serial Com Port Driver" because it solved my problems with USB serial ports. I had fits with RXTX because it would crash when the USB was unplugged. winjcom solved that problem and others as well. It has very helpful error exceptions.
Also, make sure your serial drivers are up-to-date. Downloading an update fixed my other bug.
-Stosh
I also had a problem when closing the serialPort within the serialEvent function.
Maybe it's a deadlock problem, where the close method waits forever for serialEvent's lock to be released.
Starting a new thread to close the port worked for me.
For your question, my code is the following:
if (idPuerto == null)
{
formulario = form;
boolean encontrado = false;
listaPuertos = CommPortIdentifier.getPortIdentifiers();
while( listaPuertos.hasMoreElements() && encontrado == false )
{
idPuerto = (CommPortIdentifier)listaPuertos.nextElement();
//System.out.println(idPuerto.getName());
if( idPuerto.getPortType() == CommPortIdentifier.PORT_SERIAL )
{
if( idPuerto.getName().equals(RFIDBascApp.ComBasc) )
{
encontrado = true;
logger.AddInfoUser("Puerto serie encontrado");
}
}
}
You had NoSuchPortException, so first of all iterate on all available ports!
import gnu.io.CommPortIdentifier;
import java.util.Enumeration;
public class ListAvailablePorts {
public void list() {
Enumeration ports = CommPortIdentifier.getPortIdentifiers();
while(ports.hasMoreElements()){
CommPortIdentifier port = (CommPortIdentifier) ports.nextElement();
System.out.println(port.getName());
}
}
public static void main(String[] args) {
new ListAvailablePorts().list();
}
}
#Pinheiro you might want to take a look at this