Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to you under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

 
                     Building OpenJPA
===============================================================================

These instructions describe how to build OpenJPA from source code using the
Apache Maven 2 build too. They are written for use from the console, and are 
known to work on Linux and Mac OSX. They are also reported to work from Windows.

The most up to date version of these instructions may be found on the OpenJPA 
website at http://openjpa.apache.org/building-openjpa.html

   1. Ensure that you have Java 1.5 installed and in your path by running:
      java -version
      OpenJPA requires Java 1.5 but will not compile with Java 6. For more
      detail please see http://issues.apache.org/jira/browse/OPENJPA-5.
   2. Install the build tool Apache Maven 2.0.6, from http://maven.apache.org/.
      If it is installed correctly, typing mvn -v from the console will result
      in the text "Maven version: 2.0.6"
   3. Extract the source archive if you have not already done so. 
      The source will create a new directory named:
      openjpa-<version>-source. Where <version> is the openjpa 
      version, for example apache-openjpa-1.1.0-source.
   4. Change to the openjpa source directory, which has already been created in
      the previous step.
   5. Build OpenJPA by running: mvn package or better mvn install. 
      The first time you run the build, many dependencies are automatically 
      resolved and downloaded. It is common for dependency downloading to fail
      the first time, which will fail the build. If any of these dependency 
      downloads fail, just re-run the command. You may also add the following 
      to your ~/.m2/setting.xml file
      (see http://maven.apache.org/guides/mini/guide-mirror-settings.html)

       <settings>
           <mirrors>
               <mirror>
                   <id>repo.mergere.com</id>
                   <url>http://repo.mergere.com/maven2</url>
                   <mirrorOf>central</mirrorOf>
                   </mirror>
           </mirrors>
        </settings>

        If any tests fail, and you want to ignore the failures, instead run:
        mvn package -DskipTests

An example session as as follows:

$ cd /tmp/

$ java -version

java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112)
Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing)

$ mvn -v

Maven version: 2.0.4

$ svn --version

svn, version 1.1.4 (r13838)
   compiled Jul 10 2006, 22:17:43

$ svn co https://svn.apache.org/repos/asf/openjpa/trunk/

A  trunk/openjpa-lib
A  trunk/openjpa-lib/src
A  trunk/openjpa-lib/src/test
A  trunk/openjpa-lib/src/test/java
A  trunk/openjpa-lib/src/test/java/org
A  trunk/openjpa-lib/src/test/java/org/apache
A  trunk/openjpa-lib/src/test/java/org/apache/openjpa
A  trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib
A  trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/test
A  trunk/openjpa-lib/src/test/java/org/apache/openjpa/lib/test/AbstractTestCase.
java

 ...

A  trunk/openjpa-persistence/pom.xml
Checked out revision 421381.

$ cd trunk/

$ mvn compile

[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   OpenJPA
[INFO]   Utilities
[INFO]   Kernel
[INFO]   JDBC
[INFO]   XML Store
[INFO]   JDBC 1.5
[INFO]   Kernel 1.5
[INFO]   JPA
[INFO]   JPA JDBC
[INFO]   OpenJPA Project
[INFO] -------------------------------------------------------------------------
[INFO] Building OpenJPA
[INFO]    task-segment: [compile]
[INFO] -------------------------------------------------------------------------

 ...

[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] OpenJPA ............................................... SUCCESS [0.789s]
[INFO] Utilities ............................................. SUCCESS [3.489s]
[INFO] Kernel ................................................ SUCCESS [9.347s]
[INFO] JDBC .................................................. SUCCESS [12.208s]
[INFO] XML Store ............................................. SUCCESS [1.166s]
[INFO] JDBC 1.5 .............................................. SUCCESS [1.519s]
[INFO] Kernel 1.5 ............................................ SUCCESS [0.538s]
[INFO] JPA ................................................... SUCCESS [2.777s]
[INFO] JPA JDBC .............................................. SUCCESS [2.151s]
[INFO] OpenJPA Project ....................................... SUCCESS [1.495s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 37 seconds
[INFO] Finished at: Wed Jul 26 11:44:33 PDT 2006
[INFO] Final Memory: 10M/41M
[INFO] ------------------------------------------------------------------------


$ mvn package -Dtest=false

[INFO] Scanning for projects...

...

[INFO] [assembly:assembly {execution: bin}]
[INFO] Building zip: /tmp/openjpatestbuild/trunk/openjpa-project/target/filtered
-site/resources/downloads/openjpa-0.9.0.zip

... 


$ ls -lh openjpa-project/target/filtered-site/resources/downloads/

total 9.2M
-rw-r--r--    1 mprudhom wheel       4.0M Jul 26 11:46 openjpa-0.9.0-sources.zip
-rw-r--r--    1 mprudhom wheel       5.2M Jul 26 11:46 openjpa-0.9.0.zip

 
