maxmind / MaxMind-DB-Reader-java

Java reader for the MaxMind DB format
https://maxmind.github.io/MaxMind-DB-Reader-java/
Apache License 2.0
114 stars 43 forks source link

Unable to read custom database #36

Closed mikycol closed 6 years ago

mikycol commented 6 years ago

I've created a test database and I'm trying to use it with the Java API, but I always get the following error:

Exception in thread "main" com.maxmind.db.InvalidDatabaseException: The MaxMind DB file's search tree is corrupt: contains pointer larger than the database.
    at com.maxmind.db.Reader.resolveDataPointer(Reader.java:243)
    at com.maxmind.db.Reader.get(Reader.java:150)
    at my.Test.main(Test.java:12)

I use the following code for reading:

Reader reader = new Reader(new File("test.mmdb.gz"));
InetAddress inetAddr = InetAddress.getByName("1.1.1.1");
JsonNode res = reader.get(inetAddr);
System.out.println(res);

This is the code used to write the custom database:

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw( say );
use local::lib 'local';
use MaxMind::DB::Writer::Tree;
use Net::Works::Network;
use String::Random;

sub _universal_map_key_type_callback {
  my $map = {
      word1                       => 'utf8_string',
      word2                       => 'utf8_string',
      word3                       => 'utf8_string',
  };
  my $callback = sub {
      my $key = shift;

      return $map->{$key} || die <<"ERROR";
Unknown tree key '$key'.
The universal_map_key_type_callback doesn't know what type to use for the passed
key.  If you are adding a new key that will be used in a frozen tree / mmdb then
you should update the mapping in both our internal code and here.
ERROR
  };
  return $callback;
}
my $filename = 'test.mmdb';
my $type = 'test';
my $tree = MaxMind::DB::Writer::Tree->new(
  record_size   => 28,
  ip_version    => 4,
  database_type => $type,
  languages     => [ 'en'],
  description   => {
      en => "TEST database"
  },
  map_key_type_callback => _universal_map_key_type_callback(),
);
my $rnd = new String::Random;
my $network = Net::Works::Network->new_from_string( string => '1.1.1.0/24' );
$tree->insert_network( $network, {
  word1 => 'Test 1',
  word2 => 'Test 2',
  word3 => $rnd->randpattern("CCcc!ccn")
});
$network = Net::Works::Network->new_from_string( string => '2.2.2.0/24' );
$tree->insert_network( $network, {
  word1 => 'Test 1',
  word2 => 'Test 2',
  word3 => $rnd->randpattern("CCcc!ccn")
});
open my $fh, '>:raw', $filename;
$tree->write_tree( $fh );
close $fh;
say "$filename has now been created";

The same database works perfectly in perl and python

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw( say );
use local::lib 'local';

use Data::Printer;
use MaxMind::DB::Reader;
use Net::Works::Address;

my $ip = shift @ARGV or die 'Usage: perl test-read.pl [ip_address]';

my $reader = MaxMind::DB::Reader->new( file => 'test.mmdb' );

say 'Description: ' . $reader->metadata->{description}->{en};

my $record = $reader->record_for_address( $ip );
say np $record;
#!/usr/bin/env python

import maxminddb
reader = maxminddb.open_database('test.mmdb')
print reader.get('1.1.1.1')
reader.close()

I don't understand what i did wrong

examples.zip

oschwald commented 6 years ago

Are you putting the database inside a JAR? If so, you may be running into https://github.com/maxmind/MaxMind-DB-Reader-java#packaging-database-in-a-jar

mikycol commented 6 years ago

No, I'm not putting it inside the jar.

mikycol commented 6 years ago

Any suggestions?

oschwald commented 6 years ago

I just tested out the test.mmdb generated by your script and it works fine for me. Here is my Java code:

import com.fasterxml.jackson.databind.JsonNode;
import com.maxmind.db.Reader;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;

public class Test {
    public static void main(String[] args) throws IOException {
        File database = new File("test.mmdb");
        Reader reader = new Reader(database);

        InetAddress address = InetAddress.getByName("1.1.1.1");

        JsonNode response = reader.get(address);

        System.out.println(response);

        reader.close();

    }
}

Please verify that you have the latest version of this library and that the database has not been modified.

mikycol commented 6 years ago

I begin to think that there is something wrong with the generation and not with reading. Can you send me the database you used?

Thank you

oschwald commented 6 years ago

I just ran your script. If you provide me with your email address, I can send you the file. You could also run mmdbverify on your file.

mikycol commented 6 years ago

My mail is mikycol AT gmail DOT com

Thank You very much