Preamble
I feel that this question deserves an answer, since there are a few subtleties associated with WB development which may not be very well reflected in the WB documentation and can be confusing at first.
The mechanics of package search / loading in application projects
The standard structure of the WB application project usually contains nested directories, often with the same name. For example, here is the layout of the simplest application project:
Test
Test
Kernel
init.m
Test.m
Test.nb
My main point is that for such projects, the mechanism of locating and loading packages is different from just single-package projects. Namely, when you call Get["Test`"]
or Needs["Test`"]
, then in addition to packages with the name Test.m
,Mathematica also searches for directories with name Test
present inside any of the directories currently on the $Path
variable. And if it finds such a directory, it searches for the init.m
file, which should be located in the Kernel
subdirectory. If it is found, it is loaded.
So, for an application project, it is this init.m
file that controls the way the packages of the project are loaded. If you look at the (autogenerated) init.m
file for the above sample project, it has the following contents:
(* Mathematica Init File *)
Get[ "Test`Test`"]
Note that what is being loaded is referred to as Test`Test`
. However, the resulting context will be just Test`
, which can look puzzling at first. What really happens is that the Test.m
file is in another Test
sub-folder, so for Get
to find it, it is mapped to Test`Test`
rather than just Test`
(the "left" Test`
stands for sub-folder, and the "right" Test`
for the file itself).
Likewise, you can use init.m
file to implement an arbitrarily complex and completely customized way that component packages from you project are loaded. And, the context names used in init.m
do not necessarily have to match the actual context names that end up being associated with those files - this gives another level of flexibility.
Workbench specifics
When you work from within WorkBench, then, when you click on the project's notebook, WorkBench launches the Mathematica kernel with a modified $Path
variable, which now contains the root folder of your project (the outermost Test
folder for the example above). This allows you to just call
Needs["Test`"]
from within the notebook and your project packages are loaded via the init.m
mechanism (note that again, this is not the same as search for an individual package with the name Test.m
, which is probably what you assumed and what people commonly think is happening).
When you click on "Run As Mathematica" or "Debug As Mathematica", then the default behavior is that you project is already loaded, so you can work with your notebook without even loading the project explicitly. You can have more precise control over what happens there by right-clicking on the project root folder, going to Properties -> Mathematica, and modifying the Execution Build Command field there.
Why it didn't work
In any case, this should explain why you were having trouble loading the project. I assume that you were loading the project notebook (or any other notebook) not within the WorkBench. In this case, the $Path
variable does not contain the root folder of your project when Mathematica is launched stand-alone. Therefore, Mathematica has no way to find your project.
For most cases, I would recommend to work from within Workbench, so that this problem does not occur. If you really want to work with stand-alone Mathematica (which sometimes is indeed a better option, but such cases are rare), then you have two choices:
- Copy your project to some of the default locations where Mathematica can find it, such as
$UserBaseDirectory/Applications
(but see the caveat below).
- Add the path to the root folder of your application project to the
$Path
variable prior to loading the project.
The former option is a better one, but to make it work one may need additional steps and changes to the project layout, as discussed below. The latter option is really a quick hack, which might be OK during development but is a dead-end if you plan to deploy the project so that some other people can install it on their machines, since modifying the $Path
variable is really not the way to go.
Application project layouts
When you create an application project, it is in a way a statement that you need to have a more complex project structure than a single package can offer. You may want to do this for a number of reasons, such as the need to accommodate additional resource files, split a project into several packages, or when your project has non-Mathematica components (such as Java or C code etc).
Very often then, the layout of the final project you deploy is different from the layout of your WB project, and this is right, since generally the mapping between your WB project and the final deployed one will be non-trivial. To construct the final layout, usually some build tools are used. I use Apache Ant, which is a good old tool, well-intergated into Eclispe / WB, but you are free to use other build tools such as e.g. Maven.
Why is this relevant to this discussion? Because if you simply copy the WB project into say $UserBaseDirectory/Applications
, Mathematica won't find it. Rather, what should likely be the final layout will look something like this (for the example above):
Test
Kernel
init.m
Test.m
which is (in this simple case) the "inner part" of the WB project, but in more complicated cases it will be a less trivial rearrangement of the original project. What matters here is that we are one Test
folder short here w.r.t. the original project, and this is what will allow Mathematica to find it in $UserBaseDirectory/Applications
, since the number of Test
-s is now right, so to speak (remember that the WB-initiated kernel has the root of your WB project added to the $Path
, while for a stand-alone project, only $UserBaseDirectory/Applications
is on the $Path
, that's why it is different when you work from within WB).
The standard way to do this sort of layout rearrangements is to write an Ant script which would have targets such as "build" and "deploy", the former to create the needed directory structure in some temporary local directory within the project (say "Build"), and the latter to copy the resulting layout to whatever final destination you want it to be (e.g. $UserBaseDirectory/Applications
).
If you follow these steps, then your workflow is as follows:
- Make modifications to your sources
- Run the build script
- Re-launch Mathematica kernel
This allows you to work with your project using the stand-alone Mathematica session, but the price to pay is the longer turnaround between your changes and the notebook / FrontEnd work. I personally usually use both ways, but take some shortcuts and try to work from within Workbench most of the time since the turnaround is much faster. However, for projects you want to deploy / ship to others, you will have to also use the above-described workflow, at least to test the project - as long as your final layout is not exactly the same as your WB project (but probably even if they are the same).
<<"path/yourpackage"
? $\endgroup$