Team Development Using Subversion
An Oracle JDeveloper How To
Document
Written by Susan Duncan, Oracle Corporation
May, 2008
Overview
Developing applications as a team introduces several considerations,
including source and version control for files, and utilizing shared
resources. This paper details the use of integrated source control via
Subversion in JDeveloper 11g, and how your team can package and share
resources. It looks at best practices in team development, and shows
how to coordinate check-in procedures and shared files across a
development team to leverage these features for maximum productivity
Even the smallest of development teams needs to
maintain control of its source code. There are many ways to do this:
using a manual system, a database, a commercially available or in-house
Source Code Management (SCM) system. But whatever system you use, your
system should fulfill certain basic functions:
- Integrate code changes
- Maintain code history
- Revert to previous code version
- Compare versions and changes
- Merge changes
Supported Version Control Systems
JDeveloper supports a number of version control systems.
This means you can use JDeveloper as a client to connect to the
specific version control repository and manipulate your versioned code
from within JDeveloper. This gives developers greater productivity, as
they don’t have to open another tool or move outside of their
IDE to carry out SCM operations.
In JDeveloper 11g Subversion (SVN) support directly into
the IDE. JDeveloper 11g focuses source control support on SVN whilst
continuing to enhance support for other systems, whether these are
integrated into JDeveloper (CVS) or downloadable extensions for
products such as Clear Case, Perforce etc.
Why Subversion?
SVN is a powerful, open-source version control system
that has fast become the de-facto standard for application version
control. It was developed to update and overcome some of the
limitations of Concurrent Versions System (CVS), an older open-source
system that was widely used before SVN was introduced and continues to
be used. There is a free
online book that details not only how SVN works but also
details its improvements over CVS. It can be used to check and
understand concepts and ensure that JDeveloper's SVN support is the
best it can be.
One of the major changes between CVS and SVN is
SVN’s usage of atomic commits. When you commit files either
all or none of the committed changes are done. If there is a problem
– perhaps a network failure or conflicts between some of the
changed code – then you do not finish up with some of your
files committed whilst others are rejected. This was a drawback with
CVS and is particularly important when you are doing application
development that has dependencies between files – such as a
Java file and a corresponding XML metadata file.
Another advantage of SVN is its support for full
versioning of both files and folders. A full history of them is held on
the SVN server and this allows you to add, delete, copy and rename
then. CVS only versions files and so there is not full
‘true’ version history as the folders containing
these files are not versioned. In addition, replacing a file with a new
one (completely unrelated) with the same name does not give a clean
history to that new file, the old history from the redundant file is
maintained. In addition, if a file is renamed in CVS then the version
history of those files is lost, while Subversion copies the history to
the new element.
Where more than one developer is going to be working on
the same file, there has to be a system to prevent one developer's work
unintentionally overwriting another's. The preferred solution to this
with Subversion is the copy-modify-merge model. In this model, each
developer working on a file takes a copy of it (called a Working Copy),
modifies it, then merges it with the latest code in the repository.
This may sound as if it would cause frequent conflicts in the content,
but in practice this is rarely the case. When conflicts do occur, there
is an efficient process for resolving them (see Resolving Code
Conflicts).
As with any development project, time spent setting up
your application and the SVN repository structure for that application
is time well spent.
Versioning Level
A question that comes up regularly in development teams
is ‘At what level should I version my code?’ The
answer should always be - at the top level. If you are using JDeveloper
this means at the Application Level.
We adopt this internally for JDeveloper’s development and
it's a top tip for best practice.
Initial Import
If you are working on a new development you may have to
carry out the initial import of your application to the SVN repository.
It makes sense to set up the repository at an early stage of
development. Perhaps once the initial application has been created. The
recommended standard repository layout is to provide an
<Application Name> directory containing three folders:
Trunk, Branches, Tags (see Branching).
Using JDeveloper you can use the Subversion Navigator to
add a new folder to your repository ready to house your new application
directly (see Figure 1) or you can create the folder whilst using
JDeveloper’s Import Wizard

Figure 1. JDeveloper's Subversion Repository Navigator
The wizard takes you through the steps to import your
initial application into the repository. The easiest way to open the
wizard is to select Versioning -> Import Files from the
application dropdown menu. Now you can create the folder to hold your
source code, comment your import, exclude any files or file patterns
from the initial import (see Excluding Files) and automatically
checkout the code to your local working copy ready for your development
work.
Working Copy
Using JDeveloper’s integrated SVN Navigator
and the Application Navigator it is easy to make best use of the SVN
concept Working Copy. To work on an application, you check it out from
the SVN repository. This copy becomes your working copy. In addition to
the standard Commit and Update SVN commands, JDeveloper provides
additional commands Commit Working Copy and
Update Working Copy. These commands
ensure that all the files in your working copy are committed/updated
whatever node in the Application Navigator you invoked the command
from. Figure 2 shows the Commit Working Copy menu being invoked from
the home.jspx node in the Application Navigator.
Figure 2. Invoking Commit Working Copy From File Menu
What if my development team uses tools other than
JDeveloper?
If you are using JDeveloper, you should version at the
application level. This assures that your .jws and .jpr configuration
files are included in source control, especially important if you have
dependencies between projects. But what if not all your development
team are using JDeveloper? Perhaps you have some team members that use
Eclipse or another IDE as well as JDeveloper? In this case it is
important to ensure that you still place both your 'jws' and your 'jpr'
files under source control.
Why? Because JDeveloper looks at the state of those
files to decide what versioning menu options it makes available. For
instance, say the projects making up an application had been imported
into SVN but the root level application folder and the .jws file had
not been included. Perusing the versioned files through the SVN
Navigator repository you would notice that there was no .jws in the
application root folder. To overcome this you would create a new empty
application and check out the JDeveloper projects into the new
application. But if you tried to access the Versioning menu at the
application level you would see 'Import Files' as the .jws file is not
part of the versioned code and so JDeveloper offers you the option to
place the application under version control. If this happens the
workaround is to go back to the repository and add the .jws file to
version control. This brings the IDE back into kilter and allows you to
continue using JDeveloper's integrated SVN support.
What if my development process mandates commits at the
project level?
The above scenario, checking out projects into an empty
application, does offer you an alternative to versioning at the
application level (best practice). By checking out individual projects
you are creating a working copy of each project as you check it out.
This means that you can commit and update each project as a separate
entity. But beware, if you do this then be sure that you understand any
dependencies between the projects and are careful to update all the
projects if others are also working on them.
A better alternative is to stick to the best practice
of versioning at the application level and use JDeveloper’s Pending
Changes windows to commit by project. Pending Changes
consists of three tabs and provides information on individual
applications and projects open in your IDE that are under version
control.
- The Outgoing Changes
tab shows you all files that have been modified and need committing to
the repository. Figure 3 shows 1 file with an outgoing changes in the
StoreFrontUI project.
- The Candidates tab
shows you all files that you have added to the working copy of your
versioned applications and projects (open in the IDE) since you last
committed. These files need to be added to your SVN repository using
the Add command – either from the Add button in the
Candidates tab or through the Application Navigator (see Excluding
Files)
- The Incoming Changes
tab shows you all the files that have been committed to the SVN
repository by another member of the development team since you last
committed your changes. (See Comparing Versions)

Figure 3. Outgoing Changes Tab
Whether you use Update or manually review and add the
changes might depend on how many and how complex the changes are and
also how easy the source is to read. Another very important
consideration is the nature of the change. In many cases, especially if
you are using a framework such as Oracle’s Application
Development Framework (ADF) making the changes manually could be error
prone as there are dependencies between Java and their corresponding
XML metadata files. For this reason best practice is to use the Update
Working Copy mechanism to update code from the repository, whether you
have used the History to manually browse changes in advance or not. It
may be that you use the History tab to find changes and the author (see
Figure 6) and then communicate with the author if you are unsure of how
the changes affect your code.
What if I need to check out other code not in my
application?
This might occur if your development organization has
read only ‘standard’ code or libraries. Rather than
each developer checking this code out and adding it to their
application by hand you can use the svn:externals
property. The advantage of this is that once you set the property on
your application everyone who checks out the application from SVN will
also get exactly the same set of code and associated libraries. SVN
Properties are exhaustively covered in the SVN book detailed earlier.

Figure 4. Add Subversion Property
Figure 4 shows the JDeveloper Add
Subversion Property dialog. In this example the Value
String field show a value pair entered to indicate that
the library adflibStoreFrontService.jar is to be checked out of its URL
in an SVN repository to a folder called external_jars. The folder
external_jars will be created in the Resource File
indicated in the dialog. Invoking the dialog on this node in the
Application Navigator set this. The correct URL of the library was
obtained by using the Copy URL command on the node in the Subversion
Navigator (see Figure 1)
Excluding Files From Version Control
There are a couple of ways that files are excluded from
the SVN Repository. You can exclude files during the Initial Import,
ensure that certain file name patterns are never added to the
repository or mark specific files for exclusion. JDeveloper recognizes
certain file types as not needing to be controlled and additionally
provides functionality for you to use the Subversion property svn:ignore.
During Initial Import
As mentioned earlier, it is possible to add filters to
exclude files during the Initial Import of an application. JDeveloper
uses its Global Ignore List to provide a
pre-populated list of those files/file types that you are not likely to
need versioned such as compiled Java classes (.class files). The Global
Ignore List is displayed in Step 5 of the Import wizard. You can add
filters to this list. Note that these additional filters are not added
to the Global Ignore List and are not persisted between JDeveloper
sessions. If you find that there is a specific pattern that your
development teams always filter then you should document this in your
development process to ensure that any team member doing an Initial
Import of code is aware of it.
Imagine this scenario: You create a new application
containing some compiled Java classes. The Global Ignore List is also
used by the Application Navigator to restrict the items displayed
there. Hence, you do not see the compiled classes in the navigator but,
of course, they exist on the file system. Now you Import the
application into SVN and the same filter is applied to the application.
As part of the Import wizard you choose to Check Out the imported
application. Your original application location on the file system will
by default now contain your checked out application – minus
the excluded files. In fact, your original files have been backed up by
JDeveloper so it is possible to return to them. But from this point on
you should be working with your repository to maintain all your
required code.
Excluding New Files
During application development it might be that you want
to exclude certain file types or specific files from the repository,
whilst still maintaining them in your working copy. To do this you use
the svn:ignore property. There are a number of places to do this:
- Candidates Tab, Pending Changes
- This tab shows all the files you have not yet
added to version control. You can select files here and use the context
menu to invoke the Add Subversion Property dialog. The dialog is
populated with the files you selected and you can either choose to
specifically ignore those files or edit the dialog to add file
patterns.
- Specific file in the Application
Navigator
- By invoking the Add Subversion Property dialog on
a specific file you can again add that file or a file pattern to
svn:ignore.
- Folder node in the Application Navigator
- svn:ignore is always set on a folder so you can
invoke the Add Subversion Propery dialog from any folder node. Even
when following the first two options above, the property is set on the
owning folder of the selected files
Resolving Code Conflicts
As with all development projects there are a multitude
of ways to resolve code conflicts between developers. No tool can
ensure that conflicts do not occur. Much of the onus is on the
development process of the team, its methodology and, as always,
communication between developers. Some development teams where the
developer who has the ‘lock’ on the main code wears
a ‘lock’ hat to indicate to other team members that
no one else should be updating the code (doesn’t work so well
with distributed teams).
JDeveloper's development process and methodology
minimize conflicts but developers talk regularly to each other and are
pro-active in informing and discussing potential conflicts that might
arise through new feature development, refactoring or any of the other
myriad of reasons that conflicts arise. Having said that, SVN and
JDeveloper can help to minimize these and provide strategies and
answers to resolve them
Comparing Versions
In a team environment it is inevitable that other
developers change code. These changes may or may not conflict with code
that you are changing. Using the Pending Changes Incoming tab it is
possible to see what files have being changed by other developers.
Figure 5 shows that another team member has checked in a new version of
home.jspx. At this stage it is not known if the changes are likely to
conflict with your working copy changes.

Figure 5. Incoming Changes Tab
Using this example, having seen that there are Incoming
changes you have a number of options:
- Update your code to this new version using Update or
Update Working Copy.
- If you choose this option then, provided there
are no conflicts, your code will be updated with these new changes. If
you are not working on home.jspx then this is the obvious course of
action.
- Manually check the differences between your working
copy and the newer version.
- To do this you can look at the History tab of
your working copy of home.jspx. Figure 6 shows that there are 2
differences. In the right hand pane is your editable working copy.
Choose any of the listed versions to display in the left hand pane. In
this example the latest repository version – 2766 has been
chosen. You can move the changes into your editable working copy from
this History tab.
- Select the Version History menu item from the
Versioning menu to review the different versions of the file.
- This is very similar to the History tab of the
file, but Version History is a read-only compare tool. Having perused
the differences, use Update Working Copy to get the changes into your
working copy. This can be used to compare the history of files that do
not have editors – such as the .jpr project and .jws
application files.

Figure 6. History tab of a file
Whether you use Update or manually review and add the
changes might depend on how many and how complex the changes are and
also how easy the source is to read. Another very important
consideration is the nature of the change. In many cases, especially if
you are using a framework such as Oracle’s Application
Development Framework (ADF) making the changes manually could be error
prone as there are dependencies between Java and their corresponding
XML metadata files. For this reason best practice is to use the Update
Working Copy mechanism to update code from the repository, whether you
have used the History to manually browse changes in advance or not. It
may be that you use the History tab to find changes and the author (see
Figure 6) and then communicate with the author if you are unsure of how
the changes affect your code.
An Alternative Approach
An alternative to the above is the lock-modify-unlock
model, in which a developer locks a file, modifies it, adds it back to
the repository, then unlocks it. Locking a file does not prevent
another developer from working on a copy of the file: it prevents the
content of that copy from being returned to the repository until the
lock is removed. So there is still potential for wasted effort in this
model.
The lock-modify-unlock model is more suitable for
working with files in binary formats, where it is impossible to merge
conflicting changes. It ensures that developers take it in strict turns
to submit changes to a file. JDeveloper provides support for the
Subversion property svn:needs-lock on a
file and for retaining locks on files that you are about to commit.
Resolving Conflicts
Conflicts arise when two files have identical entries
containing different content. JDeveloper’s Compare and Merge
tools are XML aware. This means that XML elements, properties and white
spaces are read and analysed when working to resolve avoid conflicts.
If the file is not XML then if two files have identical line positions
containing different content a conflict will arise. Through its merge
algorithms JDeveloper is able to resolve very many potential conflicts
but it is up to you to make final decisions on those conflicts that are
not resolveable.
If you don’t use the Compare tools prior to
doing a Commit of your working copy to the repository then you will
probably learn that one or more of your files has conflicts at Commit.
In this case, the commit is prohibited and, after you have Updated your
working copy or specific files from the repository, any files in
conflict will have duplicate copies in the application navigator (the
files represent the different versions of the file that are in
conflict. Select the Versioning -> Resolve Conflicts menu from
the file version with an exclamation point icon next to it to open the
Resolve Conflicts window. Figure 7 shows an example of this window. It
consists of three panes: The left pane shows your version of the file,
the right shows the repository version and the central pane shows the
resulting file once you resolve the conflicts. In this example the
right and left panes have been extended to show the content of those
panes. Notice that the file is an XML file and JDeveloper has
recognized that the same element, available in both versions of the
file, contains differences. In this case, the label property differs.

Figure 7. Merge Conflict Resolution Editor
Once you have resolved all the conflicts shown in the
file you can save and merge the resulting file using the Save and Merge
button at the top of the window. Now you are ready to Commit your
updated and conflict free files to the repository.
Branching
Branching is something that is seen as a requirement of
a source control system although in practice it might not be used as
extensively as you might think. The mechanics of branching are
‘simple’ but it is only as good as the process that
the development team uses. It requires developers to be vigilant in
what code they checkout, update and merge and to where. In Subversion a
branch is a copy of code that is maintained and versioned independently
but always remembers its ancestry. Your development process should
document exactly when and how branches are to be used. It may be that a
team is asked to work on a prototype that is not wanted on the main
development arm. Branching allows them to maintain this development
independently whilst also being able to update their code from the main
development as required and, at the end of the prototype, either
discard their code or merge it back into that main code line.
It may be that your branch code is a short term or a
long-term project. Whatever the case, it is always advisable to Update
from the main development line often if at some stage your branch will
be merged back into the main code line.
The steps to set up and work on a branch are simple but
care should be taken to understand what is happening at each stage of
the process. JDeveloper provides functionality to help with the
mechanics of following Subversion’s branching solution:
Create A Branch
In Subversion a branch is a copy of a code revision or a
working copy taken at a point in time. Figure 8 shows the Branch/Tag
dialog. You can create a branch from a Working Copy or from any
revision in the repository. In this example the HEAD Revision in the
repository is to be used as a branch. The working copy will be copied
to the repository location specified in the To URL . All the history of
the working copy (held in the From location in the repository) will
remain associated with the new branch.

Figure 8. Branch/Tag dialog
As well as the capability to Branch, Subversion also
provides a Tag option. These two options are identical. A Tag is
generally used to give a snapshot of code at a given point in time
whilst a branch is used for independent development. To preserve the
difference between a Tag and a Branch the Subversion repository
administrator tends to severely restrict the access and editing
capabilities given to any Tag directory
Working With A Branch
Once you have created a branch, whether from a working
copy or from a specific revision, you are likely to want to work on
your branch code and continue to make changes and commit that code. To
ensure that your working copy commits to the correct place in the
repository you use the Switch command. Figure 9 diagrams the steps of
creating and working with a branch from your working copy:
- Check out, edit and commit your working copy code to
the main development line
- Create myBranch from your working copy and switch to
myBranch (this ensures any subsequent commit/updates to your working
copy are done with the myBranch code line)
- Edit and commit your working copy that is now
switched to commit to myBranch
- As dictated by your development process, update your
branch code from the main code and resolve any conflicts
- Merge your working copy with all the changes from
myBranch. Then your working copy will reflect the merging of the latest
repository code and the myBranch code. Do this by specifying the first
and last revisions from myBranch that you want to merge.
- Resolve any irresolvable conflicts between main and
myBranch in the normal way
- At this point your working copy reflects the latest
merged code from the repository and your branch. The next step depends
on where you are in your development. You might:
a. Switch your branch back to myBranch and continue working and
committing changes to myBranch
b. Commit your working copy back into the main code so that all
developers now have the latest myBranch and main code available to them
c. Discard myBranch as it was a prototype and has served its purpose
and is never going to be added to the main development line
Figure 9. Typical branching scenario
Summary
JDeveloper and Subversion provide developers with an
integrated team development environment. This paper has demonstrated
the client side integration and best practices for using Subversion
with JDeveloper. It is outside the scope of this paper to discuss the
administration of the SVN Repository and such issues as connection
protocols.
|