JPPF, java, parallel computing, distributed computing, grid computing, parallel, distributed, cluster, grid, cloud, open source, android, .net
JPPF, java, parallel computing, distributed computing, grid computing, parallel, distributed, cluster, grid, cloud, open source, android, .net
JPPF

The open source
grid computing
solution

 Home   About   Features   Download   Documentation   On Github   Forums 

Working from the source code

From JPPF 5.2 Documentation

(Difference between revisions)
Jump to: navigation, search
(API deprecation and removal policy)
 
 
Line 3: Line 3:
 
== Source code repository ==
 
== Source code repository ==
  
We use the SourceForge.net infrastructure for our SVN repository. The repository follows a very common layout with /trunk, /branches and /tags (i.e. versions) under the repository root.
+
The JPPF source code is hosted on [https://github.com '''Github'''] at [https://github.com/lolocohen/JPPF '''https://github.com/lolocohen/JPPF''']
  
The SVN repository root is: http://svn.code.sf.net/p/jppf-project/code/
+
The URLs for cloning/checking out/feztching are:
 +
 
 +
* '''Git''': git@github.com:lolocohen/JPPF.git
 +
* '''HTTPS''': https://github.com/lolocohen/JPPF.git
  
 
== Versioning policy ==
 
== Versioning policy ==
  
* there is normally a version tag for each released version (like v_2_1 for version 2.1, etc.)
+
* there is normally a version tag for each released version (like v_2_1 for version 2.1, v_5_2_9 for version 5.2.9, etc.)
* any version that includes new features will be numbered in x.y form for minor versions, and x.0 for major versions. We're not exactly clear on the distinction between minor vs. major, however the rule of thumb is that if a major refactoring was involved, especially to enable new major features, then it is a major version
+
* any version that includes new features will be numbered in x.y form for minor versions, and x.0 for major versions. The rule of thumb is that if a major refactoring was involved, especially to enable new major features, then it is a major version.
* a version that only includes bug fixes is numbered in the form x.y.z. We call these technical releases, as they contain no new feature
+
* a version that only includes bug fixes is numbered in the form x.y.z. We call these maintenance releases. They may (rarely) include enhacements to existing features, however they do not contain any new feature.
* if we can provide a patch to our users and they are satisfied with it then that's what we do. It's much simpler and faster than releasing a new version
+
* if we can provide a patch to our users on the latest maintenance release of a version and they are satisfied with it then that's what we do. It's much simpler and faster than releasing a new version. If a new maintenance release is deliviered later on, it will include all new patches.
  
 
== Branching policy ==
 
== Branching policy ==
  
* the fewer branches, the better!
 
 
* branches are created when working on major new features in the trunk, and new minor features have been requested by the users. We keep working on the major stuff on the trunk, and create a new branch for the minor modifications and enhancements
 
* branches are created when working on major new features in the trunk, and new minor features have been requested by the users. We keep working on the major stuff on the trunk, and create a new branch for the minor modifications and enhancements
* branches are created from tagged versions, based on the latest release. For instance, the latest version was v2.4 (tag v_2_4), if we were to create a new branch now, we would create b_2_4. Then depending on major vs. minor work on the trunk, the next version based on this branch would be v_2_5 (new features that cannot wait the next major version) or v_2_4_1 (bug fixes only).
+
* branches are named in the format ''b_x_y'' corresponding to major/minor version ''x.y''. For instance, the latest version is 5.2. We are currently working on the upcoming major version 6.0. The next branch will thus be named ''b_6_0'' and a corresponding version tag ''v_6_0'' will be created. Then, the next maintenance release based on this branch will be the ''v_6_0_1'' tag, and the next branch will be ''b_6_1'' (with a corresponding v_6_1 tag).
* we only work on the trunk and the latest branch. Bug fixes are committed to both branches, as are minor new features. Major new features are committed to the trunk only.
+
* we generally only work on the trunk/master and the latest branch, as we do not have much bandwith for anything else. Bug fixes are committed to both branches, as are minor new features. Major new features are committed to the trunk only.
  
 
== Patches ==
 
== Patches ==
Line 27: Line 29:
 
== Setting up a development and build environment ==
 
== Setting up a development and build environment ==
  
Development is done with the [http://www.eclipse.org/ Eclipse] IDE. Here we are not discussing the merits of Eclipse versus other IDEs. This is just what we use.
+
Development is done with the [http://www.eclipse.org/ '''Eclipse'''] IDE. Here we are not discussing the merits of Eclipse versus other IDEs. This is just what we use.
Two additional plugins are required: [http://subclipse.tigris.org/ Subclipse] to integrate with SVN, and [http://eclipse-cs.sourceforge.net/ Checkstyle], to enforce the consistency of the code metrics and documentation.
+
An additional plugin is required: [http://eclipse-cs.sourceforge.net/ '''Checkstyle'''], to enforce the consistency of the code metrics and documentation. It can be found in the Eclipse market place at: https://marketplace.eclipse.org/content/checkstyle-plug
  
 
=== Prerequisites ===  
 
=== Prerequisites ===  
  
* to be able to build the Android node project properly, you need to define the ANDROID_HOME environment variable and make it point to the Android SDK installation root. For instance: <tt>export ANDROID_HOME=/home/me/android-sdk</tt>
+
* you must have [https://git-scm.com/ '''Git'''] installed
 +
* to be able to build the Android node project properly, you need to define the '''ANDROID_HOME''' environment variable and make it point to the Android SDK installation root. For instance: <tt>export ANDROID_HOME=/home/me/android-sdk</tt>
 
* you must also make sure that you have installed (with the Android sdk manager) the "Android 4.4.2 (API 19) SDK Platform" and the "Android SDK Build-tools" version 23.0.1
 
* you must also make sure that you have installed (with the Android sdk manager) the "Android 4.4.2 (API 19) SDK Platform" and the "Android SDK Build-tools" version 23.0.1
* make sure that you have the Subclipse and Checkstyle plugins installed in Eclipse. You can get them from the Eclipse market place
+
* JPPF uses the [http://ant.apache.org '''Apache Ant'''] build system. Make sure it is installed in your environment.
 +
* make sure that you have the Checkstyle plugin installed in Eclipse.
  
=== Importing the code from SVN ===
+
=== Importing the code from Git ===
  
* create a new Eclipse workspace and open it
+
If you have forked the JPPF repo, please replace, in the following examples, the ''git@github.com:lolocohen/JPPF.git'' URL with that of your own forked repository.
 +
 
 +
1) To import the source code:
 +
 
 +
<ul class="samplesList">
 +
  <li style="margin-bottom: 5pt">
 +
To clone the master, use:<br/>
 +
<pre style="margin-top: 0pt; margin-bottom: 0pt" prettyprint lang-txt>
 +
git clone git@github.com:lolocohen/JPPF.git
 +
</pre>
 +
This will create a local Git repo in a subfolder named "JPPF".
 +
  </li>
 +
 
 +
  <li style="margin-bottom: 5pt">
 +
To clone a specific branch to a specified folder, use:<br/>
 +
<pre style="margin-top: 0pt; margin-bottom: 0pt" prettyprint lang-txt>
 +
git clone -b b_5_2 git@github.com:lolocohen/JPPF.git JPPF-5.2
 +
</pre>
 +
This will clone the 5.2 branch in the JPPF-5.2 subfolder.<br/>
 +
  </li>
 +
 
 +
  <li style="margin-bottom: 5pt">
 +
To clone a specific tag to a specified folder:<br/>
 +
First, clone the repository:
 +
<pre style="margin-top: 0pt; margin-bottom: 0pt" prettyprint lang-txt>
 +
git clone git@github.com:lolocohen/JPPF.git JPPF-5.2.8
 +
</pre>
 +
This will clone the repo in the JPPF-5.2.8 subfolder.<br/>
 +
 
 +
Now, checkout the tag in a new local branch:
 +
<pre style="margin-top: 0pt; margin-bottom: 0pt" prettyprint lang-txt>
 +
cd JPPF-5.2.8
 +
git checkout tags/v_5_2_8 -b JPPF_528
 +
</pre>
 +
This will checkout the "v_5_2_8" tag into a new branch called "JPPF_528"
 +
  </li>
 +
</ul>
 +
 
 +
2) To open the source code in Eclipse:
 +
 
 +
* start Eclipse, specifying the folder where you cloned the repository as workspace root
 +
* ensure you have a JDK 7 installed; go to "Window > Preferences > Java > Installed JREs". If no JDK 7 is listed, please install one and add it, then make it the derfault JRE for the workspace.
 +
* set the compiler compliance level to 1.7: go to "Window > Preferences > Java > COmpiler", then select "1.7" in the "Compiler compliance level" drop-down list
 
* define a classpath variable "JDK_HOME" that points to the root installation folder of your JDK (make sure it's a JDK and not a JRE): "Window > Preferences > Java > Build Path > Classpath Variables" then click on "New ...". This is needed because JPPF uses a custom doclet for the javadoc, whose source is in JPPF/src, and the JDK's tools.jar is needed as a dependency
 
* define a classpath variable "JDK_HOME" that points to the root installation folder of your JDK (make sure it's a JDK and not a JRE): "Window > Preferences > Java > Build Path > Classpath Variables" then click on "New ...". This is needed because JPPF uses a custom doclet for the javadoc, whose source is in JPPF/src, and the JDK's tools.jar is needed as a dependency
* open the "SVN Repository Exploring" perspective and create a new SVN repository location: right-click in the "SVN Repositories" view and select "New > Repository Location"
+
* import the local Git repository:
* enter "http://svn.code.sf.net/p/jppf-project/code/" as the url: this is the root of the JPPF SVN repository
+
** from the menu, select '''File > Import > Git > Projects from Git''' and click "Next"
* depending on which version you want to build:
+
** select '''Existing local repository''' and click "Next"
** if you want the latest and greatest, expand the "trunk" subfolder
+
** click on "Add" and then browse to the root of the local Git repository
** if you want the code from another branch, expand "branches" and select the one you want. For example branches/b_5_1 contains the latest code for the 5.1.x branch
+
** make sure to check the repository you just added, then click "Finish"
** if you want the code from a specific version, expand "tags" and select the one you want. For example tags/v_5_1_4 contains the code for JPPF 5.1.4
+
** select the repository you just added and click "Next"
* select all the modules under the branch or version you chose, then right-click and select "Checkout"
+
** in the next dialog, ensure that the option "Import existing Eclipse project" is selected (it is selected by default) and click "Next"
* in the next dialog, just click "finish" and the projects are checked out into your workspace
+
** click "Finish" to import the projects
 
* everything should be imported and there should be no build error when you get back to the Java perspective
 
* everything should be imported and there should be no build error when you get back to the Java perspective
  
Line 54: Line 100:
 
* download the source distribution JPPF-x.y.z-full-src.zip and unzip it
 
* download the source distribution JPPF-x.y.z-full-src.zip and unzip it
 
* open the resulting JPPF-x.y.z-full-src folder as a workspace with Eclipse
 
* open the resulting JPPF-x.y.z-full-src folder as a workspace with Eclipse
 +
* ensure you have a JDK 7 installed; go to "Window > Preferences > Java > Installed JREs". If no JDK 7 is listed, please install one and add it, then make it the derfault JRE for the workspace.
 +
* set the compiler compliance level to 1.7: go to "Window > Preferences > Java > COmpiler", then select "1.7" in the "Compiler compliance level" drop-down list
 
* define a classpath variable "JDK_HOME" that points to the root installation folder of your JDK (make sure it's a JDK and not a JRE): "Window > Preferences > Java > Build Path > Classpath Variables" then click on "New ..."
 
* define a classpath variable "JDK_HOME" that points to the root installation folder of your JDK (make sure it's a JDK and not a JRE): "Window > Preferences > Java > Build Path > Classpath Variables" then click on "New ..."
 
* import the projects: "File > Import > General > Existing projects into Workspace"
 
* import the projects: "File > Import > General > Existing projects into Workspace"
Line 70: Line 118:
 
=== Building everything ===
 
=== Building everything ===
  
Simply run one of the "deploy[.xxx]" targets
+
Simply run one of the "deploy[.xxx]" Ant targets
All the build artifacts (zip, jar apk) are created under JPPF/build.
+
For instance:
 +
<pre prettyprint lang-txt>
 +
cd JPPF-b5.2/JPPF/bin
 +
ant deploy.noinstaller
 +
</pre>
 +
 
 +
This will build everything, except the installer, for the 5.2 branch previously imported from Git.
 +
 
 +
All the build artifacts (zip, jar apk) are created in the <WORKSPACE_ROOT>/JPPF/build folder.
  
 
=== tests ===
 
=== tests ===
  
Provides a framework and a set of automated tests based on JUnit to ensure that JPPF features are working as expected and that no regression were introduced in the latest code.
+
JPPF provides a framework and a set of automated tests based on JUnit, to ensure that JPPF features are working as expected and that no regression were introduced in the latest code.
These tests start actual drivers and nodes, and manage the corresponding processes. So they're more than unit tests.  
+
These tests start actual drivers and nodes (i.e. small but full-fledged grids on the local machine), and manage the corresponding processes. So they're more than unit tests.  
They do, however, ensure that a large set of the features are convered.
+
They do, however, ensure that the JPPF features are convered.
  
 
To run the tests, open a command prompt in JPPF_WORKSPACE/JPPF/bin and type: "<tt>ant tests.run</tt>". This will generate a number of related artifacts:
 
To run the tests, open a command prompt in JPPF_WORKSPACE/JPPF/bin and type: "<tt>ant tests.run</tt>". This will generate a number of related artifacts:
 
* an HTML JUnit tests report in JPPF_WORKSPACE/tests/report
 
* an HTML JUnit tests report in JPPF_WORKSPACE/tests/report
 
* a zip of the client, driver(s) and node(s) logs for each test class in JPPF_WORKSPACE/tests/logs.<br>For example, for the test class test.org.jppf.client.TestJPPFClient you will have the logs in JPPF_WORKSPACE/tests/logs/test.org.jppf.client.TestJPPFClient.zip
 
* a zip of the client, driver(s) and node(s) logs for each test class in JPPF_WORKSPACE/tests/logs.<br>For example, for the test class test.org.jppf.client.TestJPPFClient you will have the logs in JPPF_WORKSPACE/tests/logs/test.org.jppf.client.TestJPPFClient.zip
* the tests all log to the same client log file JPPF_WORKSPACE/tests/jppf-client.log
 
  
  
 
A number of JUnit launch configuration are also provided in test/launches, so the tests can be run from within the IDE, as any other JUnit test.
 
A number of JUnit launch configuration are also provided in test/launches, so the tests can be run from within the IDE, as any other JUnit test.
 
=== stress-tests ===
 
 
Provides a sophisticated framework for testing the resilience and stability of a JPPF grid under load and stress conditions.
 
It makes it really easy to define sophisticated topologies via a very few configuration properties.
 
See its [{{SERVER}}/private/stress-tests/Readme.txt Readme.txt] for an overview of what it can do.
 
  
 
== Code metrics and documentation constraints ==
 
== Code metrics and documentation constraints ==

Latest revision as of 07:38, 15 April 2018

Contents

Main Page > Working from the source code

[edit] 1 Source code repository

The JPPF source code is hosted on Github at https://github.com/lolocohen/JPPF

The URLs for cloning/checking out/feztching are:

[edit] 2 Versioning policy

  • there is normally a version tag for each released version (like v_2_1 for version 2.1, v_5_2_9 for version 5.2.9, etc.)
  • any version that includes new features will be numbered in x.y form for minor versions, and x.0 for major versions. The rule of thumb is that if a major refactoring was involved, especially to enable new major features, then it is a major version.
  • a version that only includes bug fixes is numbered in the form x.y.z. We call these maintenance releases. They may (rarely) include enhacements to existing features, however they do not contain any new feature.
  • if we can provide a patch to our users on the latest maintenance release of a version and they are satisfied with it then that's what we do. It's much simpler and faster than releasing a new version. If a new maintenance release is deliviered later on, it will include all new patches.

[edit] 3 Branching policy

  • branches are created when working on major new features in the trunk, and new minor features have been requested by the users. We keep working on the major stuff on the trunk, and create a new branch for the minor modifications and enhancements
  • branches are named in the format b_x_y corresponding to major/minor version x.y. For instance, the latest version is 5.2. We are currently working on the upcoming major version 6.0. The next branch will thus be named b_6_0 and a corresponding version tag v_6_0 will be created. Then, the next maintenance release based on this branch will be the v_6_0_1 tag, and the next branch will be b_6_1 (with a corresponding v_6_1 tag).
  • we generally only work on the trunk/master and the latest branch, as we do not have much bandwith for anything else. Bug fixes are committed to both branches, as are minor new features. Major new features are committed to the trunk only.

[edit] 4 Patches

We have a section of the web site dedicated to patches. These allow us to release bug fixes quickly in a formal way, and avoid a full release cycle once a bug has been fixed. It's proved quite effective so far.

[edit] 5 Setting up a development and build environment

Development is done with the Eclipse IDE. Here we are not discussing the merits of Eclipse versus other IDEs. This is just what we use. An additional plugin is required: Checkstyle, to enforce the consistency of the code metrics and documentation. It can be found in the Eclipse market place at: https://marketplace.eclipse.org/content/checkstyle-plug

[edit] 5.1 Prerequisites

  • you must have Git installed
  • to be able to build the Android node project properly, you need to define the ANDROID_HOME environment variable and make it point to the Android SDK installation root. For instance: export ANDROID_HOME=/home/me/android-sdk
  • you must also make sure that you have installed (with the Android sdk manager) the "Android 4.4.2 (API 19) SDK Platform" and the "Android SDK Build-tools" version 23.0.1
  • JPPF uses the Apache Ant build system. Make sure it is installed in your environment.
  • make sure that you have the Checkstyle plugin installed in Eclipse.

[edit] 5.2 Importing the code from Git

If you have forked the JPPF repo, please replace, in the following examples, the git@github.com:lolocohen/JPPF.git URL with that of your own forked repository.

1) To import the source code:

  • To clone the master, use:
    git clone git@github.com:lolocohen/JPPF.git
    

    This will create a local Git repo in a subfolder named "JPPF".

  • To clone a specific branch to a specified folder, use:
    git clone -b b_5_2 git@github.com:lolocohen/JPPF.git JPPF-5.2
    

    This will clone the 5.2 branch in the JPPF-5.2 subfolder.

  • To clone a specific tag to a specified folder:
    First, clone the repository:
    git clone git@github.com:lolocohen/JPPF.git JPPF-5.2.8
    

    This will clone the repo in the JPPF-5.2.8 subfolder.

    Now, checkout the tag in a new local branch:

    cd JPPF-5.2.8
    git checkout tags/v_5_2_8 -b JPPF_528
    

    This will checkout the "v_5_2_8" tag into a new branch called "JPPF_528"

2) To open the source code in Eclipse:

  • start Eclipse, specifying the folder where you cloned the repository as workspace root
  • ensure you have a JDK 7 installed; go to "Window > Preferences > Java > Installed JREs". If no JDK 7 is listed, please install one and add it, then make it the derfault JRE for the workspace.
  • set the compiler compliance level to 1.7: go to "Window > Preferences > Java > COmpiler", then select "1.7" in the "Compiler compliance level" drop-down list
  • define a classpath variable "JDK_HOME" that points to the root installation folder of your JDK (make sure it's a JDK and not a JRE): "Window > Preferences > Java > Build Path > Classpath Variables" then click on "New ...". This is needed because JPPF uses a custom doclet for the javadoc, whose source is in JPPF/src, and the JDK's tools.jar is needed as a dependency
  • import the local Git repository:
    • from the menu, select File > Import > Git > Projects from Git and click "Next"
    • select Existing local repository and click "Next"
    • click on "Add" and then browse to the root of the local Git repository
    • make sure to check the repository you just added, then click "Finish"
    • select the repository you just added and click "Next"
    • in the next dialog, ensure that the option "Import existing Eclipse project" is selected (it is selected by default) and click "Next"
    • click "Finish" to import the projects
  • everything should be imported and there should be no build error when you get back to the Java perspective

[edit] 5.3 Importing the code from the source distribution

  • download the source distribution JPPF-x.y.z-full-src.zip and unzip it
  • open the resulting JPPF-x.y.z-full-src folder as a workspace with Eclipse
  • ensure you have a JDK 7 installed; go to "Window > Preferences > Java > Installed JREs". If no JDK 7 is listed, please install one and add it, then make it the derfault JRE for the workspace.
  • set the compiler compliance level to 1.7: go to "Window > Preferences > Java > COmpiler", then select "1.7" in the "Compiler compliance level" drop-down list
  • define a classpath variable "JDK_HOME" that points to the root installation folder of your JDK (make sure it's a JDK and not a JRE): "Window > Preferences > Java > Build Path > Classpath Variables" then click on "New ..."
  • import the projects: "File > Import > General > Existing projects into Workspace"
  • browse to the "JPPF-x.y.z-full-src" workspace folder and click "OK"
  • make sure all the projects in the list are checked and click "Finish"
  • everything should be imported and there should be no build error when you get back to the Java perspective

[edit] 5.4 Building the Android node

  • the Android node is not an Eclipse project, rather it is an Android Studio project. To edit/modify the code, the best is to open it with Android Studio, however it is not necessary if you just want to build it
  • JPPF uses Ant as its build system, and it uses a specific Ant target to invoke the build of the Android node
  • in Eclipse, open the Ant view: "Window > Show View > Ant"
  • add this build file: JPPF/bin/build.xml
  • in this build file, run the target "build.android" by double-clicking it (you can also do it in the command line by running "ant build.android" in JPPF/bin)

[edit] 5.5 Building everything

Simply run one of the "deploy[.xxx]" Ant targets For instance:

cd JPPF-b5.2/JPPF/bin
ant deploy.noinstaller

This will build everything, except the installer, for the 5.2 branch previously imported from Git.

All the build artifacts (zip, jar apk) are created in the <WORKSPACE_ROOT>/JPPF/build folder.

[edit] 5.6 tests

JPPF provides a framework and a set of automated tests based on JUnit, to ensure that JPPF features are working as expected and that no regression were introduced in the latest code. These tests start actual drivers and nodes (i.e. small but full-fledged grids on the local machine), and manage the corresponding processes. So they're more than unit tests. They do, however, ensure that the JPPF features are convered.

To run the tests, open a command prompt in JPPF_WORKSPACE/JPPF/bin and type: "ant tests.run". This will generate a number of related artifacts:

  • an HTML JUnit tests report in JPPF_WORKSPACE/tests/report
  • a zip of the client, driver(s) and node(s) logs for each test class in JPPF_WORKSPACE/tests/logs.
    For example, for the test class test.org.jppf.client.TestJPPFClient you will have the logs in JPPF_WORKSPACE/tests/logs/test.org.jppf.client.TestJPPFClient.zip


A number of JUnit launch configuration are also provided in test/launches, so the tests can be run from within the IDE, as any other JUnit test.

[edit] 6 Code metrics and documentation constraints

Via Checkstyle, we attempt to enforce the following:

  • A header, with the copyright disclaimer and license terms, must be present at the start of each file (Java, configuration, XML files, etc.). Using Eclipse code and documentation templates for this is quite handy and painless.
  • there must be a Javadoc for each and all Java artifacts, no matter their visibility level: classes, instance and static variables, methods. {@inheritDoc} tags are accepted for overridden methods, when there is no significant implementation details to document.
  • Java files can be 600 hundred lines long at most. If it gets longer, split it. It may seem unduly constraining, however it forces the developers to really think about how they write their code, and as far as we know, results in a clearer code and class design. It also leads to more frequent refactorings and provides a better survivability of the design. This has worked great during all the years of JPPF development.
  • Methods can be no more than 80 lines long. If a method goes over this limit, split it.

There are few exceptions to these rules, essentially in Java files that we imported directly from other sources with a compatible license or from the public domain. We are still working on that.

You can find actual code metrics on the Open HUB page for JPPF.

[edit] 7 API deprecation and removal policy

In principle, any deprecated API is removed from the next major version. For example if method a() of class A is deprecated in version 4.1, then it will be removed in version 5.0.

When the deprecation occurs, it must be clearly documented, and the deprecated API must still work as it used to. This ensures that no existing code using this API is broken and that users have time to prepare and adjust for when it will be removed.

Here is an example of how this can be documented:

/**
 * Get the listener that receives notifications of completed tasks.
 * @return a {@code TaskCompletionListener} instance.</span>
 * @deprecated {@code TaskResultListener} and its implementations are no longer exposed
 * as public APIs. {@link JobListener} should be used instead, with the
 * {@link #addJobListener(JobListener)} and {@link #removeJobListener(JobListener)}
 * methods.
 */
@Deprecated
public TaskResultListener getResultListener() {
  ...
}

[edit] 8 JPPF Maven artifacts

Starting from JPPF 3.3, we are now publishing the main JPPF artifacts to Maven Central:
http://search.maven.org/#search|ga|1|jppf

You can also find the public snapshots and releases on Sonatype's public repository:
https://oss.sonatype.org/content/groups/public/org/jppf/

Main Page > Working from the source code

JPPF Copyright © 2005-2019 JPPF.org Powered by MediaWiki