When a P2-managed application starts, a set of configuration files are read to determine which plug-ins and features to enable. Even though files may be present in features/
and plugins/
, they won't be installed into an Eclipse application unless the P2 configuration details refer to them. To understand how this works, it is informative to see how a modern Eclipse application launches and what configuration files are used.
The launcher is the eclipse
executable (or Eclipse.app
on Mac OS X). When run, the corresponding eclipse.ini configuration file is read. If Eclipse has been rebranded/renamed, then the executable will be called something else (notEclipse
), and it will read the corresponding file (notEclipse.ini
).
The launcher performs a few tasks; it shows a splash screen, creates a JVM with the arguments specified in the configuration file, and then hands over the execution to the Equinox launcher. It is also used to define an open action so that if the Eclipse application is set as the default handler for certain file types, double-clicking on it will re-invoke the launcher, which then transfers the URL to the running Eclipse instance.
The splash screen is shown with -showSplash
(or hidden with -noSplash
), and it is defined by reference to a plug-in ID that hosts the splash.bmp
file (it must be called by that name, and it must be a bmp
file). This is handled by the Eclipse launcher initially, and once Equinox is started, the splash screen is handed over to the SWT runtime library, which can then annotate it with text and progress bars.
The launcher creates an instance of the JVM based on the arguments specified. If a JVM is not given, it tries to find one using various heuristics (it checks whether java
is on the path, whether JAVA_HOME
has been set, and so on). However, it is possible to specify a JVM on the command line with the -vm /path/to/bin/java
or -vm /path/to/bin/
argument.
The -vmargs
option is used to pass through options to the JVM itself. This can be used to set the max heap size (-Xmx
) or configure the PermGen space (-XX:MaxPermSize
).
The launcher provides an additional option, --launcher.XXMaxPermSize
, which performs some heuristics to see whether the -XX:MaxPermSize
is understood by the JVM being used, and adding the argument if it is understood.
Any arguments specified after the -vmargs
option are passed through to the JVM, and not to the Equinox runtime. So, given eclipse a b c -vmargs d e f
, the a b c
options will be handled by the launcher and passed through to Equinox, while the d e f
options are passed to the JVM. When adding command-line options to the end of either the configuration file or the command line, ensure that they are added in the right place.
When specifying options on the command line with -vmargs
, it will override any elements in the eclipse.ini
file, unless the --launcher.appendVmargs
argument is given. Using --launcher.appendVmargs
is recommended for all Eclipse applications, and it is added by default to standard Eclipse packages.
Any system properties can also be specified on the command line, after -vmargs
, using the standard -D
options. There is a list of such options described in the online Eclipse help under Eclipse runtime options, but particular ones of note are as follows:
-Dosgi.requiredJavaVersion=1.6
: This is the minimum Java version required in order to launch the platform-Dorg.eclipse.swt.internal.carbon.smallFonts
: Use smaller fonts when running on Mac OS X-Xdock:icon=/path/to/Eclipse.icns
: Use the given icon as the dock icon on Mac OS X-XstartOnFirstThread
: This allows SWT applications to run on Mac OS XMany other arguments, such as -clean
and -data
, can also be specified as system properties such as osgi.clean
and osgi.instance.area
.
Once the launcher hands control over to Equinox (specified with the -startup
and --launcher.library
arguments), the process moves into Java code. It is also possible to run Equinox with java -jar plugins/org.eclipse.equinox.launcher_*.jar
. Arguments are still passed through to the underlying application.
Equinox reads the configuration/config.ini
file, which defines a set of system properties for the application. In particular, the default workspace is defined in a property osgi.instance.area
, and allows substitution of property values such as the user's home directory with @user.home
.
The config.ini
file contains the initial bundle set to bring up the framework, which includes the simpleconfigurator
bundle. This reads the contents of the org.eclipse.equinox.simpleconfigurator/bundles.info
file, which is the set of bundles to be loaded into the framework. This list represents the last known state of the framework, but its history is managed through P2 profiles.
The config.ini
file looks like the following:
eclipse.p2.profile=epp.package.standard [email protected]/../p2 eclipse.product=org.eclipse.platform.ide osgi.bundles=reference:file:org.eclipse.equinox.simple...
From a P2 perspective, there are two things of interest here. The first is the P2 profile name (epp.package.standard
) and the second is the P2 data area (usually p2
at the top level of the Eclipse install). The p2
data area is used to store all P2 data, which includes the following:
org.eclipse.equinox.p2.core/cache/
: This is used to store cached copies of the root feature installsorg.eclipse.equinox.p2.engine/profileRegistry/
: This is the location of the P2 profilesorg.eclipse.equinox.p2.repository/cache/
: This is used to store a copy of the artifacts.xml
and content.xml
downloads from remote update sitesP2 profiles are sets of enabled features and plug-ins that are available in a running Eclipse framework. P2 allows for different profiles to be concurrently installed in an Eclipse install, and switch between them at launch time using a command-line argument. It is possible to have, for example, an Eclipse application configured for C development and an Eclipse application configured for Java development in the same install, and then at launch time switch between them using -Declipse.p2.profile=epp.package.cpp
or -Declipse.p2.profile=epp.package.standard
Each profile is given a separate directory underneath profileRegistry
; for example, …/profileRegistry/epp.package.standard.profile/
is used for the EPP standard profile. Underneath the profile directory is a set of compressed timestamped files that use the time in milliseconds, which represent the state of the Eclipse platform's installed features and plug-ins at that point in time. When a new installation occurs (such as adding new features), a new timestamped profile is generated. When Eclipse starts, it looks for the largest numerical value that ends in .profile.gz
(or .profile
) and uses that as the boot profile.
The profile itself contains an XML file that contains properties
, units
, and iuProperties
. It looks like the following:
<profile id="epp.package.standard" timestamp="1395612330274"> <properties size="7"> <property name="org.eclipse.update.install.features" value="true"/> … </properties> <units size="1564"> <unit id="org.eclipse.jdt.feature.group" version="3.9.2.v20140221-1700" singleton="false"> <properties size="12"> <property name="org.eclipse.equinox.p2.name" value="%featureName"/> … </properties> <provides size="3"> <provided namespace="org.eclipse.equinox.p2.iu" name="org.eclipse.jdt.feature.jar" version="3.9.2.v20140221-1700"/> </provides> <filter>(org.eclipse.update.install.features=true)</filter> <artifacts size="1"> <artifact classifier="org.eclipse.update.feature" id="org.eclipse.jdt" version="3.9.2.v20140221-1700"/> </artifacts> </unit> … </units> <iuProperties size="1564"> … </iuProperties> </profile>
There are some top-level properties associated with the profile as a whole (whether features are enabled, where the cache locations are, and so on) as well as a set of installable units and installable unit properties. The installable units include plug-ins, features, configuration settings, and sets of dependencies that are required for the platform.
Each installable unit has a name and a version, which almost always correspond to a binary on disk. There is also a namespace, which is used to partition the installable units into different groups:
java.package
: This is the name of a Java package, to enable Import-Package
resolutionosgi.bundle
: This is a dependency on a specific bundle name, to enable Require-Bundle
resolutionosgi.ee
: This is the execution environment (such as JavaSE-1.8
)osgi.fragment
: This defines additional requirements for fragment bundles on their fragment hostorg.eclipse.update.feature
: This gives information about features to enable feature dependenciestooling*
: These are custom-created properties to enable specific entries to be added packages, such as toolingorg.eclipse.platform.sdk
and toolingepp.package.standard
When items are installed into an application, the profile records what the additions or removals were and then regenerates the bundles.info
file. This ensures that when the framework restarts, the profile is brought up in the correct state. Similarly, feature uninstallation will remove the entries from bundles.info
and write out a new profile state.
Note that P2 manages more than just bundles.info
; it can append entries to the eclipse.ini
file, replace the application launcher itself, unpack and extract certain files from the runtime, and create directories. It is also used to calculate which additional features are required when installing new content. For this, the boolean satisfiability library SAT4j is used to determine whether there are any conflicts or whether there are any missing dependencies.
Once the P2 profile is activated, the bundles are installed and started if necessary, and then control is handed over to the Eclipse product or application, such as org.eclipse.platform.ide
or org.eclipse.ui.ide.workbench
.