I have a Provider for a MongoDB connection. I would like to store the list 
of nodes and access credentials in a properties file external to the module 
so they're easy to updated. I have this working in one way, but failing in 
another and I'm not sure why.

First, this is how I would like to do it, but the values mongoNode1 and 
mongoNode2 are never set. I have stepped through my code and I know that 
those values are loaded from the properties file and available when the 
module loads, but they come through as null in this code:

public class MongoConnectionProvider implements Provider<Mongo> {
    @Inject @Named("mongoNode1") private String mongoNode1;
    @Inject @Named("mongoNode2") private String mongoNode2;
    List<ServerAddress> mongoNodesDBAddresses;
    MongoOptions options;

    
    public MongoConnectionProvider() {
        try {
            // create addresses for each replicaset node
            List<String> mongoNodes = getMongoNodes();

            mongoNodesDBAddresses = new 
ArrayList<ServerAddress>(mongoNodes.size());
            for (String mongoNode : mongoNodes) {
                mongoNodesDBAddresses.add(new DBAddress(mongoNode));
            }
        } catch (Exception e) {
            throw new RuntimeException("Error initializing mongo db", e);
        }
        options = new MongoOptions();
        options.setReadPreference(ReadPreference.nearest()); // 
http://stackoverflow.com/questions/6520439/how-to-configure-mongodb-java-driver-mongooptions-for-production-use
    }

    @Override
    public Mongo get() {
        final Mongo mongo = new Mongo(mongoNodesDBAddresses, options);
        return mongo;
    }

    protected List<String> getMongoNodes() {
        List<String> mongoNodes = new ArrayList<String>();
        mongoNodes.add(mongoNode1);
        mongoNodes.add(mongoNode2);
        return mongoNodes;
    }
}


An option that does get me the properties is less than ideal since I have a 
handful of subclasses that break or require duplicate code when the 
constructor changes. Here's the code that works:

public class MongoConnectionProvider implements Provider<Mongo> {
    private String mongoNode1;
    private String mongoNode2;
    List<ServerAddress> mongoNodesDBAddresses;
    MongoOptions options;

    @Inject
    public MongoConnectionProvider(@Named("mongoNode1") String mongoNode1, 
@Named("mongoNode2") String mongoNode2) {
        this.mongoNode1 = mongoNode1;
        this.mongoNode2 = mongoNode2;
        try {
            // create addresses for each replicaset node
            List<String> mongoNodes = getMongoNodes();

            mongoNodesDBAddresses = new 
ArrayList<ServerAddress>(mongoNodes.size());
            for (String mongoNode : mongoNodes) {
                mongoNodesDBAddresses.add(new DBAddress(mongoNode));
            }
        } catch (Exception e) {
            throw new RuntimeException("Error initializing mongo db", e);
        }
        options = new MongoOptions();
        options.setReadPreference(ReadPreference.nearest()); // 
http://stackoverflow.com/questions/6520439/how-to-configure-mongodb-java-driver-mongooptions-for-production-use
    }

    @Override
    public Mongo get() {
        final Mongo mongo = new Mongo(mongoNodesDBAddresses, options);
        return mongo;
    }

    protected List<String> getMongoNodes() {
        List<String> mongoNodes = new ArrayList<String>();
        mongoNodes.add(mongoNode1);
        mongoNodes.add(mongoNode2);
        return mongoNodes;
    }
}

Why am I able to inject these values into the constructor, but not the 
class? I would like to make this second case work if possible.

By the way, I also tried injecting them directly into the function 
getMongoNodes, but that produces the error "annotation type not applicable 
to this kind of declaration".

    protected List<String> getMongoNodes() {
        @Inject @Named("mongoNode1") String mongoNode1;
        @Inject @Named("mongoNode2") String mongoNode2;
        List<String> mongoNodes = new ArrayList<String>();
        mongoNodes.add(mongoNode1);
        mongoNodes.add(mongoNode2);
        return mongoNodes;
    }

Any ideas how I can get these named properties into my provider without 
including them in the constructor?

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to