I am currently developing a Java application connected to a remote MongoDB databse.
I have implemented the authentication methods fallowing the mongo guides:
MongoCredential credential = MongoCredential.createScramSha1Credential(username, credentialDatabase, password.toCharArray());
MongoClient client = new MongoClient(new ServerAddress(hostname, port), Arrays.asList(credential));
mongoDatabase = client.getDatabase(database);
The app connect properly to the database but there is a thing i can't understand.It connects well to the remote server,but I don't know why it try to connect to localhost:27017.
2016-03-07 16:13:29.662 INFO 12507 --- [*.*.*:25015] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:29}] to *.*.*.*:25015
2016-03-07 16:13:29.687 INFO 12507 --- [*.*.*:25015] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=*.*.*.*:25015, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 2, 3]}, minWireVersion=0, maxWireVersion=4, maxDocumentSize=16777216, roundTripTimeNanos=24485426}
2016-03-07 16:13:30.062 INFO 12507 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2016-03-07 16:13:30.220 INFO 12507 --- [localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
So, how can I tell it I don't want to connect to localhost ?
Thanks
You can exclude Mongo auto connect/(localhost:27017) by adding below annotation on spring boot Application.java.
#EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
public class Application {
// ...
}
I'm not sure if this will help.
If you are using SpringBoot 1.4 and you will not have a bean for MongoClient in the context auto configuration will create MongoClient using default configuration.
#Configuration
---->#ConditionalOnClass(MongoClient.class)<----
#EnableConfigurationProperties(MongoProperties.class)
#ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoAutoConfiguration {
...
#Bean
---->#ConditionalOnMissingBean<----
public MongoClient mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient(this.options, this.environment);
return this.mongo;
}
...
So you have 3 options:
Exclude auto configuration for mongo.
Expose MongoClient as a bean in context.
Use default way of configuration for SpringBoot/Mongo and relay on auto configuration to create MongoClient for you:
spring.data.mongodb.host=
spring.data.mongodb.port=
spring.data.mongodb.database=
spring.data.mongodb.username=
spring.data.mongodb.password=
That's Spring Boot's Auto Configuration kicking in. You can disable it by extending your #SpringBootApplication annotation like this:
#SpringBootApplication(exclude={MongoAutoConfiguration.class})
Related
I'm running an application with Spring (as Discovery Client app), also have a Discovery Server with Eureka, and Spring Cloud Config Server. When the client app is started it's registered as "UNKNOWN" in Eureka, despite its status is set to"UP", isn't able to get the properties from the configuration server.
Client App, Eureka server,and Config Server Spring Boot Version: 2.4.2
Client bootstrap.properties:
spring.application.name=config-client-app
spring.cloud.config.discovery.enabled=true
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.instance-id=${spring.application.name}
Client application.properties file:
logging.level.=debug
server.port=8900
eureka.client.healthcheck.enabled=true
Client Application Class:
#SpringBootApplication
#EnableDiscoveryClient
#RestController
public class ConfigClientAppApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientAppApplication.class, args);
}
}
Eureka Serverproperties file:
spring.application.name=discovery-server
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Eureka Application class:
#EnableEurekaServer
#SpringBootApplication
public class DiscoveryServerApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryServerApplication.class, args);
}
}
The log info:
restartedMain] c.n.discovery.InstanceInfoReplicator : InstanceInfoReplicator onDemand update allowed rate per min is 4
2021-02-09 16:02:50.388 INFO 2845 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1612904570388 with initial instances count: 1
2021-02-09 16:02:50.390 INFO 2845 --- [ restartedMain] o.s.c.n.e.s.EurekaServiceRegistry : Registering application UNKNOWN with eureka with status UP
2021-02-09 16:02:50.391 INFO 2845 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1612904570391, current=UP, previous=STARTING]
2021-02-09 16:02:50.391 INFO 2845 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_UNKNOWN/192.168.10.22:8900: registering service...
2021-02-09 16:02:50.391 WARN 2845 --- [ restartedMain] c.n.discovery.InstanceInfoReplicator : Ignoring onDemand update due to rate limiter
2021-02-09 16:02:50.393 INFO 2845 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8900 (http) with context path ''
2021-02-09 16:02:50.394 INFO 2845 --- [ restartedMain] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8900
2021-02-09 16:02:50.413 INFO 2845 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_UNKNOWN/192.168.10.22:8900 - registration status: 204
I am using Spring cloud version
<spring-cloud.version>2021.0.5</spring-cloud.version>
and spring boot version
<version>2.7.5</version>
In application.properties, add the following lines to resolve the error:
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
By default, the Eureka Server registers itself into the discovery. The following 2 lines will tell eureka server that there is only one eureka server present in this context.
in the absence of these, our Eureka Server will try to find and register itself on other Eureka Servers in the context and throw a discovery client exception. i.e our own system.
If you encounter the below errors after adding the above properties only you need to add the below properties.
We must add this to the properties, if configuration is not required.
spring.cloud.config.enabled=false
Otherwise application will throw below exception.
No spring.config.import property has been defined
(or) If you have a other server, such as any configuration server we can add this optional server configuration to application.properties,
spring.config.import=optional:configserver: Your server url
Spring Cloud Config provides server and client-side support for
externalized configuration in a distributed system
I set up a new Spring Boot Application including only the spring-boot-starter-data-mongodb dependency and added basic mongodb configs (host, port, username, password, ..) in the application.properties.
When I execute the application the following appears in the console:
2020-12-27 23:30:21.306 INFO 25230 --- [localhost:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:86}] to localhost:27017
2020-12-27 23:30:21.306 INFO 25230 --- [localhost:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:87}] to localhost:27017
I am curios why the connection was opened twice by spring. Isn't one opened connection enough?
Please add the below line into your properties file.
spring.data.mongodb.min-connections-per-host=1
The default size is 2 for the MongoDB java driver.
Hope this will work for you!
I am new to EJB as well as Geronimo server.
I want to create Junit POC for EJB on Geronimo Server.
But on Lookup to Stateless Session bean its giving me this error.
Please find the exception below
javax.naming.NamingException: Cannot lookup '/MyStatelessSessionBeanRemote'. [Root exception is java.rmi.RemoteException: Cannot read the response from the server. The class for an object being returned is not located in this system:; nested exception is:
java.lang.ClassNotFoundException: sampleear.RemoteBusinessInterface]
at org.apache.openejb.client.JNDIContext.lookup(JNDIContext.java:240)
at javax.naming.InitialContext.lookup(InitialContext.java:363)
at test.SampleTest.setUp(SampleTest.java:44)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
I am using Geronimo server 2.1 and I have also deployed the EAR file in geronimo server.
EAR file gets successfully deployed showing on the Geronimo server.
Please find the Logs below
2019-07-01 14:39:46,221 INFO [config] Configuring Service(id=Default BMP Container, type=Container, provider-id=Default BMP Container)
2019-07-01 14:39:46,222 INFO [config] Configuring Service(id=Default CMP Container, type=Container, provider-id=Default CMP Container)
2019-07-01 14:39:46,222 INFO [config] Configuring app: sampleear/sample-ejb/1.0/ejb
2019-07-01 14:39:46,269 INFO [OpenEJB] Auto-deploying ejb MyStatelessSessionBean: EjbDeployment(deployment-id=sample-ejb/MyStatelessSessionBean)
2019-07-01 14:39:46,277 INFO [config] Loaded Module: sampleear/sample-ejb/1.0/ejb
2019-07-01 14:39:46,555 INFO [startup] Assembling app: /tmp/geronimo-deployer1011310413181662917.tmpdir/SampleEJB.jar
2019-07-01 14:39:46,557 ERROR [startup] Jndi(name=MyStatelessSessionBeanRemote) cannot be bound to Ejb(deployment-id=sample-ejb/MyStatelessSessionBean). Name already taken by Ejb(deployment-id=SampleEJB.jar/MyStatelessSessionBean)
2019-07-01 14:39:46,557 INFO [startup] Created Ejb(deployment-id=sample-ejb/MyStatelessSessionBean, ejb-name=MyStatelessSessionBean, container=Default Stateless Container)
2019-07-01 14:39:46,558 INFO [startup] Deployed Application(path=/tmp/geronimo-deployer1011310413181662917.tmpdir/SampleEJB.jar)
2019-07-01 14:39:46,673 INFO [SupportedModesServiceImpl] Portlet mode 'edit' not found for portletId: '/plugin.Deployment!227983155|0'
2019-07-01 14:39:46,676 INFO [XSRFHandler] Updated HTML content with XSRF JavaScript for requestURI=/console/portal//Applications/Deploy%20New
Junit - Client
public class SampleTest extends TestCase {
protected MyStatelessSessionBean remoteBusinessIntf;
public void setUp() throws Exception {
super.setUp();
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
prop.put("java.naming.provider.url", "ejbd://127.0.0.1:4201");
// prop.put("openejb.authentication.realmName","geronimo-admin");
// prop.put("java.naming.security.principal","system");
// prop.put("java.naming.security.credentials","manager");
Context context = new InitialContext(prop);
remoteBusinessIntf = (MyStatelessSessionBean) context.lookup("MyStatelessSessionBeanRemote"); // Giving error on this.
}
public void testSaveBook() {
System.out.println("ok");
remoteBusinessIntf.sayHello("EJB");
}
}
Stateless Session Bean
package sampleear;
import javax.ejb.Remote;
import javax.ejb.Stateless;
#Stateless
public class MyStatelessSessionBean implements RemoteBusinessInterface {
public String sayHello(String name) {
return getClass().getName() + " says hello to "+ name + ".";
}
}
Remote Interface
package sampleear;
import javax.ejb.Remote;
#Remote
public interface RemoteBusinessInterface {
public String sayHello(String name);
}
Deployed EJB Application
Component Name State Commands
org.apache.geronimo.configs/mejb/2.1.4/car running Stop Restart Uninstall
org.apache.geronimo.plugins/agent/2.1.4/car running Stop Restart Uninstall
sampleear/sample-ejb/1.0/ejb running Stop Restart Uninstall
Geronimo v2.1.4
No Modifications to port.Default Port is used.
Port Details of Geronimo
Startup completed in 31.119s seconds
Listening on Ports:
1050 0.0.0.0 CORBA Naming Service
1099 0.0.0.0 RMI Naming
1527 0.0.0.0 Derby Connector
2001 0.0.0.0 OpenEJB ORB Adapter
4201 0.0.0.0 OpenEJB Daemon
6882 0.0.0.0 OpenEJB ORB Adapter
8009 0.0.0.0 Tomcat Connector AJP AJP
8080 0.0.0.0 Tomcat Connector HTTP BIO HTTP
8443 0.0.0.0 Tomcat Connector HTTPS BIO HTTPS
9999 0.0.0.0 JMX Remoting Connector
61613 0.0.0.0 ActiveMQ Transport Connector
61616 0.0.0.0 ActiveMQ Transport Connector
I have again created the fresh Geronimo server and deployed the EJB Application.This time haven't got any deployment error. Please find the logs below.
2019-07-02 10:28:18,242 INFO [config] Configuring Service(id=Default Stateful Container, type=Container, provider-id=Default Stateful Container)
2019-07-02 10:28:18,242 INFO [config] Configuring Service(id=Default BMP Container, type=Container, provider-id=Default BMP Container)
2019-07-02 10:28:18,242 INFO [config] Configuring Service(id=Default CMP Container, type=Container, provider-id=Default CMP Container)
2019-07-02 10:28:18,243 INFO [config] Configuring app: sampleear/sample-ejb/1.0/ejb
2019-07-02 10:28:18,275 INFO [OpenEJB] Auto-deploying ejb MyStatelessSessionBean: EjbDeployment(deployment-id=sample-ejb/MyStatelessSessionBean)
2019-07-02 10:28:18,281 INFO [config] Loaded Module: sampleear/sample-ejb/1.0/ejb
2019-07-02 10:28:18,555 INFO [startup] Assembling app: /tmp/geronimo-deployer7186189966556040174.tmpdir/SampleEJB.jar
2019-07-02 10:28:18,558 INFO [startup] Jndi(name=MyStatelessSessionBeanRemote) --> Ejb(deployment-id=sample-ejb/MyStatelessSessionBean)
2019-07-02 10:28:18,558 INFO [startup] Created Ejb(deployment-id=sample-ejb/MyStatelessSessionBean, ejb-name=MyStatelessSessionBean, container=Default Stateless Container)
2019-07-02 10:28:18,558 INFO [startup] Deployed Application(path=/tmp/geronimo-deployer7186189966556040174.tmpdir/SampleEJB.jar)
2019-07-02 10:28:18,669 INFO [SupportedModesServiceImpl] Portlet mode 'edit' not found for portletId: '/plugin.Deployment!227983155|0'
2019-07-02 10:28:18,673 INFO [XSRFHandler] Updated HTML content with XSRF JavaScript for requestURI=/console/portal//Applications/Deploy%20New
For example a database such as MongoDB. I doubt that it is unnecessary to open and close a connection for every request. So I try to keep a connection to handle every request like this.
public class MongoUtils {
private static final String connectionString = "mongodb://localhost:27017";
private static final MongoClient client;
static {
client = MongoClients.create(connectionString);
}
public static MongoClient getConnection(){
return client;
}
}
But maybe I'm doing this wrong somewhere. I don't know why it create the first connection and leave it there, then it create the second connection and use that to handle my db request. Here's the log
2018-10-25 11:37:36 INFO AnnotationMBeanExporter:433 - Registering beans for JMX exposure on startup
2018-10-25 11:37:36 INFO Http11NioProtocol:180 - Starting ProtocolHandler ["http-nio-8808"]
2018-10-25 11:37:36 INFO NioSelectorPool:180 - Using a shared selector for servlet write/read
2018-10-25 11:37:36 INFO TomcatWebServer:206 - Tomcat started on port(s): 8808 (http) with context path '/api'
2018-10-25 11:37:36 INFO Backend:59 - Started Backend in 3.251 seconds (JVM running for 6.935)
2018-10-25 11:37:56 INFO [/api]:180 - Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-10-25 11:37:56 INFO DispatcherServlet:494 - FrameworkServlet 'dispatcherServlet': initialization started
2018-10-25 11:37:56 INFO DispatcherServlet:509 - FrameworkServlet 'dispatcherServlet': initialization completed in 39 ms
2018-10-25 11:37:56 INFO cluster:71 - Cluster created with settings {hosts=[10.184.153.232:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2018-10-25 11:37:56 INFO cluster:71 - Cluster description not yet available. Waiting for 30000 ms before timing out
2018-10-25 11:37:56 INFO connection:71 - Opened connection [connectionId{localValue:1, serverValue:27}] to 10.184.153.232:27017
2018-10-25 11:37:56 INFO cluster:71 - Monitor thread successfully connected to server with description ServerDescription{address=10.184.153.232:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[4, 0, 3]}, minWireVersion=0, maxWireVersion=7, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=3393851}
2018-10-25 11:37:56 INFO connection:71 - Opened connection [connectionId{localValue:2, serverValue:28}] to 10.184.153.232:27017
Look up "connection pooling" which is the idea of having a "pool" of connections left open that your requests can use. If they are idle a while you can program them to close; conversely if they are overloaded you can program a connection pool to open even more connections to accommodate the load. They are tunable / configurable in other ways.
MongoDB Java Driver database connection pooling with Tomcat
How to establish a connection pool in JDBC?
To quote directly from the JavaDocs of com.mongodb.MongoClient:
A MongoDB client with internal connection pooling. For most applications, you should have one MongoClient instance for the entire JVM.
The client itself has internal connection pooling and is thread-safe. So you should use a single MongoClient instance for your application.
This suggests that you're already using it as recommended.
I'm running a java web server on Windows with a local MongoDB database using
mongo-java-driver 3.2.2
When starting the server I create a new MongoClient:
MongoClient mongoClient = new MongoClient("localhost:27017", options);
(options contain some CodecRegistries)
Right after running the server I get the following log:
com.mongodb.diagnostics.logging.SLF4JLogger info
INFO: Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
...
But then, after a few seconds, the server starts and I get the following log:
com.mongodb.diagnostics.logging.SLF4JLogger info
INFO: Opened connection [connectionId{localValue:2, serverValue:1}] to localhost:27017
com.mongodb.diagnostics.logging.SLF4JLogger info
INFO: Monitor thread successfully connected to server with description
ServerDescription{address=localhost:27017, type=STANDALONE,
state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 2,
0]}, minWireVersion=0, maxWireVersion=4, maxDocumentSize=16777216,
roundTripTimeNanos=1691281}
I couldn't find a reason why the client would fail to connect for the first time and then recover but this behavior seems consistent with every run.
Did anyone come across similar behavior? If so, how could I solve the problem?
I'll provide any additional information if needed.
turn off mongodb logger in log4f.properties like:
log4j.logger.org.mongodb = OFF
notice it is org.mongodb not com.mongodb