|
|
|
FAQ List
1. Platform Compatibility
1.1 With which versions of Microsoft's .NET does IIOP.NET work?
1.2 Does IIOP.NET work with Microsoft's Windows CE .NET (Compact Framework)?
1.3 Does IIOP.NET support Visual Studio's Intellisense?
1.4 Does IIOP.NET work with Mono?
2. ORB Compatibility
2.1 Can IIOP.NET interoperate with BEA WebLogic 6.1?
2.2 Can IIOP.NET interoperate with BEA WebLogic 8.1?
2.3 Can IIOP.NET interoperate with IBM Websphere 4?
2.4 Can IIOP.NET interoperate with IBM Websphere 5.0 / 5.1?
2.5 Can IIOP.NET interoperate with JBoss 3.2?
2.6 Can IIOP.NET interoperate with JBoss 4?
2.7 Can IIOP.NET interoperate with OmniORB?
2.8 Can IIOP.NET interoperate with MICO ORB?
2.9 Can IIOP.NET interoperate with TAO ORB?
3. Configuration
3.1 Can the IIOP.NET sources be compiled without any configuration?
3.2 Can the IIOP.NET channel be configured with a config-file?
3.3 How do I configure NUnit V2.0 to use the .NET Framework 1.1?
4. Usage
4.1 How do I use the IDLToCLSCompiler?
4.2 How do I configure IIOP.NET to generate debug information?
4.3 How do I handle shared IDL files?
4.4 How do I configure the channel timeout?
5. Accessing CORBA objects from IIOP.NET
5.1 How can I access an object using its stringified IOR?
5.2 How can I get the stringified IOR from a proxy object?
5.3 How can I access an object using its corbaloc:iiop address?
5.4 How do I implement a callback?
5.5 How do I implement a command pattern?
5.6 How do I implement the _is_a test?
5.7 How do I implement the _non_existant test?
5.8 How do I specify the TCKind explixitly?
5.9 How do I force IIOP.NET to use a given IP address for callbacks?
6. Accessing .NET Objects from CORBA with IIOP.NET
6.1 How do I implement the CORBA USER_ID and SYSTEM_ID policies?
6.2 How do I implement the CORBA PERSISTENT policy?
6.3 Do TRANSIENT servants have different IORs?
7. Frequent Errors (Troubleshooting)
7.1 Exception: Invalid PInvoke metadata format
7.2 omg.org.CORBA.NO_IMPLEMENT: CORBA system exception, completed: Completed_MayBe minor: 1
7.3 omg.org.CORBA.INTF_REPOS: CORBA system exception, completed: Completed_MayBe minor: 1414
7.4 omg.org.CORBA.CODESET_INCOMPATIBLE: CORBA system exception, completed: Completed_No minor: 9501
7.5 omg.org.CORBA.OBJECT_NOT_EXIST
7.6 scoped name not resolvable: TypeCode; currentscope: CORBA
7.7 omg.org.CORBA.MARSHAL: CORBA system exception : omg.org.CORBA.MARSHAL, completed: Completed_MayBe minor: 901
7.8 warning CS1595: 'I' is defined in multiple places
7.9 CORBA system exception : omg.org.CORBA.INTERNAL, completed: Completed_MayBe minor: 1960
7.10 IIOP.NET sends the wrong IP address
7.11 JacORB throws a 'org.omg.CORBA.MARSHAL: Cannot handle TypeCode with kind 30 minor code: 0 completed: No'
7.12 BAD_OPERATION exception accessing a Java server
8. About
8.1 Who maintains this project?
8.2 Who did help?
8.3 How can I submit a patch?
1. Platform Compatibility
2. ORB Compatibility
3. Configuration
3.1 Can the IIOP.NET sources be compiled without any configuration?
IIOP.NET itself doesn't need any external file, but to compile the tutorials and
some of integration tests, you must copy the files ir.idl and orb.idl
in the ./IDL directory before compiling the tutorials. You will find
these two files as part of your Java SDK in the %JAVA_HOME%\lib directory.
To compile parts of the project, the makefile requires some
environment variables to be set:
WAS_HOME |
WebSphere 5 application server path
used by Examples\EBJChatRoom\WebSphere_5and the IntegrationTests
|
JBOSS_HOME |
JBoss 3.2.1 application server path
used by Examples\EBJChatRoom\JBoss3.2.1and the IntegrationTests
|
NUNITV2_HOME |
NUnit V2 path
used by IIOPChannel unit tests and for
the IntegrationTests
|
JUNIT_HOME |
JUnit path
used by the IntegrationTests
|
|
3.2 Can the IIOP.NET channel be configured with a config-file?
Yes, it can.
Example:
The following config file
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel type="Ch.Elca.Iiop.IiopChannel,IiopChannel" port="8087"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
is equivalent to the following:
// register the channel
IiopChannel chan = new IiopChannel(8087);
ChannelServices.RegisterChannel(chan);
The config file is processed with:
RemotingConfiguration.Configure(configFile);
|
4. Usage
4.1 How do I use the IDLToCLSCompiler?
The IDLToCLSCompiler creates the .NET proxies for one or more IDL files.
IDLToCLSCompiler [options] target_assembly idl-files...
target_assembly is the name of the target assembly without .dll
idl-files one or more idl files containg OMG IDL definitions
options are
-h help
-o directory output directory (default is `-o .`)
-r assembly assemblies to check for types in, instead of generating them
-c xmlfile specifies custom mappings
-d define defines a preprocessor symbol
-basedir directory directory to change to before doing any processing.
-idir directory directory containing idl files (multiple -idir allowed)
-vtSkel enable creation of value type implementation skeletons
-vtSkelProv The fully qualified name of the codedomprovider to use for value type skeleton generation
-vtSkelTd The targetDirectory for generated valuetype impl skeletons
-vtSkelO Overwrite already present valuetype skeleton implementations
-snk sign key file (used for generating strong named assemblies)
-delaySign delay signing of assembly (snk file contains only a pk)
-asmVersion the version of the generated assembly
-mapAnyToCont maps idl any to the any container omg.org.CORBA.Any; if not specified, any is mapped to object
Examples:
-
IDLToCLSCompiler proxy def.idl
-
generate
proxy.dll from def.idl in the current directory.
IDLToCLSCompiler proxy def1.idl def2.idl
-
generate
proxy.dll from def1.idl and def2.idl in the current directory.
IDLToCLSCompiler -o bin proxy def.idl
-
generate
proxy.dll from def.idl in the directory bin .
IDLToCLSCompiler -o bin -idir c:\IDL -idir d:\IDL proxy def.idl
-
generate
proxy.dll from def.idl in the directory bin ; search for imported idl files in c:\IDL and d:\IDL .
IDLToCLSCompiler -d IIOPNet proxy def.idl
-
generate
proxy.dll from def.idl in the current directory; the symbol "IIOPNet" is defined for the IDL preprocessor
Notes:
The compiler will warn you that you must provide the implementation for the classes implementing the CORBA valuetypes. The article Accessing an EJB from .NET Using IIOP.NET: an Example contains a detailed explanation and example (see step 4). You can generate a skeleton (to be completed) of those classes with the option -vtSkel .
|
4.2 How do I configure IIOP.NET to generate debug information?
Availability: November 6th 2003 (CVS); release 1.5.1
The IIOP.NET channel must be recompiled with /debug+ /d:DEBUG /d:TRACE to enable the debugging code; using nmake:
nmake rebuild-base-debug
This will delete the channel's binaries and recompile them with debug enabled.
You can now recompile the example or code that need inspection and execute it. After execution, you will find in the same directory a file named IIOPNET_DebugOutput_timestamp containing additional information.
After debugging remember to recompile the channel without debugging, as this can generate fairly big trace files whenever used:
nmake rebuild-base
|
4.3 How do I handle shared IDL files?
Sometimes, some remote object definitions are factored into a shared IDL file, and used in multiple other IDL files. Generating the .NET proxies for each IDL file causes the definitions in the shared IDL to be generated twice, and .NET compilers complain with warning "X is defined in multiple places".
Let assume the following configuration:
common.idl
//common definitions
a.idl
#include "common.idl"
....
b.idl
#include "common.idl"
...
The first approach is to compile all the idls into a single dll file; this assumes that the definitions in common.idl are protected with ifdefs to avoid their redefinition due to multiple imports:
IDLToCLSCompiler defs common.idl a.idl b.idl
If you need to have separate dlls for each idl file, common.idl must be compiled separatedly to avoid duplicating its definitions. This is done with:
IDLToCLSCompiler common common.idl
IDLToCLSCompiler -r common.dll a a.idl
IDLToCLSCompiler -r common.dll b b.idl
The -r option forces the compiler to check into the given assembly whether some definitions (in this case common.idl) are already available, in which case no further code is generated for them.
|
4.4 How do I configure the channel timeout?
Before version 1.7.0 RC1 timeouts could not be configured.
The channel timeout is configured during the channel registration. By default, the timeout is set to infinity (no timeout).
Property | Introduced in | Type | Description |
IiopClientChannel.CLIENT_RECEIVE_TIMEOUT_KEY | 1.7.0 RC1 | int | reception timeout in milliseconds |
IiopClientChannel.CLIENT_SEND_TIMEOUT_KEY | 1.7.0 RC1 | int | sending timeout in milliseconds |
IiopClientChannel.CLIENT_REQUEST_TIMEOUT_KEY | 1.8 | int | request timeout in milliseconds: abort request if no answer arrives before the timeout |
IiopClientChannel.ALLOW_REQUEST_MULTIPLEX_KEY | 1.8 | bool | allow sending new requests on a connection while previous requests are still pending (default: true) |
IiopClientChannel.MAX_NUMBER_OF_MULTIPLEXED_REQUESTS_KEY | 1.8 | int | maximal number of pending requests on a connection; requires ALLOW_REQUEST_MULTIPLE_KEY=true (default: 1000) |
IiopClientChannel.CLIENT_CONNECTION_LIMIT_KEY | 1.8 | int | maximal number of open connections to one target (default: 5) |
IiopClientChannel.SERVERTHREADS_MAX_PER_CONNECTION_KEY | 1.8 | int | maximal number of incoming pending requests per connection (default: 25) |
The following code installs an IIOP Channel with receive and send timeouts.
IDictionary props = new Hashtable();
props[IiopClientChannel.CLIENT_RECEIVE_TIMEOUT_KEY] = 1000; // timeout 1000ms
props[IiopClientChannel.CLIENT_SEND_TIMEOUT_KEY] = 1000; // timeout 1000ms
// register the channel
IiopClientChannel channel = new IiopClientChannel(props);
ChannelServices.RegisterChannel(channel);
|
5. Accessing CORBA objects from IIOP.NET
5.1 How can I access an object using its stringified IOR?
The following Code reads an stringified IOR from the file iorfile and creates a proxy for
the remote object represented by the IOR:
StreamReader stream = new StreamReader(iorfile);
String ior = stream.ReadLine();
MyRemoteObjectIF remoteObject =
(MyRemoteObjectIF)RemotingServices.Connect(typeof(MyRemoteObjectIF), ior);
|
5.2 How can I get the stringified IOR from a proxy object?
The following method (from Ch.Elca.Iiop in IIOPChannel.dll) returns the stringified IOR of an object, given its local proxy:
OrbServices orb = OrbServices.GetSingleton();
String ior = orb.object_to_string(proxy);
Since 12 August 2004, this code works also for local objects, but those must first be registered with RemotingServices.Marshall .
For versions before 13 April 2004 (v1.6.0 and earlier), use the following (otherwise deprecated) code:
String ior = ProxyHelper.GetIorForProxy(proxy);
|
5.3 How can I access an object using its corbaloc:iiop address?
The following code creates a proxy for the remote object represented by the given corbaloc:
string loc = "corbaloc::localhost:3528/myobject";
MyRemoteObjectIF remoteObject =
(MyRemoteObjectIF)RemotingServices.Connect(typeof(MyRemoteObjectIF), loc);
Note: This feature is only available in IIOP.NET 1.4.0 and above.
|
5.4 How do I implement a callback?
IIOP.NET contains two examples using callbacks:
Examples\Callback\ChatroomInterDN
- shows using a callback in a scenario with an IIOP.NET client and an IIOP.NET server
Examples\EJBChatRoom
- contains a similar example with an IIOP.NET client and various J2EE application servers; this example is explained in detail in the Code Project's article Accessing an EJB from .NET Using IIOP.NET: an Example
For each callback, ensure that the following points are fullfilled:
- The callback implementation class must inherhit from MarshalByRefObject
- The callback implementation class must implement the callback interface
- The callback implementation class must have the SupportedInterfaceAttribute:
[SupportedInterfac(typeof(CallbackInterface)]
public class CallbackImpl : CallbackInterface {
// ...
}
- Create an IiopChannel with a callback port to allow the client to receive the server's messages (using only an IIOPClientChannel or an IIOPChannel without port won't work):
int callbackPort = 0; // automatic assignement
IiopChannel chan = new IiopChannel(callbackPort);
ChannelServices.RegisterChannel(chan);
|
5.5 How do I implement a command pattern?
In the command pattern, you pack the command to execute in a
parametrized data-structure (usually a CORBA value-type) and pass it to the
server, which provides one method that accepts and executes all command types.
You can find an example in Examples/EJBCommandPattern/
A few remarks to the server implementation:
- Define the abstract
Command class as Serializable
- All commands classes inherit from Command
- The EJB has method
execute with takes at least one parameter of type Command
(thus acceps all types that are compatible with Command)
- To provide a nice object-oriented implementation, every command
has a method execute to perform the command; the EJB only forward the call to this
method (no huge switch-statement needed). We hide this method to the client by creating
the IDL of the base command class with the option
-noValueMethods (note that all other
command classes should be compiled as usual, using -noValueMethods would hide all their
getter and setter methods making them much more difficult to implement).
A few remarks to the client implementation
|
5.6 How do I implement the _is_a test?
_is_a is realized as
OrbServices orb = OrbServices.GetSingleton();
bool isA = orb.is_a(proxy, typeof(QueriedInterface));
For versions before 13 April 2004 (v1.6.0 and earlier), OrbServices is not available! You shall use the following (otherwise deprecated) pattern:
bool isA = ((omg.org.CORBA.IObject)proxy)._is_a(
Ch.Elca.Iiop.Idl.Repository.GetRepositoryID(typeof(InterfaceType)));
|
5.8 How do I specify the TCKind explixitly?
It is possible to force the marshaller to use a different type (e.g. if you need unsigned integers). Here's an example; the remote method has the following signature:
// idl method
CORBA::ULong ExtractFromULongAny(const CORBA::Any& arg);
You can pass an unsigned long to the method using the following code:
// C# client code
OrbServices orb = OrbServices.GetSingleton();
int arg2 = 89;
omg.org.CORBA.TypeCode ulongTC = orb.create_ulong_tc();
Any any = new Any(arg2, ulongTC);
int result2 = m_testService.ExtractFromULongAny(any);
|
5.9 How do I force IIOP.NET to use a given IP address for callbacks?
When your machine hangs on multiple networks, or when the communication goes through a NAT, you may need to specify the IP address sent to the CORBA peer to ensure that the peer can find the local machine.
The following code snippet specifies "192.9.200.180" as the local IP address sent to the peer:
IDictionary props = new Hashtable();
props[IiopServerChannel.PORT_KEY] = 0;
props[IiopServerChannel.MACHINE_NAME_KEY] = "192.9.200.180";
IIOPChannel chan = new IIOPChannel(props);
You can also use props[IiopServerChannel.BIND_TO_KEY] to additionally restrict the channel to listening to a particular IP address only instead of listening to any.
|
6. Accessing .NET Objects from CORBA with IIOP.NET
6.1 How do I implement the CORBA USER_ID and SYSTEM_ID policies?
To implement the USER_ID policy (i.e. always publishing an object under the same name), register the object with RemotingServices.Marshal(obj, uri) . IIOP.NET generates a key by transforming all ASCII characters to their corresponding byte value; as an exception, "\u" is escaped to "\\u"; other unicode charaters are each transformed to their corresponding "\uhhhh" representation, whereas hhhh is the hex value of the character.
Example 1: RemotingServices.Marshal(obj, "test") publishes an object as corbaloc::localhost:8087/test (assuming that the channel is listening to port 8087).
Example 2: RemotingServices.Marshal(obj, "uriâé") is published as corbaloc::localhost:8087/uri\u0083\u0082 .
By default, .NET uses the SYSTEM_ID policy: it assigns to the object some random URI with format "[app-domain-id (GUID)]/[random bytes]_[seq-nr].rem". This is also explicitely achieved with the call RemotingServices.Marshal(obj) .
|
6.2 How do I implement the CORBA PERSISTENT policy?
The PERSISTENT policy assumes the USER_ID policy (the object must be accessible through the same URI).
The persistency must be handled by the servant implementation, which should store the state whenever it changes, and restore it when the servant is created.
|
6.3 Do TRANSIENT servants have different IORs?
TRANSIENT servants receive different IORs as long as you implement them using the SYSTEM_ID policy, i.e. you register them with
RemotingServices.Marshal(servant); // register, let the system assign a random name
or you do not register them at all, when returning them to the client peer, in which case .NET registers them for you with the above call.
|
7. Frequent Errors (Troubleshooting)
7.1 Exception: Invalid PInvoke metadata format
This is usually caused by the some backward incompatibility between the .NET framework 1.0 and 1.1: the error occurs, when you run an application built for .NET framework 1.0 on the .NET framework 1.1.
A detailed description of the problem and possible solutions can be found here:
|
7.2 omg.org.CORBA.NO_IMPLEMENT: CORBA system exception, completed: Completed_MayBe minor: 1
The marshaller on the .NET-side cannot find the class implementing the valuetype.
Check that:
- you did implement a class XYZImpl, where XYZ is the type name of the valuetype
- XYZImpl inherits from the abstract class XYZ (this class is generated by the IDLToCLSgenerator)
- XYZImpl is in the same namespace as XYZ
- XYZImpl is serializable
- XYZImpl has a parameterless public constructor
- XYZImpl is not abstract
- XYZImpl implements all the inherited abstract methods and properties
|
7.5 omg.org.CORBA.OBJECT_NOT_EXIST
This exception is thrown when an inexistent object is requested on a remote machine. The exception it thrown by the remote name resolver, thus the connection is fine.
Please check the object name used. The problem can also happen when accessing a CORBA service (they are also implemented as remote objects), like the naming service.
|
7.6 scoped name not resolvable: TypeCode; currentscope: CORBA
This error is issued when using the java orb.idl instead of the IIOP.NET orb.idl.
Since IIOP.NET 1.6.1, you don't need to copy any orb.idl into your idl
directory, because the compiler does automatically use its own (found in directory IDLToCLSCompiler\IDL\).
|
7.12 BAD_OPERATION exception accessing a Java server
The client is requesting an unknown operation from the server. This often happens when the code and the stubs get out of sync (i.e. the code changes but the stubs are not recreated).
Try to refresh the stubs with rmic -iiop .
|
8. About
8.2 Who did help?
First, we would like to thank Prof. Dr. J. Gutknecht at ETH (Programming Languages and Runtime Systems Research Group) and Elca Informatique who made this project possible.
Like every opensource project, many persons have helped improving IIOP.NET with important remarks, feedback, patches, and other contributions. We would like to address you our gratitude publicly.
IIOP.NET Hall of Fame (in alphabetic order):
- Jacob Alvarez
- Atif Aziz
- David Bellette
- Stephen Bogner
- Blazej Budzynski
- Stefano Delli Ponti
- Erik Doernenburg
- Clemens Fischer
- Alexej Gapotchenko
- Steven Hartland
- Ramon Guiu i Hernandez
- Tina Hofmann
- Dennis Homann
- Aitor Illarramendi
- Thomas Köhler
- Alexander Kornienko
- Marc R. Lehmann
- Glen Mah
- Eduardo Macarron Miegemolle
- Urs C. Muff
- Andre Natal
- SangHyun Park
- Bill Petheram
- Florian Pflug
- Andreas Rullmann
- Justus Schach
- Dirk O. Siebnich
- Angel Silva
- Arne Sostack
- Andrew S. Townley
- David Tzur
- Christopher Vijith
- Michael Watkin
|
|
|
About this project
This project is maintained by Elca Informatique SA and
was developed in collaboration with
the Programming Languages and Runtime Systems Research Group of the ETH-Zurich
as part of Dominic Ullmann's diploma thesis.
IIOP.NET Use Cases
Read the IIOP.NET success stories.
News
|
|