spring-ws deprecated DefaultHttpClient - apache-httpclient-4.x

I found that HttpComponentsMessageSender default constructor in spring-ws-core 3.4.0.RELEASE, which depends on httpclient 4.5.6, is instantiating a DefaultHttpClient() which is deprecated. However, when i tried to set a custom Httpclient with:
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender(HttpClientBuilder.create().build());
httpComponentsMessageSender.setReadTimeout(1000l);
i got:
Caused by: java.lang.UnsupportedOperationException: null
at org.apache.http.impl.client.InternalHttpClient.getParams(InternalHttpClient.java:211) ~[httpclient-4.5.6.jar:4.5.6]
at org.springframework.ws.transport.http.HttpComponentsMessageSender.setReadTimeout(HttpComponentsMessageSender.java:149) ~[spring-ws-core-3.0.4.RELEASE.jar:na]
Is that correct that spring uses a deprecated class by default?
How should i set my custom HttpClient instance?
it seems that if i set my own HttpClient i cannot configure it through HttpCompoemntsMessageSender.
thanks,

Not sure if you was able to resolve this but here is the solution to the following issue:
Caused by: java.lang.UnsupportedOperationException: null
at org.apache.http.impl.client.InternalHttpClient.getParams(InternalHttpClient.java:211) ~[httpclient-4.5.6.jar:4.5.6]
at org.springframework.ws.transport.http.HttpComponentsMessageSender.setReadTimeout(HttpComponentsMessageSender.java:149) ~[spring-ws-core-3.0.4.RELEASE.jar:na]
Note the HttpComponentsMessageSender.setReadTimeout() configures the underlying HttpClient's readTimeout by configuring the HttpClient Params.
As you provided above you can use the HttpClientBuilder to do this:
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender(HttpClientBuilder.create().build());
The solution is to set the "DefaultRequestConfig" on the HttpClientBuilder
HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.build();
As shown below you can set these configuration options at the HttpClient Level by defining a RequestConfig. Here is an example below:
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(60 * 1000)
.setConnectTimeout(60 * 1000)
.setSocketTimeout(60 * 1000)
.build();
Hope this helps.

Related

How Can I Add The OutputStream Using Programmatical Configuration in Log4j2?

Any idea how I can add my output stream to the build config?
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder osAppender = builder.newAppender("os", "OutputStream");
osAppender.addAttribute("target", myStream);
builder.add(osAppender);
BuiltConfiguration config = builder.build();
Configurator.initialize(config);
This is the Error message I get:
2022-01-27 15:04:41,203 main ERROR OutputStream contains an invalid element or attribute "target"
2022-01-27 15:04:41,227 main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.OutputStreamAppender for element OutputStream: java.lang.NullPointerException java.lang.NullPointerException
at org.apache.logging.log4j.core.appender.OutputStreamAppender.getManager(OutputStreamAppender.java:159)
Thanks
The ConfigurationBuilder API does not allow you to set attributes which can not be serialized to a String. Therefore you'll need to use OutputSreamAppender's builder directly:
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
final Appender appender = OutputStreamAppender.newBuilder()//
.setTarget(myStream)
.setConfiguration(ctx.getConfiguration())
.build();
config.addLoggerAppender(ctx.getRootLogger(), appender);
See this question for another example of ConfigurationBuilder API vs direct instantiation of Log4j components.
Check also Log4j's architecture, which explains how all these components work together.

loadKeyMaterial method deprecated, tell me the alternative

configureBody(request, requestData.getBody())
configureHeaders(request, requestData.getHeadersAsMap())
String keyPassphrase = "password";
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("Resources/certificates/selfsigned.jks"), keyPassphrase.toCharArray());
SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, "password").build(); //(keyStore, "password").build()
HttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();
HttpResponse response = httpClient.execute(request, httpClientContext)
coming error:- groovy.lang.MissingMethodException: No signature of method: org.apache.http.ssl.SSLContextBuilder.loadKeyMaterial()
i am using httpclient4.5.5 jar. loadkeyMaterial method was deprecated in httpclient4.4. kindly suggest some alternative.
You should use loadKeyMaterial from org.apache.http.ssl.SSLContextBuilder instead fo from org.apache.http.conn.ssl.SSLContextBuilder which is deprecated.
So, basically change your imports:
// The one deprecated to be removed from your code
//import org.apache.http.conn.ssl.SSLContextBuilder;
// The good one
import org.apache.http.ssl.SSLContextBuilder;

Hikaricp with Hibernate and MySql: one of either dataSource or dataSourceClassName must be specified

I am working with:
Spring 4.1.4.RELEASE
Hibernate 4.3.8.FINAL
HikariCP 2.3.2
MySQL 5.6.22 Homebrew
HikariCP page has two interesting documentation/blog about MySQL and Hibernate
After to read the following tutorial about MySQL:
MySQL Configuration
I have the following configuration about the DataSource:
Alpha (the best recommended and first try)
#Bean(name="dataSource", destroyMethod="close")
public DataSource dataSourceDevelopment() throws Exception{
HikariConfig hc = new HikariConfig();
hc.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
//hc.setDriverClassName("com.mysql.jdbc.Driver");
//hc.setJdbcUrl("jdbc:mysql://localhost:3306/manolodb_01");
hc.setUsername("user");
hc.setPassword("password");
hc.setPoolName("hikaricp-manolodb_01-pool");
hc.addDataSourceProperty("databaseName", "manolodb_01");
hc.addDataSourceProperty("cachePrepStmts", "true");
hc.addDataSourceProperty("prepStmtCacheSize", "250");
hc.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
hc.addDataSourceProperty("useServerPrepStmts", "true");
HikariDataSource hds = new HikariDataSource(hc);
return hds;
}
After to read the following tutorial about Hibernate:
Hibernate4
I have the following configuration:
#Bean
public LocalSessionFactoryBean sessionFactory(DataSource dataSource){
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(dataSource);
localSessionFactoryBean.setPackagesToScan("com.manuel.jordan.domain");
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", environment.getRequiredProperty("database.hibernate.dialect", String.class));
hibernateProperties.setProperty("hibernate.connection.provider_class","com.zaxxer.hikari.hibernate.HikariConnectionProvider");
hibernateProperties.setProperty("hibernate.cache.provider_class","org.hibernate.cache.NoCacheProvider");
hibernateProperties.setProperty("hibernate.show_sql","true");
hibernateProperties.setProperty("hibernate.format_sql","true");
hibernateProperties.setProperty("hibernate.use_sql_comments","true");
hibernateProperties.setProperty("hibernate.max_fetch_depth","30");
hibernateProperties.setProperty("hibernate.default_batch_fetch_size","30");
hibernateProperties.setProperty("hibernate.jdbc.batch_size","30");//N + 1
hibernateProperties.setProperty("hibernate.order_updates", "true");
hibernateProperties.setProperty("org.hibernate.SQL","true");
hibernateProperties.setProperty("org.hibernate.type","true");
localSessionFactoryBean.setHibernateProperties(hibernateProperties);
return localSessionFactoryBean;
}
observe I am using:
hibernateProperties.setProperty("hibernate.connection.provider_class","com.zaxxer.hikari.hibernate.HikariConnectionProvider");
But I always receive:
Caused by: java.lang.IllegalArgumentException: one of either dataSource or dataSourceClassName must be specified
at com.zaxxer.hikari.AbstractHikariConfig.validate(AbstractHikariConfig.java:747)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:73)
at com.zaxxer.hikari.hibernate.HikariConnectionProvider.configure(HikariConnectionProvider.java:80)
... 54 more
Even with Beta
#Bean(name="dataSource", destroyMethod="close")
public DataSource dataSourceDevelopment() throws Exception{
HikariConfig hc = new HikariConfig();
//hc.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
hc.setDriverClassName("com.mysql.jdbc.Driver");
hc.setJdbcUrl("jdbc:mysql://localhost:3306/manolodb_01");
hc.setUsername("user");
hc.setPassword("password");
hc.setPoolName("hikaricp-manolodb_01-pool");
hc.addDataSourceProperty("databaseName", "manolodb_01");
hc.addDataSourceProperty("cachePrepStmts", "true");
hc.addDataSourceProperty("prepStmtCacheSize", "250");
hc.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
hc.addDataSourceProperty("useServerPrepStmts", "true");
HikariDataSource hds = new HikariDataSource(hc);
return hds;
}
I get the same error message:
I did realize if I comment
hibernateProperties.setProperty("hibernate.connection.provider_class","com.zaxxer.hikari.hibernate.HikariConnectionProvider");
I have no errors. Why this behavior?
I think my configuration is correct because the second link says:
In order to use the HikariConnectionProvider in Hibernate 4.x add the
following property to your hibernate.properties configuration file:
hibernate.connection.provider_class=com.zaxxer.hikari.hibernate.HikariConnectionProvider
And that is what I haveā€¦
I don't want include HikariCP configuration properties directly in the hibernate.properties how the second link offers too.
You have 2 options to configure a DataSource for use with hibernate either you fully configure a DataSource in spring and inject it into the dataSource property of the LocalSessionFactoryBean or your use the hibernate properties to configure the DataSource in that case you must set the hibernate.connection.provider_class.

javax.xml.bind.UnmarshalException when request rest json service with jersey client

I have a rest webservice (with jersey) which returns json list, if i call it directly it returns exactly this :
[{"success":false,"uri":"foo:22","message":"Unknown host : foo"},{"success":true,"uri":"localhost:8082","message":null}]
generated by this snippet :
#GET
#Path("/opening/")
public List<OpeningResult> testOpenings(#QueryParam("uri") List<String> uris) {
LOG.debug("testOpenings request uris :[" + uris + "]");
List<OpeningResult> openingResults = infoService.testOpenings(uris);
return openingResults;
}
It's a Collection of Pojo which look like this :
#XmlRootElement(name = "OpeningResult")
public class OpeningResult {
attributes
...
getter/setter
}
this Pojo is shared through a common jar between the server and the client.
i call the web service with this snippet :
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/scheduler/rest/opening");
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
for (String uri : uris) {
params.add("uri", uri);
}
List<OpeningResult> results = newArrayList(resource.queryParams(params).get(OpeningResult[].class));
I add some trace on the server side, i see that my rest service is called with the good parameters, buth on client side, i have this error :
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"success"). Expected elements are <{}OpeningResult>
I don't find where it comes from ?
Modify your code to set up your client like this:
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
Client client = Client.create(clientConfig);
I had the exact same problem until this question and its answers pointed me in the right direction.
The situation is caused by the default jersey-json module used for serialization to and from JSON, which does not handle certain JSON constructs properly.
You can set the FEATURE_POJO_MAPPING flag to use the Jackson library's JacksonJsonProvider for JSON serialization instead.
Check out the Jersey Client side doc on using JSON. It looks like you're at least missing the annotation:
#Produces("application/json")
But you could also be missing the POJO Mapping feature filters for both client and server side. These all seem to be minor configuration changes.

StructureMap Exception Code: 202 No Default Instance defined

When I register the following in SM and then attempt to create an instance I get the exception - 'StructureMap Exception Code: 202 No Default Instance defined for PluginFamily...'
Scan(x =>
{
x.Assembly("MVCDemo");
x.Assembly("MVCDemo.Infrastructure");
x.Assembly("MVCDemo.Services");
x.AddAllTypesOf(typeof (IRepository<>));
});
ForRequestedType<IRepository<Employee>>().TheDefault.Is.ConstructedBy(() => new EmployeeRepository());
var tmp4 = ObjectFactory.GetInstance<IRepository<Employee>>();
The exception occurs when I try and get an instance of IRepository.
Does anyone know what I'm missing?
Cheers
Ollie
The answer is I shouldn't use ObjectFactory to create instance, I should use the container:
var container = new Container(new MvcDemoRegistry());
var cultureProvider = container.GetInstance<IProvideCultureInfo>();
Ta
Ollie
You aren't supposed to use containers to get instances when using an IoC and DI. You should be using constructor injection and have the IoC handle the injection for you.