OpenJFX strives not just to be an open source project, but to be an "open development" project as well. This means transparency in planning, performance, bugs, fixes, decisions, code reviews, and more. Any committer on OpenJFX has equal privilege to any other committer and access to the same tools. As OpenJDK provides more infrastructure for open development for things like code review, OpenJFX will take advantage of it.
Tools are a big part of being a productive developer on OpenJFX and we aim to provide excellent support for all three major IDEs: NetBeans, IntelliJ IDEA, and Eclipse. Regardless of which development environment you prefer, you should find it easy to get up and running with OpenJFX. We hope you will return the favor by submitting patches and bug reports!
This section assumes that you have already succeeded in Building OpenJFX. A gradle build must complete before IDE support will fully work (otherwise your IDE will just be a glorified text editor with lots of red squiggles!). Specific instructions for using each IDE is provided below, followed by a discussion on Developer Workflow, Using Mercurial, and Communication with other members of the team. Further information on how we work can be found under Policies and Processes.
Using NetBeans
- Edit netbeans.conf
- Invoke NetBeans
- Add the JDK8 Platform
- Import NetBeans projects
- Rebuild
- Run sample code
- Run sample code with grade built shared libraries (optional)
Edit netbeans.conf
We have found the nightly versions of NetBeans to be unstable under JDK8, but fine otherwise. Further, NetBeans needs to be told not to report errors when private JDK classes referenced. The netbeans.conf file is located in the etc directory of your NetBeans install. You will edit netbeans_default_options and netbeans_jdkhome.
- Change netbeans_default_options to remove "-J-ea" and add "-J-da -J-DCachingArchiveProvider.disableCtSym=true". It does not hurt to increase memory using "-J-Xmx1024m".
- Change netbeans_jdkhome to point to a JDK7 JVM.
Here is a sample file from the Mac. The Windows and Linux default options might be a bit different.
# Options used by NetBeans launcher by default: # (can be overridden by explicit command line switches) # # Note that default -Xmx and -XX:MaxPermSize are selected for you automatically. # You can find these values in var/log/messages.log file in your userdir. # The automatically selected value can be overridden by specifying -J-Xmx or # -J-XX:MaxPermSize= here or on the command line. # # If you specify the heap size explicitly, you may also want to enable # Concurrent Mark & Sweep garbage collector. # (see http://wiki.netbeans.org/FaqGCPauses) # netbeans_default_options="-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-Xmx1024m -J-da -J-DCachingArchiveProvider.disableCtSym=true -J-Dnetbeans.logger.console=true -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true -J-Dplugin.manager.check.updates=false -J-Dnetbeans.extbrowser.manual_chrome_plugin_install=yes" # Default location of JDK: # (set by installer or commented out if launcher should decide) # # It can be overridden on command line by using --jdkhome <dir> # Be careful when changing jdkhome. # There are two NetBeans launchers for Windows (32-bit and 64-bit) and # installer points to one of those in the NetBeans application shortcut # based on the Java version selected at installation time. # netbeans_jdkhome="/Library/Java/JavaVirtualMachines/jdk1.7.0_11.jdk/Contents/Home"
Invoke NetBeans
Add the JDK8 Platform
Import the NetBeans Projects
Rebuild
Run Sample Code
Run Sample Code with gradle built shared libraries
Using IntelliJ IDEA
Using Eclipse
Developer Workflow
The developer workflow always begins and ends with JIRA.
Everything about an issue is captured in JIRA, whether it is a Bug, Feature, Tweak, or Task. JIRA is the database of record for OpenJFX. Any Bug, Feature, Tweak, or Task will have all comments related to the issue recorded directly on the issue, or linked to from the issue. For example, if there is an openjfx-dev mailing list thread about the issue, the issue should contain a link to the mail archives.
The first step in the workflow is to search JIRA for your issue. You may use the JIRA search functionality, or you may ask developers on openjfx-dev if an issue you see is a known issue. You may be asked to file an issue. If you do, it is important to understand the difference between a Feature, a Tweak, and a Bug.
A Feature is a significant piece of new functionality which is expected to take more than two weeks to implement, document, and test. Because features represent a significant amount of work, a development team needs to prioritize and approve work on features. Whoever proposes to work on a feature is responsible to "fund" the development, documentation, and testing. For example, if Feature X is important to you, you can take responsibility to ensure that it is developed according to guidelines and feedback from the team, develop the documentation, and develop the tests. If you do so and the feature is in harmony with the rest of the platform (we're not adding a full blown email client!) then the feature has been "self funded" by the contributor, but will still be gratefully accepted by OpenJFX. On the other hand, if all you propose is to provide the implementation, then it will be up to somebody else to agree to fund the documentation and testing before the feature can be integrated.
Features do not necessarily mean new API, they may also mean significant implementation work such as a new rendering pipeline. A Feature is never a Bug.
A Tweak is a less significant amount of work. It is somewhat like a "little feature". Tweaks can be delivered after the Feature Freeze date, even if they implement new API, as long as the amount of work to deliver the completed tweak is less than two weeks. As with Features, if a contributor wants to supply a Tweak, it is best to ensure that testing and documentation is complete, otherwise the Tweak may not be accepted.
A Bug is a defect in the code. Something is not behaving as it should. Bugs can be fixed all the way to the Code Freeze date, although with stricter guidelines the closer the Code Freeze date approaches. Sometimes the line is blurry between a Bug and a Feature, so be gentle if you need to adjust somebodies Feature to turn it into a Bug or (worse!) if you have to turn a Bug into a Feature. Use judgement and Do the Right Thing.
As a contributor, you might be done with your involvement after filing the issue. If you are not interested or capable of spending the time to supply a patch as well, we thank you! Every little contribution makes a big difference and is gratefully received.
Otherwise, it is time now to tell the Issue owner that you are interested in providing a patch. Collaborate with the owner -- they may already have something in mind that could make your job easier, and smooth the process of accepting the contribution back. Make sure people know you are working on something so that effort is not duplicated. Be responsive if people approach you about the current state of the work.
You should also make sure that you have signed and submitted an Oracle Contributor Agreement and that it has been received and processed. A committer must ensure this has been filed for any non-trivial contribution and the submitter is on the signatories list.
One excellent way to collaborate is to fork the project on BitBucket. From here you can work transparently, making your changes readily available to anybody who would like to contribute. If you need to go away for a while, let the Issue owner know so that the owner isn't waiting around for a patch that is never going to come.
Once you have a patch developed, you have two options. If you are a committer, then you should use the code review process (TBD). If you are not a committer then the best approach is to attach a diff or patch to the JIRA issue if it is very small, or a Webrev to the issue if it is larger. Or you can issue a pull request from BitBucket and provide a link to the pull request in the JIRA. From this point, the issue owner needs to provide quick feedback in the JIRA issue, a code review, and acceptance of the submission when appropriate or clear guidance on why a submission was not accepted when appropriate.
The committer who owns the issue will then be responsible for taking the patch, applying it, running the tests, and pushing the fix to the repository. The comment on the change set should be of the form:
RT-12345: Short Description of the JIRA issue
Summary: Optionally provided to give more info on what is being done
Submitted-By: Contributor email who submitted it
The Summary is optional, and Submitted-By should only be used when the contribution came from somebody who is not a committer on the project.
The final step is to update the JIRA. The JIRA issue should be marked "Resolved" (not "Closed") and a comment should be added with a reference to which changeset(s) were involved. This is most helpful when it is a link to the Mercurial HTTP website for OpenJFX so that a simple click will lead to the patch.
Using Mercurial
Mercurial is a very powerful source control system. If you have not used Mercurial before, it is highly recommended that you download and read the free Mercurial HG RedBook. This will give you a working knowledge of how to use Mercurial from the command line, which is very useful for those cases that you run into from time to time where whatever Mercurial UI you might use day-to-day fails you.
Since cloning a fresh repository is fairly expensive, and since developers are often faced with working on several issues concurrently (perhaps one is in code review while you work on another), each developer must decide how to manage multiple concurrent patches. The most dangerous method is to have a single repository with multiple fixes in it concurrently, because the possibility of introducing a bad patch is quite high.
Because true branches in Mercurial are a permanent part of the record and pushed to all parent repositories, we never use branches in Mercurial. Rather, we either use locally cloned repos, manually managed patches, or Mercurial Queues.
Having multiple local repos is relatively straightforward. First, you clone from whatever the parent repo is you want, for example, from graphics:
hg clone http://hg.openjdk.java.net/openjfx/8/graphics/rt /path/to/my/local/integRepo
Then you clone from your local integration repo, once for each local "branch" you want to maintain. Because Mercurial will use hard links, this should be fairly quick in most cases.
hg clone /path/to/my/local/integRepo rt-1234 hg clone /path/to/my/local/integRepo rt-5678
Basically at this point you manage your own integrations with the graphics repo. Theoretically straightforward, but a lot of busy work!
Another common approach is to use manually managed patches. The way this typical works is that you clone from your repo (such as graphics) and work in that cloned repo. You then do some work. When it is time to switch to another issue that needs to be fixed, you save off the current changes as a patch, revert the changes, and start work on the second issue. When you want to switch back to the first issue, you save off the diff for the second issue, revert all changes, and import the first diff again.
hg clone http://hg.openjdk.java.net/openjfx/8/graphics/rt cd rt vi SomeFile.txt hg diff > rt-1234.patch hg revert --all --no-backup vi SomeOtherFile.txt hg diff > rt-5678.patch hg revert --all -no-backup hg import --no-commit rt-1234.patch
This is by no means foolproof and is a fair amount of work! Wouldn't it be great if there were some tools to automate this work? Well, that is exactly what Mercurial Queues are. Conceptually MQ is one big queue of patches that get applied to your workspace. You can push new changes on, and pop changes off. The above example would be implemented like this in MQ:
hg clone http://hg.openjdk.java.net/openjfx/8/graphics/rt cd rt hg qnew rt-1234 vi SomeFile.txt hg qrefresh hg qnew rt-5678 vi SomeOtherFile.txt hg qpop
SourceTree and TortoiseHg
Instead of using the command line (or perhaps, in addition to) you can also use various visual tools. Atlassian produces one for Mac (and now for Windows) called SourceTree. It has a very simple and intuitive user interface and performs most every task you need when it comes to managing a mercurial repository. You can clone directly within the tool, or open an existing locally cloned Mercurial repository. From within SourceTree you can view the entire history, search through the history, view outstanding changes, commit, push, pull, and perform all the other operations necessary for working with your repo.
Another highly used visual tool for Mercurial on Windows is TortoiseHg. It is very similar visually and in function to SourceTree. For this reason we will focus only on SourceTree in this section, as much of this information also applies to TortoiseHg, or is near enough that you can figure out the rest.
The main window gives a quick view at a glance of the current state of affairs. The branch view shows the history of changes and merges that exist in the repo. You can easily see who has pushed what changsets. If you select a changeset within this view, the details of the changeset are shown below it, listing all the files, and the individual hunks that changed. For the current uncommitted changes, you can revert any hunk (not just an entire file!), and for committed changes you can reverse any hunk (or file), making it easy to back out some changes.
SourceTree also gives you a method for dealing with multiple concurrent changes (the problem we defined in <<Using Mercurial>> above). It is similar to the manual patch style, but using visual tools instead of managing it by hand.
First, we have a very simple project with a single file, Foo.txt. Our repo has a single change set where Foo.txt was created and its single line "First Foo".
We then modify the Foo.txt file. You can see that we've modified the first line to say "Second Foo".
We've now been interrupted and need to switch to another issue. First we select the "Shelve" toolbar button and name our shelved change set
The repo has now been reset to its normal state, and I am free to start working on my second issue, RT-5678. I then am interrupted again and have to switch back to rt-1234 in order to commit the work (perhaps a pending code review has now finished). So, as before, I shelve my changes.
Now I select the shelved rt-1234 and choose to unshelve it.
Mercurial with NetBeans
Mercurial with IntelliJ IDEA
Mercurial with Eclipse
Communication
OpenJFX is a project with committers and contributors from all over the globe. We all live in vastly different timezones and speak very different native languages, and yet all collaborate together on a single code base and a single project. It is sometimes easy for misunderstandings to arise, and sometimes difficult to effectively communicate ideas in a time-sensitive manner. Over many years the software development community has identified a few things that make communicating and collaborating on software easier. We have tried to gather the best practices and bring them all together.
The openjfx-dev mailing list is the main source for free-form communication among all members of the team. The mailing list archives are publicly available. After subscribing to openjfx-dev, you are able to post textual content and easily follow along in all the various issues that are discussed on the list. openjfx-dev is intended as a list for discussing the development of OpenJFX. Every API change request is first created as a JIRA issue, and then a formal request made to openjfx-dev. This is so that everybody can see when a new API is being proposed, and can chime in (primarily on the JIRA issue) with feedback about that API design.
openjfx-dev is also the place to raise architectural issues or questions, or to get help when things aren't building or when some new idea needs to be discussed. It should be a place of respect and moderation in dialog. We're all on the same team, working together to build the best project we can.
Although much dialog occurs on openjfx-dev, the most work and the most data resides in JIRA. Each issue in JIRA contains (or should contain) all of the information pertaining to that issue, such that anybody who reads over the issue can understand the problem, the proposed solutions, the chosen solution (and why it was chosen), the nature and flow of the code review, and when and where the fix went in (or why a fix did not go in) and/or links to that information. JIRA will tell you when an issue is scheduled for work, or if it is unscheduled, or if it is unassigned or to whom it is assigned. Generally individuals are encouraged to vote for issues they feel are important, and to watch any issue that they are interested in and want to participate on.
Most teams also setup JIRA Dashboards for monitoring the progress of a particular release. Some are also using JIRA tags on issues to indicate which "sprint" an issue is assigned to. These dashboards can be searched out by each user of JIRA and added to their home page.
By using JIRA effectively, and by using JIRA dashboards, it is possible for anybody to follow along with development of those issues they are most interested in, and to track the progress of the release and what work is going on now. We attempt to make sure that JIRA is the database of record, meaning that the most accurate up-to-date information is always kept in JIRA.