You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2012/04/06 15:25:46 UTC

svn commit: r1310314 - in /lucene/dev/branches/branch_3x: dev-tools/scripts/smokeTestRelease.py solr/NOTICE.txt

Author: rmuir
Date: Fri Apr  6 13:25:46 2012
New Revision: 1310314

URL: http://svn.apache.org/viewvc?rev=1310314&view=rev
Log:
SOLR-3331: solr NOTICE.txt is missing information

Modified:
    lucene/dev/branches/branch_3x/dev-tools/scripts/smokeTestRelease.py
    lucene/dev/branches/branch_3x/solr/NOTICE.txt

Modified: lucene/dev/branches/branch_3x/dev-tools/scripts/smokeTestRelease.py
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/dev-tools/scripts/smokeTestRelease.py?rev=1310314&r1=1310313&r2=1310314&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/dev-tools/scripts/smokeTestRelease.py (original)
+++ lucene/dev/branches/branch_3x/dev-tools/scripts/smokeTestRelease.py Fri Apr  6 13:25:46 2012
@@ -14,6 +14,10 @@
 # limitations under the License.
 
 import os
+import tarfile
+import threading
+import subprocess
+import signal
 import shutil
 import hashlib
 import httplib
@@ -32,11 +36,42 @@ import checkJavaDocs
 # must have a working gpg, tar, unzip in your path.  This has been
 # tested on Linux and on Cygwin under Windows 7.
 
-# http://s.apache.org/lusolr32rc2
+def javaExe(version):
+  if version == '1.5':
+    path = JAVA5_HOME
+  elif version == '1.6':
+    path = JAVA6_HOME
+  elif version == '1.7':
+    path = JAVA7_HOME
+  else:
+    raise RuntimeError("unknown Java version '%s'" % version)
+  return 'export JAVA_HOME=%s PATH=%s/bin:$PATH' % (path, path)
 
-JAVA5_HOME = '/usr/local/jdk1.5.0_22'
-JAVA6_HOME = '/usr/local/jdk1.6.0_27'
-JAVA7_HOME = '/usr/local/jdk1.7.0_01'
+def verifyJavaVersion(version):
+  s = os.popen('%s; java -version 2>&1' % javaExe(version)).read()
+  if s.find('java version "%s.' % version) == -1:
+    raise RuntimeError('got wrong version for java %s:\n%s' % (version, s))
+
+# http://s.apache.org/lusolr32rc2
+env = os.environ
+try:
+  JAVA5_HOME = env['JAVA5_HOME']
+except KeyError:
+  JAVA5_HOME = '/usr/local/jdk1.5.0_22'
+
+try:
+  JAVA6_HOME = env['JAVA6_HOME']
+except KeyError:
+  JAVA6_HOME = '/usr/local/jdk1.6.0_27'
+
+try:
+  JAVA7_HOME = env['JAVA7_HOME']
+except KeyError:
+  JAVA7_HOME = '/usr/local/jdk1.7.0_01'
+
+verifyJavaVersion('1.5')
+verifyJavaVersion('1.6')
+verifyJavaVersion('1.7')
 
 # TODO
 #   + verify KEYS contains key that signed the release
@@ -165,6 +200,17 @@ def checkSigs(project, urlString, versio
   if keysURL is None:
     raise RuntimeError('%s is missing KEYS' % project)
 
+  if not os.path.exists('%s/apache-rat-0.8.jar' % tmpDir):
+    print '  downloading Apache RAT...'
+    download('apache-rat-incubating-0.8-bin.tar.bz2',
+             'http://archive.apache.org/dist/incubator/rat/binaries/apache-rat-incubating-0.8-bin.tar.bz2',
+             tmpDir)
+    t = tarfile.open('%s/apache-rat-incubating-0.8-bin.tar.bz2' % tmpDir)
+    t.extract('apache-rat-0.8/apache-rat-0.8.jar', '%s/apache-rat-0.8.jar' % tmpDir)
+  else:
+    print '  apache RAT already downloaded...'
+
+  print '  get KEYS'
   download('%s.KEYS' % project, keysURL, tmpDir)
 
   keysFile = '%s/%s.KEYS' % (tmpDir, project)
@@ -327,9 +373,9 @@ def unpack(project, tmpDir, artifact, ve
     raise RuntimeError('unpack produced entries %s; expected only %s' % (l, expected))
 
   unpackPath = '%s/%s' % (destDir, expected)
-  verifyUnpacked(project, artifact, unpackPath, version)
+  verifyUnpacked(project, artifact, unpackPath, version, tmpDir)
 
-def verifyUnpacked(project, artifact, unpackPath, version):
+def verifyUnpacked(project, artifact, unpackPath, version, tmpDir):
   os.chdir(unpackPath)
   isSrc = artifact.find('-src') != -1
   l = os.listdir(unpackPath)
@@ -376,53 +422,75 @@ def verifyUnpacked(project, artifact, un
       raise RuntimeError('%s: unexpected files/dirs in artifact %s: %s' % (project, artifact, l))
 
   if isSrc:
+    print '    make sure no JARs/WARs in src dist...'
+    lines = os.popen('find . -name \\*.jar').readlines()
+    if len(lines) != 0:
+      print '    FAILED:'
+      for line in lines:
+        print '      %s' % line.strip()
+      raise RuntimeError('source release has JARs...')
+    lines = os.popen('find . -name \\*.war').readlines()
+    if len(lines) != 0:
+      print '    FAILED:'
+      for line in lines:
+        print '      %s' % line.strip()
+      raise RuntimeError('source release has WARs...')
+
+    print '    run "ant validate"'
+    run('%s; ant validate' % javaExe('1.7'), '%s/validate.log' % unpackPath)
+
+    print '    run "ant rat-sources"'
+    run('%s; ant -lib %s/apache-rat-0.8.jar rat-sources' % (javaExe('1.7'), tmpDir), '%s/rat-sources.log' % unpackPath)
+    
     if project == 'lucene':
       print '    run tests w/ Java 5...'
-      run('export JAVA_HOME=%s; ant test' % JAVA5_HOME, '%s/test.log' % unpackPath)
-      run('export JAVA_HOME=%s; ant jar' % JAVA5_HOME, '%s/compile.log' % unpackPath)
+      run('%s; ant test' % javaExe('1.5'), '%s/test.log' % unpackPath)
+      run('%s; ant jar' % javaExe('1.5'), '%s/compile.log' % unpackPath)
       testDemo(isSrc, version)
       # test javadocs
       print '    generate javadocs w/ Java 5...'
-      run('export JAVA_HOME=%s; ant javadocs' % JAVA5_HOME, '%s/javadocs.log' % unpackPath)
-      # disabled: RM cannot fix all this, see LUCENE-3887
-      #if checkJavaDocs.checkPackageSummaries('build/docs/api'):
-      #  raise RuntimeError('javadoc summaries failed')
-      
+      run('%s; ant javadocs' % javaExe('1.5'), '%s/javadocs.log' % unpackPath)
+      if checkJavaDocs.checkPackageSummaries('build/docs/api'):
+        print '\n***WARNING***: javadocs want to fail!\n'
+        # disabled: RM cannot fix all this, see LUCENE-3887
+        #raise RuntimeError('javadoc summaries failed')
     else:
       print '    run tests w/ Java 6...'
-      run('export JAVA_HOME=%s; ant test' % JAVA6_HOME, '%s/test.log' % unpackPath)
+      run('%s; ant test' % javaExe('1.6'), '%s/test.log' % unpackPath)
 
       # test javadocs
       print '    generate javadocs w/ Java 6...'
-      # uncomment this after 3.5.0 and delete the hack below
-      # run('export JAVA_HOME=%s; ant javadocs' % JAVA6_HOME, '%s/javadocs.log' % unpackPath)
-      os.chdir('lucene')
-      run('export JAVA_HOME=%s; ant javadocs' % JAVA6_HOME, '%s/javadocs.log' % unpackPath)
-      os.chdir(unpackPath)
-
-      os.chdir('solr')
-      run('export JAVA_HOME=%s; ant javadocs' % JAVA6_HOME, '%s/javadocs.log' % unpackPath)
-      os.chdir(unpackPath)
-      # end hackidy-hack     
+      run('%s; ant javadocs' % javaExe('1.6'), '%s/javadocs.log' % unpackPath)
 
       print '    run tests w/ Java 7...'
-      run('export JAVA_HOME=%s; ant test' % JAVA7_HOME, '%s/test.log' % unpackPath)
+      run('%s; ant test' % javaExe('1.7'), '%s/test.log' % unpackPath)
  
       # test javadocs
       print '    generate javadocs w/ Java 7...'
-      # uncomment this after 3.5.0 and delete the hack below
-      # run('export JAVA_HOME=%s; ant javadocs' % JAVA7_HOME, '%s/javadocs.log' % unpackPath)
-      os.chdir('lucene')
-      run('export JAVA_HOME=%s; ant javadocs' % JAVA7_HOME, '%s/javadocs.log' % unpackPath)
-      os.chdir(unpackPath)
+      run('%s; ant javadocs' % javaExe('1.7'), '%s/javadocs.log' % unpackPath)
 
       os.chdir('solr')
-      run('export JAVA_HOME=%s; ant javadocs' % JAVA7_HOME, '%s/javadocs.log' % unpackPath)
-      os.chdir(unpackPath)
-      # end hackidy-hack   
+      print '    test solr example w/ Java 6...'
+      run('%s; ant clean example' % javaExe('1.6'), '%s/antexample.log' % unpackPath)
+      testSolrExample(unpackPath, JAVA6_HOME, True)
+
+      print '    test solr example w/ Java 7...'
+      run('%s; ant clean example' % javaExe('1.7'), '%s/antexample.log' % unpackPath)
+      testSolrExample(unpackPath, JAVA7_HOME, True)
+      os.chdir('..')
+
+      print '    check NOTICE'
+      testNotice(unpackPath)
+
   else:
     if project == 'lucene':
       testDemo(isSrc, version)
+    else:
+      print '    test solr example w/ Java 6...'
+      testSolrExample(unpackPath, JAVA6_HOME, False)
+
+      print '    test solr example w/ Java 7...'
+      testSolrExample(unpackPath, JAVA7_HOME, False)
 
   testChangesText('.', version, project)
 
@@ -430,6 +498,86 @@ def verifyUnpacked(project, artifact, un
     print '    check Lucene\'s javadoc JAR'
     unpackJavadocsJar('%s/lucene-core-%s-javadoc.jar' % (unpackPath, version), unpackPath)
 
+def testNotice(unpackPath):
+  solrNotice = open('%s/NOTICE.txt' % unpackPath).read()
+  luceneNotice = open('%s/lucene/NOTICE.txt' % unpackPath).read()
+
+  expected = """
+=========================================================================
+==  Apache Lucene Notice                                               ==
+=========================================================================
+
+""" + luceneNotice + """---
+"""
+  
+  if solrNotice.find(expected) == -1:
+    raise RuntimeError('Solr\'s NOTICE.txt does not have the verbatim copy, plus header/footer, of Lucene\'s NOTICE.txt')
+  
+def readSolrOutput(p, startupEvent, logFile):
+  f = open(logFile, 'wb')
+  try:
+    while True:
+      line = p.readline()
+      if line == '':
+        break
+      f.write(line)
+      f.flush()
+      # print 'SOLR: %s' % line.strip()
+      if line.find('Started SocketConnector@0.0.0.0:8983') != -1:
+        startupEvent.set()
+  finally:
+    f.close()
+    
+def testSolrExample(unpackPath, javaPath, isSrc):
+  logFile = '%s/solr-example.log' % unpackPath
+  os.chdir('example')
+  print '      start Solr instance (log=%s)...' % logFile
+  env = {}
+  env.update(os.environ)
+  env['JAVA_HOME'] = javaPath
+  env['PATH'] = '%s/bin:%s' % (javaPath, env['PATH'])
+  server = subprocess.Popen(['java', '-jar', 'start.jar'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
+
+  startupEvent = threading.Event()
+  serverThread = threading.Thread(target=readSolrOutput, args=(server.stderr, startupEvent, logFile))
+  serverThread.setDaemon(True)
+  serverThread.start()
+
+  # Make sure Solr finishes startup:
+  startupEvent.wait()
+  print '      startup done'
+  
+  try:
+    print '      test utf8...'
+    run('sh ./exampledocs/test_utf8.sh', 'utf8.log')
+    print '      index example docs...'
+    run('sh ./exampledocs/post.sh ./exampledocs/*.xml', 'post-example-docs.log')
+    print '      run query...'
+    s = urllib2.urlopen('http://localhost:8983/solr/select/?q=video').read()
+    if s.find('<result name="response" numFound="3" start="0">') == -1:
+      print 'FAILED: response is:\n%s' % s
+      raise RuntimeError('query on solr example instance failed')
+  finally:
+    # Stop server:
+    print '      stop server (SIGINT)...'
+    os.kill(server.pid, signal.SIGINT)
+
+    # Give it 10 seconds to gracefully shut down
+    serverThread.join(10.0)
+
+    if serverThread.isAlive():
+      # Kill server:
+      print '***WARNING***: Solr instance didn\'t respond to SIGINT; using SIGKILL now...'
+      os.kill(server.pid, signal.SIGKILL)
+
+      serverThread.join(10.0)
+
+      if serverThread.isAlive():
+        # Shouldn't happen unless something is seriously wrong...
+        print '***WARNING***: Solr instance didn\'t respond to SIGKILL; ignoring...'
+
+  os.chdir('..')
+    
 def unpackJavadocsJar(jarPath, unpackPath):
   destDir = '%s/javadocs' % unpackPath
   if os.path.exists(destDir):
@@ -437,9 +585,10 @@ def unpackJavadocsJar(jarPath, unpackPat
   os.makedirs(destDir)
   os.chdir(destDir)
   run('unzip %s' % jarPath, '%s/unzip.log' % destDir)
-  # disabled: RM cannot fix all this, see LUCENE-3887
-  #if checkJavaDocs.checkPackageSummaries('.'):
-  #  raise RuntimeError('javadoc problems')
+  if checkJavaDocs.checkPackageSummaries('.'):
+    # disabled: RM cannot fix all this, see LUCENE-3887
+    # raise RuntimeError('javadoc problems')
+    print '\n***WARNING***: javadocs want to fail!\n'
   os.chdir(unpackPath)
 
 def testDemo(isSrc, version):
@@ -456,8 +605,8 @@ def testDemo(isSrc, version):
   else:
     cp = 'lucene-core-{0}.jar{1}contrib/demo/lucene-demo-{0}.jar'.format(version, sep)
     docsDir = 'docs'
-  run('export JAVA_HOME=%s; %s/bin/java -cp "%s" org.apache.lucene.demo.IndexFiles -index index -docs %s' % (JAVA5_HOME, JAVA5_HOME, cp, docsDir), 'index.log')
-  run('export JAVA_HOME=%s; %s/bin/java -cp "%s" org.apache.lucene.demo.SearchFiles -index index -query lucene' % (JAVA5_HOME, JAVA5_HOME, cp), 'search.log')
+  run('%s; java -cp "%s" org.apache.lucene.demo.IndexFiles -index index -docs %s' % (javaExe('1.5'), cp, docsDir), 'index.log')
+  run('%s; java -cp "%s" org.apache.lucene.demo.SearchFiles -index index -query lucene' % (javaExe('1.5'), cp), 'search.log')
   reMatchingDocs = re.compile('(\d+) total matching documents')
   m = reMatchingDocs.search(open('search.log', 'rb').read())
   if m is None:
@@ -862,6 +1011,8 @@ def main():
   if not DEBUG:
     if os.path.exists(tmpDir):
       raise RuntimeError('temp dir %s exists; please remove first' % tmpDir)
+
+  if not os.path.exists(tmpDir):
     os.makedirs(tmpDir)
   
   lucenePath = None

Modified: lucene/dev/branches/branch_3x/solr/NOTICE.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/NOTICE.txt?rev=1310314&r1=1310313&r2=1310314&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/NOTICE.txt (original)
+++ lucene/dev/branches/branch_3x/solr/NOTICE.txt Fri Apr  6 13:25:46 2012
@@ -41,34 +41,11 @@ License: The BSD License (http://www.ope
 ==  Apache Lucene Notice                                               ==
 =========================================================================
 
-ICU4J, (under contrib/icu) is licensed under an MIT styles license
-(contrib/icu/lib/ICU-LICENSE.txt) and Copyright (c) 1995-2008 
-International Business Machines Corporation and others
-
-Some data files (under contrib/icu/src/data) are derived from Unicode data such
-as the Unicode Character Database. See http://unicode.org/copyright.html for more
-details.
-
-The class org.apache.lucene.SorterTemplate was inspired by CGLIB's class with
-the same name. The implementation part is mainly done using pre-existing
-Lucene sorting code. In-place stable mergesort was borrowed from CGLIB,
-which is Apache-licensed.
-
-The class org.apache.lucene.util.WeakIdentityMap was derived from
-the Apache CXF project and is Apache License 2.0.
+Apache Lucene
+Copyright 2012 The Apache Software Foundation
 
-The Google Code Prettify is Apache License 2.0.
-See http://code.google.com/p/google-code-prettify/
-
-JUnit (junit-4.10) is licensed under the Common Public License v. 1.0
-See http://junit.sourceforge.net/cpl-v10.html
-
-Includes software from other Apache Software Foundation projects,
-including, but not limited to:
- - Apache Ant
- - Apache Jakarta Regexp
- - Commons Compress
- - Xerces
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
 
 The snowball stemmers in
   contrib/analyzers/common/src/java/net/sf/snowball
@@ -84,7 +61,7 @@ The KStem stemmer in
 was developed by Bob Krovetz and Sergio Guzman-Lara (CIIR-UMass Amherst)
 under the BSD-license.
 
-The Arabic,Persian,Romanian,Bulgarian, and Hindi analyzers (common) come with a default
+The Arabic,Persian,Romanian,Bulgarian, and Hindi analyzers (contrib/analyzers) come with a default
 stopword list that is BSD-licensed created by Jacques Savoy.  These files reside in:
 contrib/analyzers/common/src/resources/org/apache/lucene/analysis/ar/stopwords.txt,
 contrib/analyzers/common/src/resources/org/apache/lucene/analysis/fa/stopwords.txt,
@@ -108,21 +85,133 @@ contrib/analyzers/common/src/java/org/ap
 contrib/analyzers/common/src/java/org/apache/lucene/analysis/ru/RussianLightStemmer.java
 contrib/analyzers/common/src/java/org/apache/lucene/analysis/sv/SwedishLightStemmer.java
 
-The Stempel analyzer (stempel) includes BSD-licensed software developed 
+The Stempel analyzer (contrib/analyzers) includes BSD-licensed software developed 
 by the Egothor project http://egothor.sf.net/, created by Leo Galambos, Martin Kvapil,
 and Edmond Nolan.
 
-The Polish analyzer (stempel) comes with a default
+The Polish analyzer (contrib/analyzers) comes with a default
 stopword list that is BSD-licensed created by the Carrot2 project. The file resides
 in contrib/analyzers/stempel/src/resources/org/apache/lucene/analysis/pl/stopwords.txt.
 See http://project.carrot2.org/license.html.
 
-The SmartChineseAnalyzer source code (smartcn) was
+Includes software from other Apache Software Foundation projects,
+including, but not limited to:
+ - Apache Ant
+ - Apache Jakarta Regexp
+ - Commons Compress
+ - Xerces
+
+The SmartChineseAnalyzer source code (under contrib/analyzers) was
 provided by Xiaoping Gao and copyright 2009 by www.imdict.net.
 
-WordBreakTestUnicode_*.java (under src/test/) 
-is derived from Unicode data such as the Unicode Character Database. 
-See http://unicode.org/copyright.html for more details.
+ICU4J, (under contrib/icu) is licensed under an MIT styles license
+(contrib/icu/lib/ICU-LICENSE.txt) and Copyright (c) 1995-2008 
+International Business Machines Corporation and others
+
+Some files (contrib/analyzers/common/src/test/.../WordBreakTestUnicode_*.java
+and data files under contrib/icu/src/data/) are derived from Unicode data such
+as the Unicode Character Database. See http://unicode.org/copyright.html for more
+details.
+
+The class org.apache.lucene.SorterTemplate was inspired by CGLIB's class with
+the same name. The implementation part is mainly done using pre-existing
+Lucene sorting code. In-place stable mergesort was borrowed from CGLIB,
+which is Apache-licensed.
+
+The class org.apache.lucene.util.WeakIdentityMap was derived from
+the Apache CXF project and is Apache License 2.0.
+
+The Google Code Prettify is Apache License 2.0.
+See http://code.google.com/p/google-code-prettify/
+
+JUnit (junit-4.10) is licensed under the Common Public License v. 1.0
+See http://junit.sourceforge.net/cpl-v10.html
+
+This product includes code (JaspellTernarySearchTrie) from Java Spelling Checking Package (jaspell): http://jaspell.sourceforge.net/
+License: The BSD License (http://www.opensource.org/licenses/bsd-license.php)
+
+===========================================================================
+Kuromoji Japanese Morphological Analyzer - Apache Lucene Integration
+===========================================================================
+
+This software includes a binary and/or source version of data from
+
+  mecab-ipadic-2.7.0-20070801
+
+which can be obtained from
+
+  http://atilika.com/releases/mecab-ipadic/mecab-ipadic-2.7.0-20070801.tar.gz
+
+or
+
+  http://jaist.dl.sourceforge.net/project/mecab/mecab-ipadic/2.7.0-20070801/mecab-ipadic-2.7.0-20070801.tar.gz
+
+===========================================================================
+mecab-ipadic-2.7.0-20070801 Notice
+===========================================================================
+
+Nara Institute of Science and Technology (NAIST),
+the copyright holders, disclaims all warranties with regard to this
+software, including all implied warranties of merchantability and
+fitness, in no event shall NAIST be liable for
+any special, indirect or consequential damages or any damages
+whatsoever resulting from loss of use, data or profits, whether in an
+action of contract, negligence or other tortuous action, arising out
+of or in connection with the use or performance of this software.
+
+A large portion of the dictionary entries
+originate from ICOT Free Software.  The following conditions for ICOT
+Free Software applies to the current dictionary as well.
+
+Each User may also freely distribute the Program, whether in its
+original form or modified, to any third party or parties, PROVIDED
+that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear
+on, or be attached to, the Program, which is distributed substantially
+in the same form as set out herein and that such intended
+distribution, if actually made, will neither violate or otherwise
+contravene any of the laws and regulations of the countries having
+jurisdiction over the User or the intended distribution itself.
+
+NO WARRANTY
+
+The program was produced on an experimental basis in the course of the
+research and development conducted during the project and is provided
+to users as so produced on an experimental basis.  Accordingly, the
+program is provided without any warranty whatsoever, whether express,
+implied, statutory or otherwise.  The term "warranty" used herein
+includes, but is not limited to, any warranty of the quality,
+performance, merchantability and fitness for a particular purpose of
+the program and the nonexistence of any infringement or violation of
+any right of any third party.
+
+Each user of the program will agree and understand, and be deemed to
+have agreed and understood, that there is no warranty whatsoever for
+the program and, accordingly, the entire risk arising from or
+otherwise connected with the program is assumed by the user.
+
+Therefore, neither ICOT, the copyright holder, or any other
+organization that participated in or was otherwise related to the
+development of the program and their respective officials, directors,
+officers and other employees shall be held liable for any and all
+damages, including, without limitation, general, special, incidental
+and consequential damages, arising out of or otherwise in connection
+with the use or inability to use the program or any product, material
+or result produced or otherwise obtained by using the program,
+regardless of whether they have been advised of, or otherwise had
+knowledge of, the possibility of such damages at any time during the
+project or thereafter.  Each user will be deemed to have agreed to the
+foregoing by his or her commencement of use of the program.  The term
+"use" as used herein includes, but is not limited to, the use,
+modification, copying and distribution of the program and the
+production of secondary products from the program.
+
+In the case where the program, whether in its original form or
+modified, was distributed or delivered to or received by a user from
+any person, organization or entity other than ICOT, unless it makes or
+grants independently of ICOT any specific warranty to the user in
+writing, such person, organization or entity, will also be exempted
+from and not be held liable to the user for any such damages as noted
+above as far as the program is concerned.
 ---
 
 This product includes/uses software, Woodstox (http://woodstox.codehaus.org),