I ran into a problem a few days ago when I had to introduce C++ files into a Java project. It started with a need to measure the CPU usage of the Java process and it was decided that the way to go was to use JNI to call out to a native library (a shared library on a Unix machine) written in C. The problem was to find an appropriate place to put the C files in the source repository (incidentally Clearcase) which consists of only Java files.
I thought of a couple of alternatives:
(a) Create a separate directory for putting the C files (specifically, one .h file and one .c file) at the top of the source base like:
/vobs/myproduct/javasrc
/vobs/myproduct/cppsrc
I didn't like this because I have only two C files and it seemed very odd to split the source base at the language level like this. Had substantial portions of the project been written more or less equally in C++ and Java, this could be okay.
(b) Put the C files into the Java package that uses it.
I have the calling Java classes in /vobs/myproduct/com/mycompany/myproduct/util/ and the C files also go in there.
I didn't like this either because I think the C files just don't belong in the Java package.
Has anybody solved a problem like this before? Generally, what's a good strategy to follow when organizing codebase that mixes two or more languages?
Update: I don't have any plan to use any C or C++ in my project, some Jython perhaps, but you never know when my customers need a feature that can be solved only by using C or best solved by using C.
"I didn't like this because I have only two C files and it seemed very odd to split the source base at the language level like this"
Why does it seem odd? Consider this project:
project1\src\java
project1\src\cpp
project1\src\python
Or, if you decide to split things up into modules:
project1\module1\src\java
project1\module1\src\cpp
project1\module2\src\java
project1\module2\src\python
I guess it's a matter of personal taste, but the above structure is fairly common, and I think it works quite well once you get used to it.
The default Maven-generated layout for web apps is src/main/java
, src/test/java
, src/main/resources
, and src/test/resources
. I would assume that it would default to adding src/main/cpp
and src/test/cpp
as well. This seems like a decent enough convention to me.
Keeping them in separate folders is a good idea. It makes it easier to find than searching Java packages for the C files, and it also allows for the possibility of adding more C code in the future without having to move it all around later.
Personally I'd separate the two, possibly even into their own separate projects, but that's when they are both separate things, much like you wouldn't put two different concepts in the same class. It's get much vaguer when they both touch the same conceptual area. Ofcourse there's always issues when it comes to building the code, is putting it in structure b) possible for instance without needing to do all sorts of tricks to get it to compile? Are you planning on using more C in the project, in which case the C files would get spread all over your project if you follow the same pattern ...
Personally in the case of split language solutions, I would keep them in seperate projects or folders.
One way of looking at the problem is to treat the C classes like any other third party API. Interface out the dependancies (i.e. avoid direct calls) in your java code to avoid tight coupling and keep the C source in a seperate project/folder from the java.
Let's use different terminology. There is one product which is not project. The product consist of Java workspace and C/C++ workspace, each loadable from the different IDE. Eventually if you use one and the same IDE there will be only one workspace.
Each workspace consists of several projects. Each project has its own folder structure (src, bin, res, e.t.c). So in case it is only one workspace, then it is better to have at least one Java and one C/C++ project inside, each with different compile/run/debug/output/... settings.
So, I would use:
Product/Workspace(1)/JavaProject1/src
Product/Workspace(1)/JavaProject2/src
Product/Workspace(1 or 2)/CPPproject1/src
Product/Workspace(1 or 2)/CPPproject2/src ...
This way you can use eventually one and the same folder structure for each project, which is more consistent. Basically this is just one more level of abstraction - dividing the product to different related projects.
In this case, the files in question are not just a different language, but also run as a separate program that interacts through a defined interface. This means that the source files can be treated as a separate project, and therefore kept elsewhere.
The case is different in .NET projects which mix C# and ASP.NET (for example) within one codebase. How do people organise their code in such cases?