[med-svn] [Git][med-team/rdp-readseq][master] 3 commits: d/p/random-access-file.patch: aggregate RandomAccessFile to resolve Java 25...

Andreas Tille (@tille) gitlab at salsa.debian.org
Wed Feb 25 06:44:02 GMT 2026



Andreas Tille pushed to branch master at Debian Med / rdp-readseq


Commits:
81efc13d by Vladimir Petko at 2026-02-25T19:13:53+13:00
d/p/random-access-file.patch: aggregate RandomAccessFile to resolve Java 25 ftbfs (Closes: #1128172).

- - - - -
3e97a913 by Vladimir Petko at 2026-02-25T19:13:57+13:00
changelog

- - - - -
cc586538 by Andreas Tille at 2026-02-25T07:43:50+01:00
Merge branch 'master' into 'master'

Resolve Java 25 ftbfs

See merge request med-team/rdp-readseq!1
- - - - -


3 changed files:

- debian/changelog
- + debian/patches/random-access-file.patch
- + debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,9 +1,14 @@
 rdp-readseq (2.0.2-10) UNRELEASED; urgency=medium
 
+  [ Andreas Tille ]
   * Remove Tim Booth <tbooth at ceh.ac.uk> since address is bouncing
     (Thank you for your work on this package, Tim)
 
- -- Andreas Tille <tille at debian.org>  Mon, 16 Sep 2024 10:13:22 +0200
+  [ Vladimir Petko ]
+  * d/p/random-access-file.patch: aggregate RandomAccessFile to resolve
+    Java 25 ftbfs (Closes: #1128172).
+
+ -- Vladimir Petko <vladimir.petko at canonical.com>  Wed, 25 Feb 2026 18:27:22 +1300
 
 rdp-readseq (2.0.2-9) unstable; urgency=medium
 


=====================================
debian/patches/random-access-file.patch
=====================================
@@ -0,0 +1,603 @@
+Description: Reimplement BufferedRandomAccessFile
+ Original implementation partially overriden RandomAccessFile methods.
+ This patch provides a replacement implementation that aggregates
+ RandomAccessFile and uses the same serialization logic.
+ This resolves the dependency on RandomAccessFile implementation
+ details.
+ The write methods and logic were removed as they are not used in the
+ main code.
+Author: Vladimir Petko <vladimir.petko at canonical.com>
+Bug: https://github.com/rdpstaff/ReadSeq/issues/4
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1128172
+Last-Update: 2026-02-25
+
+--- a/src/edu/msu/cme/rdp/readseq/utils/BufferedRandomAccessFile.java
++++ b/src/edu/msu/cme/rdp/readseq/utils/BufferedRandomAccessFile.java
+@@ -16,177 +16,239 @@
+  */
+ package edu.msu.cme.rdp.readseq.utils;
+ 
+-import java.io.File;
+-import java.io.IOException;
+-import java.io.RandomAccessFile;
++import java.io.*;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.VarHandle;
++import java.nio.ByteOrder;
+ 
+ /**
+- *
+- * @author fishjord
++ * The buffered wrapper around RandomAccessFile.
++ * Original implementation inherited RandomAccessFile and relied on
++ * partially overriding its methods.
++ * This implementation aggregates RandomAccessFile and implements DataInput
++ * using the same serialization logic as RandomAccessFile.
+  */
+-public class BufferedRandomAccessFile extends RandomAccessFile {
++public class BufferedRandomAccessFile implements DataInput {
+ 
+-    private byte[] buf;
+-    private long realPos;
+-    private int bufPos;
+-    private int bufEnd;
+-    private boolean sync = false;
++    private final RandomAccessFile raf;
++    private final byte[] buffer;
++    private long bufferStart;
++    private int bufferLimit;
++    private int bufferPos;
++    private final Converter converter = new Converter();
+ 
+-    public BufferedRandomAccessFile(File f, String mode, int bufSize) throws IOException {
+-        super(f, mode);
+-        buf = new byte[bufSize];
+-        fillBuffer();
+-    }
++    // the code is copied from jdk.internal.util.ByteAray
++    private static class Converter {
++        private static final VarHandle INT = create(int[].class);
++        private static final VarHandle LONG = create(long[].class);
++        private final byte[] buffer = new byte[8];
+ 
+-    @Override
+-    public int skipBytes(int n) throws IOException{
+-        return super.skipBytes(n);
++        private static VarHandle create(Class<?> viewArrayClass) {
++            return MethodHandles.byteArrayViewVarHandle(viewArrayClass, ByteOrder.BIG_ENDIAN);
++        }
++
++        public int getInt(BufferedRandomAccessFile f) throws IOException {
++            f.readFully(this.buffer, 0, 4);
++            return (int) INT.get(this.buffer, 0);
++        }
++
++        public long getLong(BufferedRandomAccessFile f) throws IOException {
++            f.readFully(this.buffer, 0, 8);
++            return (long) LONG.get(this.buffer, 0);
++        }
+     }
+ 
+-    @Override
+-    public final int read() throws IOException {
+-        if (bufPos >= bufEnd) {
+-            if (fillBuffer() < 0) {
+-                return -1;
+-            }
++    public BufferedRandomAccessFile(File name, int bufferSize) throws IOException {
++        if (bufferSize <= 0) {
++            throw new IllegalArgumentException("bufferSize must be > 0, got: " + bufferSize);
+         }
++        this.raf = new RandomAccessFile(name, "r");
++        this.buffer = new byte[bufferSize];
++        this.bufferStart = 0;
++        this.bufferLimit = 0;
++        this.bufferPos = 0;
++    }
+ 
+-        if (bufEnd == 0) {
+-            return -1;
++
++    public void seek(long pos) throws IOException {
++        if (pos >= bufferStart && pos < bufferStart + bufferLimit) {
++            bufferPos = (int) (pos - bufferStart);
+         } else {
+-            return buf[bufPos++] & 0xff;
++            raf.seek(pos);
++            bufferStart = pos;
++            bufferLimit = 0;
++            bufferPos = 0;
+         }
+     }
+ 
+-    @Override
+-    public int read(byte b[]) throws IOException {
+-        return read(b, 0, b.length);
++    public long getFilePointer() throws IOException {
++        return bufferStart + bufferPos;
+     }
+ 
+-    @Override
+-    public int read(byte b[], int off, int len) throws IOException {
+-        int readCount = 0;
+-        for(int index = off;index < len;index++) {
+-            int r = this.read();
+-            if(r == -1) {
++    public long length() throws IOException {
++        return raf.length();
++    }
++
++    public void close() throws IOException {
++        raf.close();
++    }
++
++    private boolean ensureData() throws IOException {
++        if (bufferPos < bufferLimit) {
++            return true;
++        }
++        long nextFilePos = bufferStart + bufferLimit;
++        raf.seek(nextFilePos);
++        int n = raf.read(buffer);
++        if (n <= 0) {
++            return false;
++        }
++        bufferStart = nextFilePos;
++        bufferLimit = n;
++        bufferPos = 0;
++        return true;
++    }
++
++    private int readBytes(byte[] dest, int off, int len) throws IOException {
++        int remaining = len;
++        int destOff = off;
++        while (remaining > 0) {
++            if (!ensureData()) {
+                 break;
+             }
+-
+-            readCount++;
+-            b[index] = (byte)r;
++            int available = bufferLimit - bufferPos;
++            int toCopy = Math.min(available, remaining);
++            System.arraycopy(buffer, bufferPos, dest, destOff, toCopy);
++            bufferPos += toCopy;
++            destOff += toCopy;
++            remaining -= toCopy;
+         }
+-        return readCount;
++        return len - remaining;
+     }
+ 
+     @Override
+-    public final void write(int b) throws IOException {
+-        if (bufPos >= buf.length) {
+-            fillBuffer();
++    public void readFully(byte[] b) throws IOException {
++        if (readBytes(b, 0, b.length) != b.length) {
++            throw new EOFException("Could not read fully into buffer");
+         }
++    }
+ 
+-        buf[bufPos++] = (byte) b;
+-        if (bufPos >= bufEnd) {
+-            bufEnd = bufPos;
++    @Override
++    public void readFully(byte[] b, int off, int len) throws IOException {
++        if (off < 0 || len < 0 || off + len > b.length) {
++            throw new IndexOutOfBoundsException();
+         }
++        if (readBytes(b, off, len) != len) {
++            throw new EOFException("Could not read fully into buffer");
++        }
++    }
+ 
+-        sync = true;
++    @Override
++    public int skipBytes(int n) throws IOException {
++        if (n <= 0)
++            return 0;
++        long current = getFilePointer();
++        long fileLen = raf.length();
++        long skip = Math.min(n, fileLen - current);
++        if (skip > 0) {
++            seek(current + skip);
++        }
++        return (int) skip;
+     }
+ 
+     @Override
+-    public long getFilePointer() throws IOException {
+-        long l = realPos;
+-        return (l - bufEnd + bufPos);
++    public boolean readBoolean() throws IOException {
++        return read() != 0;
+     }
+ 
+     @Override
+-    public void seek(long pos) throws IOException {
+-        int n = (int) (realPos - pos);
++    public byte readByte() throws IOException {
++        return (byte) read();
++    }
++
++    public int read() throws IOException {
++        if (!ensureData()) {
++            return -1;
++        }
++        return buffer[bufferPos++] & 0xFF;
++    }
++
++    public int read(byte[] buf) throws IOException {
++        return readBytes(buf, 0, buf.length);
++    }
+ 
+-        if (n >= 0 && n <= bufEnd) {
+-            bufPos = bufEnd - n;
++    @Override
++    public int readUnsignedByte() throws IOException {
++        int ch = this.read();
++        if (ch < 0) {
++            throw new EOFException();
+         } else {
+-            sync();
+-            super.seek(pos);
+-            invalidate();
++            return ch;
+         }
+     }
+ 
+     @Override
+-    public void write(byte[] b) throws IOException {
+-        throw new UnsupportedOperationException();
++    public short readShort() throws IOException {
++        return (short)this.readUnsignedShort();
+     }
+ 
+     @Override
+-    public void write(byte b[], int off, int len) throws IOException {
+-        throw new UnsupportedOperationException();
++    public int readUnsignedShort() throws IOException {
++        this.readFully(this.buffer, 0, 2);
++        return (this.buffer[1] & 255) + ((this.buffer[0] & 255) << 8);
+     }
+ 
+     @Override
+-    public void close() throws IOException {
+-        sync();
+-        super.close();
++    public char readChar() throws IOException {
++        return (char) readUnsignedShort();
+     }
+ 
+-    private void sync() throws IOException {
+-        if (sync) {
+-            super.seek(realPos - bufEnd);
+-            super.write(buf, 0, bufEnd);
+-            sync = false;
+-            //invalidate();
+-        }
++    @Override
++    public int readInt() throws IOException {
++        return converter.getInt(this);
+     }
+ 
+-    private int fillBuffer() throws IOException {
+-        sync();
++    @Override
++    public long readLong() throws IOException {
++        return converter.getLong(this);
++    }
+ 
+-        int n = super.read(buf, 0, buf.length);
+-        if (n >= 0) {
+-            //System.out.println("Filling buffer...read in " + n + " bytes");
+-            realPos += n;
+-            bufEnd = n;
+-            bufPos = 0;
+-        }
+-        return n;
++    @Override
++    public float readFloat() throws IOException {
++        return Float.intBitsToFloat(readInt());
+     }
+ 
+-    private void invalidate() throws IOException {
+-        bufEnd = 0;
+-        bufPos = 0;
+-        realPos = super.getFilePointer();
++    @Override
++    public double readDouble() throws IOException {
++        return Double.longBitsToDouble(readLong());
+     }
+ 
+-    public static void main(String[] args) throws Exception {
++    @Override
++    public String readLine() throws IOException {
++        StringBuilder sb = new StringBuilder();
++        int c;
+         try {
+-            File file = new File("tmp.bin");
+-            if (file.exists()) {
+-                file.delete();
++            c = read();
++        } catch (EOFException e) {
++            return null;
++        }
++        while (c != '\n' && c != -1) {
++            if (c != '\r') {
++                sb.append((char) c);
++            }
++            try {
++                c = read();
++            } catch (EOFException e) {
++                break;
+             }
+-
+-            BufferedRandomAccessFile f = new BufferedRandomAccessFile(file, "rw", 1);
+-
+-            f.writeInt(1);
+-            f.writeInt(2);
+-            f.writeInt(3);
+-            f.writeInt(4);
+-            f.writeInt(5);
+-
+-            f.seek(0);
+-
+-            System.out.println(f.readInt());
+-            System.out.println(f.readInt());
+-            f.writeInt(6);
+-            System.out.println(f.readInt());
+-            System.out.println(f.readInt());
+-
+-            f.seek(0);
+-
+-            System.out.println(f.readInt());
+-            System.out.println(f.readInt());
+-            System.out.println(f.readInt());
+-            System.out.println(f.readInt());
+-            System.out.println(f.readInt());
+-            f.close();
+-        } catch (Exception e) {
+         }
++        if (sb.isEmpty() && c == -1)
++            return null;
++        return sb.toString();
++    }
++
++    @Override
++    public String readUTF() throws IOException {
++        return DataInputStream.readUTF(this);
+     }
+ }
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/SeqReaderCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/SeqReaderCore.java
+@@ -56,11 +56,11 @@
+         }
+     }
+     private boolean seekable;
+-    private RandomAccessFile rawRAFile = null;
++    private BufferedRandomAccessFile rawRAFile = null;
+     private DataInputStream is = null;
+ 
+     public SeqReaderCore(File seqFile) throws IOException {
+-        this.rawRAFile = new BufferedRandomAccessFile(seqFile, "r", 4096);
++        this.rawRAFile = new BufferedRandomAccessFile(seqFile, 4096);
+         seekable = true;
+     }
+ 
+@@ -69,7 +69,7 @@
+         seekable = false;
+     }
+ 
+-    protected final RandomAccessFile getRawFile() throws IOException {
++    protected final BufferedRandomAccessFile getRawFile() throws IOException {
+         if (!seekable) {
+             throw new IOException("Stream seq cores are not seekable");
+         }
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/STKCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/STKCore.java
+@@ -17,6 +17,8 @@
+ package edu.msu.cme.rdp.readseq.readers.core;
+ 
+ import edu.msu.cme.rdp.readseq.readers.Sequence;
++import edu.msu.cme.rdp.readseq.utils.BufferedRandomAccessFile;
++
+ import java.io.File;
+ import java.io.IOException;
+ import java.io.RandomAccessFile;
+@@ -37,7 +39,7 @@
+ 
+     public STKCore(File f) throws IOException {
+         super(f);
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         long firstSeqStart = -1;
+ 
+@@ -103,7 +105,7 @@
+ 
+                 seqid = sid.toString();
+             }
+-            
++
+             if (firstSeqStart == -1) {
+                 firstSeqStart = currSeqIndex;
+             }
+@@ -130,8 +132,8 @@
+ 
+     @Override
+     public Sequence readNextSeq() throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
+-        
++        BufferedRandomAccessFile seqFile = super.getRawFile();
++
+         long seqStart = seqFile.getFilePointer();
+ 
+         String line = seqFile.readLine().trim();
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/EMBLCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/EMBLCore.java
+@@ -19,6 +19,8 @@
+ import edu.msu.cme.rdp.readseq.readers.Sequence;
+ import edu.msu.cme.rdp.readseq.SequenceFormat;
+ import edu.msu.cme.rdp.readseq.sequences.GenbankSequence;
++import edu.msu.cme.rdp.readseq.utils.BufferedRandomAccessFile;
++
+ import java.io.DataOutputStream;
+ import java.io.File;
+ import java.io.IOException;
+@@ -45,7 +47,7 @@
+     }
+ 
+     public Map<String, Long> scanInternal() throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         long firstHeader = seqFile.getFilePointer();
+@@ -68,7 +70,7 @@
+     }
+ 
+     public int scanToStream(DataOutputStream out) throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         long firstHeader = seqFile.getFilePointer();
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/SFFCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/SFFCore.java
+@@ -17,6 +17,7 @@
+ package edu.msu.cme.rdp.readseq.readers.core;
+ 
+ import edu.msu.cme.rdp.readseq.QSequence;
++import edu.msu.cme.rdp.readseq.utils.BufferedRandomAccessFile;
+ import edu.msu.cme.rdp.readseq.utils.SeqUtils;
+ import java.io.ByteArrayInputStream;
+ import java.io.DataInput;
+@@ -238,7 +239,7 @@
+             return readIndex();
+         }
+ 
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(commonHeader.headerLength);
+         LinkedHashMap<String, Long> seqIndex = new LinkedHashMap(commonHeader.numReads);
+@@ -270,9 +271,9 @@
+             clipRight = readBlock.clipQualRight;
+         }
+         if (clipLeft  > clipRight )
+-           return readNextSeq(); 
++           return readNextSeq();
+         String seq = readBlock.seq.substring(clipLeft - 1, clipRight);
+-        
++
+ 
+         return new QSequence(readBlock.name, "", seq, Arrays.copyOfRange(readBlock.qual, clipLeft - 1, clipRight));
+     }
+@@ -354,7 +355,7 @@
+             throw new IOException("Index offset is not set correctly");
+         }
+ 
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         long seekBackTo = seqFile.getFilePointer();
+         seqFile.seek(commonHeader.indexOffset);
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/FastaCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/FastaCore.java
+@@ -17,6 +17,7 @@
+ package edu.msu.cme.rdp.readseq.readers.core;
+ 
+ import edu.msu.cme.rdp.readseq.readers.Sequence;
++import edu.msu.cme.rdp.readseq.utils.BufferedRandomAccessFile;
+ import edu.msu.cme.rdp.readseq.SequenceFormat;
+ import java.io.DataOutputStream;
+ import java.io.File;
+@@ -43,7 +44,7 @@
+     }
+ 
+     public Map<String, Long> scanInternal() throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         readUntilNext('>');
+@@ -67,7 +68,7 @@
+     }
+ 
+     public int scanToStream(DataOutputStream out) throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         readUntilNext('>');
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/FastqCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/FastqCore.java
+@@ -18,6 +18,7 @@
+ 
+ import edu.msu.cme.rdp.readseq.QSequence;
+ import edu.msu.cme.rdp.readseq.readers.Sequence;
++import edu.msu.cme.rdp.readseq.utils.BufferedRandomAccessFile;
+ import edu.msu.cme.rdp.readseq.SequenceFormat;
+ import java.io.DataOutputStream;
+ import java.io.File;
+@@ -65,7 +66,7 @@
+     }
+ 
+     public Map<String, Long> scanInternal() throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         readUntilNext('@');
+@@ -76,10 +77,10 @@
+ 
+         while (seqFile.getFilePointer() != seqFile.length()) {
+             String sid = parseSid();
+-            seqIndex.put(sid, lastHeader);    
++            seqIndex.put(sid, lastHeader);
+             String temp = readUntilNext("\n@");
+-            // when @ is the first char of the quality line    
+-            String[] lines = temp.split("\n");            
++            // when @ is the first char of the quality line
++            String[] lines = temp.split("\n");
+             if ( lines.length == 2){
+                 readUntilNext("\n@");
+             }
+@@ -93,7 +94,7 @@
+     }
+ 
+     public int scanToStream(DataOutputStream out) throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         readUntilNext('@');
+--- a/src/edu/msu/cme/rdp/readseq/readers/core/GenbankCore.java
++++ b/src/edu/msu/cme/rdp/readseq/readers/core/GenbankCore.java
+@@ -17,6 +17,7 @@
+ package edu.msu.cme.rdp.readseq.readers.core;
+ 
+ import edu.msu.cme.rdp.readseq.readers.Sequence;
++import edu.msu.cme.rdp.readseq.utils.BufferedRandomAccessFile;
+ import edu.msu.cme.rdp.readseq.SequenceFormat;
+ import java.io.DataOutputStream;
+ import java.io.File;
+@@ -43,7 +44,7 @@
+     }
+ 
+     public Map<String, Long> scanInternal() throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         long firstHeader = seqFile.getFilePointer();
+@@ -66,7 +67,7 @@
+     }
+ 
+     public int scanToStream(DataOutputStream out) throws IOException {
+-        RandomAccessFile seqFile = super.getRawFile();
++        BufferedRandomAccessFile seqFile = super.getRawFile();
+ 
+         seqFile.seek(0);
+         long firstHeader = seqFile.getFilePointer();


=====================================
debian/patches/series
=====================================
@@ -0,0 +1 @@
+random-access-file.patch



View it on GitLab: https://salsa.debian.org/med-team/rdp-readseq/-/compare/252bdbe7775ff03829523786281799ea7262572e...cc586538f2f9388d9b1adb41e1873a7779b2a666

-- 
View it on GitLab: https://salsa.debian.org/med-team/rdp-readseq/-/compare/252bdbe7775ff03829523786281799ea7262572e...cc586538f2f9388d9b1adb41e1873a7779b2a666
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20260225/fa2fd593/attachment-0001.htm>


More information about the debian-med-commit mailing list