问:
SSL Handshake failure with TLSv1 by using Java 6, HTMLUnit and Bouncy Castle
I am trying to connect SSL site https://link.bollore-logistics.com by using Java 6 and HTMLUnit, I have added more supported Ciphers by using Bouncy Castle. But still, I am receiving handshake failure. I cannot upgrade Java version due to production limitation. Please kindly help

Code of configuration:

```<code>HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

    if (Security.getProvider("BC") == null){
        logger.info("Bouncy Castle provider is NOT available");
    }
    else{
        logger.info("Bouncy Castle provider is available");
    }

    Provider provider = new BouncyCastleProvider();
    Security.addProvider(provider);

    SSLContext context = SSLContext.getInstance("SSL");

    context.init(null, new X509TrustManager[]{new X509TrustManager() {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }}, new SecureRandom());

    String[] scs = context.getSocketFactory().getSupportedCipherSuites();
    Arrays.sort(scs);

    for(String s : scs) {
        System.out.println(s);
     }
    HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
</code>```

Code to make connection (HTMLUnit):

```<code>WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getPage(url);
</code>```

Here is the error log:

```<code>2017-12-06 11:27:40 DEBUG WebClient:325 - Get page for window named '', using WebRequest[<url="http://link.bollore-logistics.com/Contact/SmartSearch/77707575", GET, EncodingType[name=application/x-www-form-urlencoded], [], {Accept-Encoding=gzip, deflate, Accept=*/*}, null>]
2017-12-06 11:27:40 DEBUG WebClient:1259 - Load response for GET http://link.bollore-logistics.com/Contact/SmartSearch/77707575
trigger seeding of SecureRandom
done seeding SecureRandom
2017-12-06 11:27:40 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:40 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 0 of 6; total allocated: 0 of 20]
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:40 DEBUG MainClientExec:234 - Opening connection {}->http://link.bollore-logistics.com:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:138 - Connection established 192.168.171.168:52556<->195.101.158.66:80
2017-12-06 11:27:40 DEBUG MainClientExec:255 - Executing request GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG MainClientExec:260 - Target auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG MainClientExec:266 - Proxy auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG headers:124 - http-outgoing-0 >> GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Host: link.bollore-logistics.com
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Language: en-US
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Encoding: gzip, deflate
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept: */*
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Connection: Keep-Alive
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "GET /Contact/SmartSearch/77707575 HTTP/1.1[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Host: link.bollore-logistics.com[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Language: en-US[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Encoding: gzip, deflate[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept: */*[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "HTTP/1.0 302 Found[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Server: BigIP[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Content-Length: 0[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "[\r][\n]"
2017-12-06 11:27:41 DEBUG headers:113 - http-outgoing-0 << HTTP/1.0 302 Found
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Server: BigIP
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Connection: Keep-Alive
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Content-Length: 0
2017-12-06 11:27:41 DEBUG MainClientExec:284 - Connection can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:314 - Connection [id: 0][route: {}->http://link.bollore-logistics.com:80] can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 1; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG WebClient:1349 - Got a redirect status code [302] new location = [https://link.bollore-logistics.com/Contact/SmartSearch/77707575]
2017-12-06 11:27:41 DEBUG WebClient:1259 - Load response for GET https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:41 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 1 of 6; total allocated: 2 of 20]
2017-12-06 11:27:41 DEBUG MainClientExec:234 - Opening connection {s}->https://link.bollore-logistics.com:443
2017-12-06 11:27:41 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:443
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:335 - Connecting socket to link.bollore-logistics.com/195.101.158.66:443 with timeout 90000
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:388 - Enabled protocols: [TLSv1]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:389 - Enabled cipher suites:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:393 - Starting handshake
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1512530605 bytes = { 147, 117, 177, 152, 172, 87, 109, 103, 219, 130, 24, 140, 216, 108, 154, 3, 162, 211, 205, 89, 29, 221, 91, 103, 85, 39, 206, 187 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 161
0000: 01 00 00 9D 03 01 5A 27   63 AD 93 75 B1 98 AC 57  ......Z'c..u...W
0010: 6D 67 DB 82 18 8C D8 6C   9A 03 A2 D3 CD 59 1D DD  mg.....l.....Y..
0020: 5B 67 55 27 CE BB 00 00   36 00 04 00 05 00 2F C0  [gU'....6...../.
0030: 02 C0 04 C0 0C C0 0E C0   07 C0 09 C0 11 C0 13 00  ................
0040: 33 00 32 00 0A C0 03 C0   0D C0 08 C0 12 00 16 00  3.2.............
0050: 13 00 09 00 15 00 12 00   03 00 08 00 14 00 11 01  ................
0060: 00 00 3E 00 0A 00 34 00   32 00 17 00 01 00 03 00  ..>...4.2.......
0070: 13 00 15 00 06 00 07 00   09 00 0A 00 18 00 0B 00  ................
0080: 0C 00 19 00 0D 00 0E 00   0F 00 10 00 11 00 02 00  ................
0090: 12 00 04 00 05 00 14 00   08 00 16 00 0B 00 02 01  ................
00A0: 00                                                 .
http-bio-8080-exec-3, WRITE: TLSv1 Handshake, length = 161
[Raw write]: length = 166
0000: 16 03 01 00 A1 01 00 00   9D 03 01 5A 27 63 AD 93  ...........Z'c..
0010: 75 B1 98 AC 57 6D 67 DB   82 18 8C D8 6C 9A 03 A2  u...Wmg.....l...
0020: D3 CD 59 1D DD 5B 67 55   27 CE BB 00 00 36 00 04  ..Y..[gU'....6..
0030: 00 05 00 2F C0 02 C0 04   C0 0C C0 0E C0 07 C0 09  .../............
0040: C0 11 C0 13 00 33 00 32   00 0A C0 03 C0 0D C0 08  .....3.2........
0050: C0 12 00 16 00 13 00 09   00 15 00 12 00 03 00 08  ................
0060: 00 14 00 11 01 00 00 3E   00 0A 00 34 00 32 00 17  .......>...4.2..
0070: 00 01 00 03 00 13 00 15   00 06 00 07 00 09 00 0A  ................
0080: 00 18 00 0B 00 0C 00 19   00 0D 00 0E 00 0F 00 10  ................
0090: 00 11 00 02 00 12 00 04   00 05 00 14 00 08 00 16  ................
00A0: 00 0B 00 02 01 00                                  ......
[Raw read]: length = 5
0000: 15 03 01 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
http-bio-8080-exec-3, READ: TLSv1 Alert, length = 2
http-bio-8080-exec-3, RECV TLSv1 ALERT:  fatal, handshake_failure
http-bio-8080-exec-3, called closeSocket()
http-bio-8080-exec-3, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:87 - http-outgoing-1: Shutdown connection
2017-12-06 11:27:41 DEBUG MainClientExec:128 - Connection discarded
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:79 - http-outgoing-1: Close connection
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1694)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:939)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at com.gargoylesoftware.htmlunit.HtmlUnitSSLConnectionSocketFactory.connectSocket(HtmlUnitSSLConnectionSocketFactory.java:155)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
    at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1371)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:407)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:392)
    at com.grabber.Grabber.accessWebpage(Grabber.java:204)
    at com.grabber.Grabber.doGet(Grabber.java:53)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:619)
</code>```

答:
I had a similar problem (but not using HtmlUnit in that case. I used a directly a org.apache.http.impl.client.CloseableHttpClient).

It seams there is something wrong with the handshake until java 7 (no problem anymore in java 8). If you try to access a server providing "TLSv1.2" you might get the error reported by you.

If security is not that much of an issue in your case, you can try the to force usage of TLSv1.1 (as long as you have not yet switched to java 8).
This shoud be possible this way:

```<code>   WebClientOptions webClientOptions= new WebClientOptions();
   webClientOptions.setSSLClientProtocols(new String[]{"TLSv1.1"});
   SSLConnectionSocketFactory.buildSSLSocketFactory(webClientOptions);
</code>```

Body:
I am trying to connect SSL site https://link.bollore-logistics.com by using Java 6 and HTMLUnit, I have added more supported Ciphers by using Bouncy Castle. But still, I am receiving handshake failure. I cannot upgrade Java version due to production limitation. Please kindly help

Code of configuration:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

    if (Security.getProvider("BC") == null){
        logger.info("Bouncy Castle provider is NOT available");
    }
    else{
        logger.info("Bouncy Castle provider is available");
    }

    Provider provider = new BouncyCastleProvider();
    Security.addProvider(provider);

    SSLContext context = SSLContext.getInstance("SSL");

    context.init(null, new X509TrustManager[]{new X509TrustManager() {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }}, new SecureRandom());

    String[] scs = context.getSocketFactory().getSupportedCipherSuites();
    Arrays.sort(scs);

    for(String s : scs) {
        System.out.println(s);
     }
    HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

Code to make connection (HTMLUnit):

WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getPage(url);

Here is the error log:

2017-12-06 11:27:40 DEBUG WebClient:325 - Get page for window named '', using WebRequest[<url="http://link.bollore-logistics.com/Contact/SmartSearch/77707575", GET, EncodingType[name=application/x-www-form-urlencoded], [], {Accept-Encoding=gzip, deflate, Accept=*/*}, null>]
2017-12-06 11:27:40 DEBUG WebClient:1259 - Load response for GET http://link.bollore-logistics.com/Contact/SmartSearch/77707575
trigger seeding of SecureRandom
done seeding SecureRandom
2017-12-06 11:27:40 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:40 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 0 of 6; total allocated: 0 of 20]
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:40 DEBUG MainClientExec:234 - Opening connection {}->http://link.bollore-logistics.com:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:138 - Connection established 192.168.171.168:52556<->195.101.158.66:80
2017-12-06 11:27:40 DEBUG MainClientExec:255 - Executing request GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG MainClientExec:260 - Target auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG MainClientExec:266 - Proxy auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG headers:124 - http-outgoing-0 >> GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Host: link.bollore-logistics.com
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Language: en-US
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Encoding: gzip, deflate
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept: */*
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Connection: Keep-Alive
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "GET /Contact/SmartSearch/77707575 HTTP/1.1[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Host: link.bollore-logistics.com[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Language: en-US[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Encoding: gzip, deflate[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept: */*[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "HTTP/1.0 302 Found[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Server: BigIP[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Content-Length: 0[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "[\r][\n]"
2017-12-06 11:27:41 DEBUG headers:113 - http-outgoing-0 << HTTP/1.0 302 Found
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Server: BigIP
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Connection: Keep-Alive
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Content-Length: 0
2017-12-06 11:27:41 DEBUG MainClientExec:284 - Connection can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:314 - Connection [id: 0][route: {}->http://link.bollore-logistics.com:80] can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 1; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG WebClient:1349 - Got a redirect status code [302] new location = [https://link.bollore-logistics.com/Contact/SmartSearch/77707575]
2017-12-06 11:27:41 DEBUG WebClient:1259 - Load response for GET https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:41 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 1 of 6; total allocated: 2 of 20]
2017-12-06 11:27:41 DEBUG MainClientExec:234 - Opening connection {s}->https://link.bollore-logistics.com:443
2017-12-06 11:27:41 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:443
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:335 - Connecting socket to link.bollore-logistics.com/195.101.158.66:443 with timeout 90000
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:388 - Enabled protocols: [TLSv1]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:389 - Enabled cipher suites:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:393 - Starting handshake
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1512530605 bytes = { 147, 117, 177, 152, 172, 87, 109, 103, 219, 130, 24, 140, 216, 108, 154, 3, 162, 211, 205, 89, 29, 221, 91, 103, 85, 39, 206, 187 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 161
0000: 01 00 00 9D 03 01 5A 27   63 AD 93 75 B1 98 AC 57  ......Z'c..u...W
0010: 6D 67 DB 82 18 8C D8 6C   9A 03 A2 D3 CD 59 1D DD  mg.....l.....Y..
0020: 5B 67 55 27 CE BB 00 00   36 00 04 00 05 00 2F C0  [gU'....6...../.
0030: 02 C0 04 C0 0C C0 0E C0   07 C0 09 C0 11 C0 13 00  ................
0040: 33 00 32 00 0A C0 03 C0   0D C0 08 C0 12 00 16 00  3.2.............
0050: 13 00 09 00 15 00 12 00   03 00 08 00 14 00 11 01  ................
0060: 00 00 3E 00 0A 00 34 00   32 00 17 00 01 00 03 00  ..>...4.2.......
0070: 13 00 15 00 06 00 07 00   09 00 0A 00 18 00 0B 00  ................
0080: 0C 00 19 00 0D 00 0E 00   0F 00 10 00 11 00 02 00  ................
0090: 12 00 04 00 05 00 14 00   08 00 16 00 0B 00 02 01  ................
00A0: 00                                                 .
http-bio-8080-exec-3, WRITE: TLSv1 Handshake, length = 161
[Raw write]: length = 166
0000: 16 03 01 00 A1 01 00 00   9D 03 01 5A 27 63 AD 93  ...........Z'c..
0010: 75 B1 98 AC 57 6D 67 DB   82 18 8C D8 6C 9A 03 A2  u...Wmg.....l...
0020: D3 CD 59 1D DD 5B 67 55   27 CE BB 00 00 36 00 04  ..Y..[gU'....6..
0030: 00 05 00 2F C0 02 C0 04   C0 0C C0 0E C0 07 C0 09  .../............
0040: C0 11 C0 13 00 33 00 32   00 0A C0 03 C0 0D C0 08  .....3.2........
0050: C0 12 00 16 00 13 00 09   00 15 00 12 00 03 00 08  ................
0060: 00 14 00 11 01 00 00 3E   00 0A 00 34 00 32 00 17  .......>...4.2..
0070: 00 01 00 03 00 13 00 15   00 06 00 07 00 09 00 0A  ................
0080: 00 18 00 0B 00 0C 00 19   00 0D 00 0E 00 0F 00 10  ................
0090: 00 11 00 02 00 12 00 04   00 05 00 14 00 08 00 16  ................
00A0: 00 0B 00 02 01 00                                  ......
[Raw read]: length = 5
0000: 15 03 01 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
http-bio-8080-exec-3, READ: TLSv1 Alert, length = 2
http-bio-8080-exec-3, RECV TLSv1 ALERT:  fatal, handshake_failure
http-bio-8080-exec-3, called closeSocket()
http-bio-8080-exec-3, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:87 - http-outgoing-1: Shutdown connection
2017-12-06 11:27:41 DEBUG MainClientExec:128 - Connection discarded
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:79 - http-outgoing-1: Close connection
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1694)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:939)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at com.gargoylesoftware.htmlunit.HtmlUnitSSLConnectionSocketFactory.connectSocket(HtmlUnitSSLConnectionSocketFactory.java:155)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
    at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1371)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:407)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:392)
    at com.grabber.Grabber.accessWebpage(Grabber.java:204)
    at com.grabber.Grabber.doGet(Grabber.java:53)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:619)

Body:
I had a similar problem (but not using HtmlUnit in that case. I used a directly a org.apache.http.impl.client.CloseableHttpClient).

It seams there is something wrong with the handshake until java 7 (no problem anymore in java 8). If you try to access a server providing "TLSv1.2" you might get the error reported by you.

If security is not that much of an issue in your case, you can try the to force usage of TLSv1.1 (as long as you have not yet switched to java 8).
This shoud be possible this way:

   WebClientOptions webClientOptions= new WebClientOptions();
   webClientOptions.setSSLClientProtocols(new String[]{"TLSv1.1"});
   SSLConnectionSocketFactory.buildSSLSocketFactory(webClientOptions);


来源: stackexchange

问:
Scala List function for grouping consecutive identical elements
Given e.g.:

```<code>List(5, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
</code>```

I'd like to get to:

```<code>List(List(5), List(2), List(3, 3, 3), List(5, 5), List(3, 3), List(2, 2, 2))
</code>```

I would assume there is a simple List function that does this, but am unable to find it.

答:
I have these implementations lying around from working on collections methods.  In the end I checked in simpler implementations of inits and tails and left out cluster.  Every new method no matter how simple ends up collecting a big tax which is hard to see from the outside.  But here's the implementation I didn't use.

```<code>import generic._
import scala.reflect.ClassManifest
import mutable.ListBuffer
import annotation.tailrec
import annotation.unchecked.{ uncheckedVariance => uV }

def inits: List[Repr] = repSequence(x => (x, x.init), Nil)
def tails: List[Repr] = repSequence(x => (x, x.tail), Nil)
def cluster[A1 >: A : Equiv]: List[Repr] =
  repSequence(x => x.span(y => implicitly[Equiv[A1]].equiv(y, x.head)))

private def repSequence(
  f: Traversable[A @uV] => (Traversable[A @uV], Traversable[A @uV]),
  extras: Traversable[A @uV]*): List[Repr] = {

  def mkRepr(xs: Traversable[A @uV]): Repr = newBuilder ++= xs result
  val bb = new ListBuffer[Repr]

  @tailrec def loop(xs: Repr): List[Repr] = {
    val seq = toCollection(xs)
    if (seq.isEmpty)
      return (bb ++= (extras map mkRepr)).result

    val (hd, tl) = f(seq)
    bb += mkRepr(hd)
    loop(mkRepr(tl))
  }

  loop(self.repr)
}
</code>```

[Edit: I forget other people won't know the internals.  This code is written from inside of TraversableLike, so it wouldn't run out of the box.]

ContentLicense: CC BY-SA 2.5

Body:
Given e.g.:

List(5, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)

I'd like to get to:

List(List(5), List(2), List(3, 3, 3), List(5, 5), List(3, 3), List(2, 2, 2))

I would assume there is a simple List function that does this, but am unable to find it.

Body:
I have these implementations lying around from working on collections methods.  In the end I checked in simpler implementations of inits and tails and left out cluster.  Every new method no matter how simple ends up collecting a big tax which is hard to see from the outside.  But here's the implementation I didn't use.

import generic._
import scala.reflect.ClassManifest
import mutable.ListBuffer
import annotation.tailrec
import annotation.unchecked.{ uncheckedVariance => uV }

def inits: List[Repr] = repSequence(x => (x, x.init), Nil)
def tails: List[Repr] = repSequence(x => (x, x.tail), Nil)
def cluster[A1 >: A : Equiv]: List[Repr] =
  repSequence(x => x.span(y => implicitly[Equiv[A1]].equiv(y, x.head)))

private def repSequence(
  f: Traversable[A @uV] => (Traversable[A @uV], Traversable[A @uV]),
  extras: Traversable[A @uV]*): List[Repr] = {

  def mkRepr(xs: Traversable[A @uV]): Repr = newBuilder ++= xs result
  val bb = new ListBuffer[Repr]

  @tailrec def loop(xs: Repr): List[Repr] = {
    val seq = toCollection(xs)
    if (seq.isEmpty)
      return (bb ++= (extras map mkRepr)).result

    val (hd, tl) = f(seq)
    bb += mkRepr(hd)
    loop(mkRepr(tl))
  }

  loop(self.repr)
}

[Edit: I forget other people won't know the internals.  This code is written from inside of TraversableLike, so it wouldn't run out of the box.]


问:
c++ Prim minimum spanning tree using Boost Library
I am working on a project where I need to implement Dijkstra's, Prim's and A* algorithms on an input file my professor will provide.  I have successfully written working code for Dijkstra's but I am hitting a wall trying to get my same graph to work for Prim's as well.  I feel like my problem is not properly having a min spanning tree map to pull my info from but I cant really wrap my head around what the problem is, any help would be greatly appreciated.

structs and graph traits for edges and verts:

```<code>typedef boost::adjacency_list_traits<vecS, vecS, undirectedS, listS> GraphTraits;
// type 'Vertex' identifies each vertex uniquely:
typedef GraphTraits::vertex_descriptor Vertex;
// Property type associated to each vertex:
struct VertexProperty {
    string name;  // Name of vertex (i.e., "location")
    Vertex predecessor; // Predecessor along optimal path.
    double distance; // Distance to the goal, along shortest path.
    default_color_type color; // for use by dijkstra.
    VertexProperty(const string& aName = "") : name(aName) { };
};
// Property type associated to each edge:
struct EdgeProperty {
    double weight; // distance to travel along this edge.
    EdgeProperty(double aWeight = 0.0) : weight(aWeight) { };
};
// Type of the graph used:
typedef adjacency_list<vecS, vecS, undirectedS, VertexProperty, EdgeProperty> Graph;
// Create a global graph object 'g'
Graph g;
// This is a visitor for the dijkstra algorithm. This visitor does nothing special.
struct do_nothing_dijkstra_visitor {
    template <typename Vertex, typename Graph>
    void initialize_vertex(Vertex u, const Graph& g) const { };
    template <typename Vertex, typename Graph>
    void examine_vertex(Vertex u, const Graph& g) const { };
    template <typename Edge, typename Graph>
    void examine_edge(Edge e, const Graph& g) const { };
    template <typename Vertex, typename Graph>
    void discover_vertex(Vertex u, const Graph& g) const { };
    template <typename Edge, typename Graph>
    void edge_relaxed(Edge e, const Graph& g) const { };
    template <typename Edge, typename Graph>
    void edge_not_relaxed(Edge e, const Graph& g) const { };
    template <typename Vertex, typename Graph>
    void finish_vertex(Vertex u, const Graph& g) const { };
};
</code>```

Variables:

```<code>string tempName1, tempName2, tempString, data2;
int weight;
string inputFile;
int choice;
Vertex cur_v, start_v, goal_v;
map<string, Vertex> name2v, name1v;
double totalDist, tempDist;
int numVert = 0;
</code>```

Graph constructions based on file uploaded:

```<code>            //build graph based on file loaded
            getline(fin, tempString);
            getline(fin, tempString);
            stringstream tempSS(tempString);
            while (getline(tempSS, tempName1, ',')) {
                name2v[tempName1] = add_vertex(VertexProperty(tempName1), g);
                numVert++;
            }
            getline(fin, tempString);
            while (getline(fin, tempString)) {
                tempString.erase(tempString.begin(), tempString.begin() + tempString.find('(') + 1);
                tempString.erase(tempString.begin() + tempString.find(')'), tempString.end());
                stringstream temp_ss(tempString);
                getline(temp_ss, tempName1, ',');
                getline(temp_ss, tempName2, ',');
                temp_ss >> weight;
                add_edge(name2v[tempName1], name2v[tempName2], EdgeProperty(weight), g);
            }
            name1v = name2v;
</code>```

Prim's call:

```<code>cout << "Please enter the Vertex you would like to start at: ";
            cin >> tempName1;
            transform(tempName1.begin(), tempName1.end(), tempName1.begin(), ::toupper);
            start_v = name1v[tempName1];
            prim_minimum_spanning_tree(g, start_v,
                get(&VertexProperty::predecessor, g),
                get(&VertexProperty::distance, g),
                get(&EdgeProperty::weight, g),
                identity_property_map(),
                do_nothing_dijkstra_visitor());
</code>```

I tried to just include the code that matters.  Like I said this code will work for Dijkstra but I am not sure how to make it work for Prim's.  I am thinking I need to add more to the struct for the VertexProperty or have a map to store the min spannning tree.  Thanks in advance.

答:
I don't see what exactly you are asking (aside from code style and quality issues).

Here it is, note

the reduced visitor

removed confusing comments

and of course that I'm generating a random graph here because we don't have your input

Live On Coliru

```<code>#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/prim_minimum_spanning_tree.hpp>
#include <boost/graph/random.hpp>
#include <fstream>
#include <map>
#include <random>
#include <sstream>

typedef boost::adjacency_list_traits<boost::vecS, boost::vecS, boost::undirectedS> GraphTraits;
typedef GraphTraits::vertex_descriptor Vertex;

struct DijkstraStuff {
    Vertex predecessor;
    double distance;
    boost::default_color_type color; // for use by dijkstra.
};

struct VertexProperty : DijkstraStuff {
    std::string name;
    VertexProperty(const std::string &aName = "") : name(aName){};
};

struct EdgeProperty {
    double weight; // distance to travel along this edge.
    EdgeProperty(double aWeight = 0.0) : weight(aWeight){};
};

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, VertexProperty, EdgeProperty> Graph;

struct do_nothing_dijkstra_visitor : boost::default_dijkstra_visitor {};

int main() {
    Graph g;
    std::map<std::string, Vertex> name_map;

    // read graph (random for now)
    {
        std::mt19937 prng{ 42 };
        generate_random_graph(g, 10, 20, prng);

        for (auto vd : boost::make_iterator_range(vertices(g))) {
            name_map[g[vd].name = "NAME" + std::to_string(vd)] = vd;
        }

        std::uniform_real_distribution<double> weight_dist(0, 1);
        for (auto ed : boost::make_iterator_range(edges(g))) {
            g[ed].weight = weight_dist(prng);
        }
    }

    print_graph(g, get(&VertexProperty::name, g));

    Graph::vertex_descriptor start_v;

    std::cout << "Please enter the Vertex you would like to start at: ";
    {
        std::string startName;
        std::cin >> startName;
        std::transform(startName.begin(), startName.end(), startName.begin(),
                       [](uint8_t ch) { return std::toupper(ch); });
        start_v = name_map.at(startName);
    }

    boost::prim_minimum_spanning_tree(g, start_v, get(&VertexProperty::predecessor, g),
          get(&VertexProperty::distance, g), get(&EdgeProperty::weight, g),
          boost::identity_property_map(), do_nothing_dijkstra_visitor());

}
</code>```

Printing the result

The resulting MST is encoded as the predecessor map. Print it as follows:

```<code>for (auto vd : boost::make_iterator_range(vertices(g))) {
    auto p = g[vd].predecessor;
    std::cout << "Pred of " << g[vd].name << " is " << g[p].name << "\n";
}
</code>```

(This assumes all vertices are in the MST, for simplicity. This is the same as assuming you didn't have unconnected vertices in the input)

Prints (for the given random seed and starting vertex):

```<code>Pred of NAME1 is NAME9
Pred of NAME2 is NAME2
Pred of NAME3 is NAME6
Pred of NAME4 is NAME1
Pred of NAME5 is NAME6
Pred of NAME6 is NAME1
Pred of NAME7 is NAME3
Pred of NAME8 is NAME7
Pred of NAME9 is NAME0
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am working on a project where I need to implement Dijkstra's, Prim's and A* algorithms on an input file my professor will provide.  I have successfully written working code for Dijkstra's but I am hitting a wall trying to get my same graph to work for Prim's as well.  I feel like my problem is not properly having a min spanning tree map to pull my info from but I cant really wrap my head around what the problem is, any help would be greatly appreciated.

structs and graph traits for edges and verts:

typedef boost::adjacency_list_traits<vecS, vecS, undirectedS, listS> GraphTraits;
// type 'Vertex' identifies each vertex uniquely:
typedef GraphTraits::vertex_descriptor Vertex;
// Property type associated to each vertex:
struct VertexProperty {
    string name;  // Name of vertex (i.e., "location")
    Vertex predecessor; // Predecessor along optimal path.
    double distance; // Distance to the goal, along shortest path.
    default_color_type color; // for use by dijkstra.
    VertexProperty(const string& aName = "") : name(aName) { };
};
// Property type associated to each edge:
struct EdgeProperty {
    double weight; // distance to travel along this edge.
    EdgeProperty(double aWeight = 0.0) : weight(aWeight) { };
};
// Type of the graph used:
typedef adjacency_list<vecS, vecS, undirectedS, VertexProperty, EdgeProperty> Graph;
// Create a global graph object 'g'
Graph g;
// This is a visitor for the dijkstra algorithm. This visitor does nothing special.
struct do_nothing_dijkstra_visitor {
    template <typename Vertex, typename Graph>
    void initialize_vertex(Vertex u, const Graph& g) const { };
    template <typename Vertex, typename Graph>
    void examine_vertex(Vertex u, const Graph& g) const { };
    template <typename Edge, typename Graph>
    void examine_edge(Edge e, const Graph& g) const { };
    template <typename Vertex, typename Graph>
    void discover_vertex(Vertex u, const Graph& g) const { };
    template <typename Edge, typename Graph>
    void edge_relaxed(Edge e, const Graph& g) const { };
    template <typename Edge, typename Graph>
    void edge_not_relaxed(Edge e, const Graph& g) const { };
    template <typename Vertex, typename Graph>
    void finish_vertex(Vertex u, const Graph& g) const { };
};

Variables:

string tempName1, tempName2, tempString, data2;
int weight;
string inputFile;
int choice;
Vertex cur_v, start_v, goal_v;
map<string, Vertex> name2v, name1v;
double totalDist, tempDist;
int numVert = 0;

Graph constructions based on file uploaded:

            //build graph based on file loaded
            getline(fin, tempString);
            getline(fin, tempString);
            stringstream tempSS(tempString);
            while (getline(tempSS, tempName1, ',')) {
                name2v[tempName1] = add_vertex(VertexProperty(tempName1), g);
                numVert++;
            }
            getline(fin, tempString);
            while (getline(fin, tempString)) {
                tempString.erase(tempString.begin(), tempString.begin() + tempString.find('(') + 1);
                tempString.erase(tempString.begin() + tempString.find(')'), tempString.end());
                stringstream temp_ss(tempString);
                getline(temp_ss, tempName1, ',');
                getline(temp_ss, tempName2, ',');
                temp_ss >> weight;
                add_edge(name2v[tempName1], name2v[tempName2], EdgeProperty(weight), g);
            }
            name1v = name2v;

Prim's call:

cout << "Please enter the Vertex you would like to start at: ";
            cin >> tempName1;
            transform(tempName1.begin(), tempName1.end(), tempName1.begin(), ::toupper);
            start_v = name1v[tempName1];
            prim_minimum_spanning_tree(g, start_v,
                get(&VertexProperty::predecessor, g),
                get(&VertexProperty::distance, g),
                get(&EdgeProperty::weight, g),
                identity_property_map(),
                do_nothing_dijkstra_visitor());

I tried to just include the code that matters.  Like I said this code will work for Dijkstra but I am not sure how to make it work for Prim's.  I am thinking I need to add more to the struct for the VertexProperty or have a map to store the min spannning tree.  Thanks in advance.

Body:
I don't see what exactly you are asking (aside from code style and quality issues).

Here it is, note

the reduced visitor

removed confusing comments

and of course that I'm generating a random graph here because we don't have your input

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/prim_minimum_spanning_tree.hpp>
#include <boost/graph/random.hpp>
#include <fstream>
#include <map>
#include <random>
#include <sstream>

typedef boost::adjacency_list_traits<boost::vecS, boost::vecS, boost::undirectedS> GraphTraits;
typedef GraphTraits::vertex_descriptor Vertex;

struct DijkstraStuff {
    Vertex predecessor;
    double distance;
    boost::default_color_type color; // for use by dijkstra.
};

struct VertexProperty : DijkstraStuff {
    std::string name;
    VertexProperty(const std::string &aName = "") : name(aName){};
};

struct EdgeProperty {
    double weight; // distance to travel along this edge.
    EdgeProperty(double aWeight = 0.0) : weight(aWeight){};
};

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, VertexProperty, EdgeProperty> Graph;

struct do_nothing_dijkstra_visitor : boost::default_dijkstra_visitor {};

int main() {
    Graph g;
    std::map<std::string, Vertex> name_map;

    // read graph (random for now)
    {
        std::mt19937 prng{ 42 };
        generate_random_graph(g, 10, 20, prng);

        for (auto vd : boost::make_iterator_range(vertices(g))) {
            name_map[g[vd].name = "NAME" + std::to_string(vd)] = vd;
        }

        std::uniform_real_distribution<double> weight_dist(0, 1);
        for (auto ed : boost::make_iterator_range(edges(g))) {
            g[ed].weight = weight_dist(prng);
        }
    }

    print_graph(g, get(&VertexProperty::name, g));

    Graph::vertex_descriptor start_v;

    std::cout << "Please enter the Vertex you would like to start at: ";
    {
        std::string startName;
        std::cin >> startName;
        std::transform(startName.begin(), startName.end(), startName.begin(),
                       [](uint8_t ch) { return std::toupper(ch); });
        start_v = name_map.at(startName);
    }

    boost::prim_minimum_spanning_tree(g, start_v, get(&VertexProperty::predecessor, g),
          get(&VertexProperty::distance, g), get(&EdgeProperty::weight, g),
          boost::identity_property_map(), do_nothing_dijkstra_visitor());

}

Printing the result

The resulting MST is encoded as the predecessor map. Print it as follows:

for (auto vd : boost::make_iterator_range(vertices(g))) {
    auto p = g[vd].predecessor;
    std::cout << "Pred of " << g[vd].name << " is " << g[p].name << "\n";
}

(This assumes all vertices are in the MST, for simplicity. This is the same as assuming you didn't have unconnected vertices in the input)

Prints (for the given random seed and starting vertex):

Pred of NAME1 is NAME9
Pred of NAME2 is NAME2
Pred of NAME3 is NAME6
Pred of NAME4 is NAME1
Pred of NAME5 is NAME6
Pred of NAME6 is NAME1
Pred of NAME7 is NAME3
Pred of NAME8 is NAME7
Pred of NAME9 is NAME0


问:
SML: Where is the syntax error
So I recently learned sml and really confused on how to use it compared to java. So I was told me make a code that takes consecutive pairs of values, adding them and inserting the sums into a new list.

If the original list has an odd length, then the first n-1 items are pairwise added, and the n-th item is simply copied as is at the end of the new list.

So my code so far is:

```<code>fun sumpairs x =

    if null x then []
    else (if (tl x =[]) then x
    else hd x + hd(tl x) :: sumpairs(tl (tl x));

sumpairs([1,2,3]); (I want to test it on this to get something like [3,3])
</code>```

but I'm getting a syntax error. And since the sml doesn't find the error for me I'm lost on what the problem or if it even works or not. I believe that is should work.

答:
You have an unmatched parenthesis in (if (tl x =[]).

(SML's error messages are possibly the most confusing I've encountered - I get "syntax error at EOF", which is completely useless.)

It's easier to match parentheses if you use fewer:

```<code>fun sumpairs x =
    if null x then []
    else if tl x = [] then x
    else hd x + hd (tl x) :: sumpairs (tl (tl x))
</code>```

An editor that can show which parentheses match also helps.

Most modern programmer's editors can do that, if you find the magic setting.

I would recommend that you get comfortable with pattern matching - it's usually much easier to follow the logic with patterns than with a chain of conditionals:

```<code>fun sumpairs [] = []
  | sumpairs [x] = [x]
  | sumpairs (x::y::xs) = x + y :: sumpairs xs
</code>```

Title: SML: Where is the syntax error

Body:
So I recently learned sml and really confused on how to use it compared to java. So I was told me make a code that takes consecutive pairs of values, adding them and inserting the sums into a new list.

If the original list has an odd length, then the first n-1 items are pairwise added, and the n-th item is simply copied as is at the end of the new list.

So my code so far is:

fun sumpairs x =

    if null x then []
    else (if (tl x =[]) then x
    else hd x + hd(tl x) :: sumpairs(tl (tl x));

sumpairs([1,2,3]); (I want to test it on this to get something like [3,3])

but I'm getting a syntax error. And since the sml doesn't find the error for me I'm lost on what the problem or if it even works or not. I believe that is should work.

Body:
You have an unmatched parenthesis in (if (tl x =[]).

(SML's error messages are possibly the most confusing I've encountered - I get "syntax error at EOF", which is completely useless.)

It's easier to match parentheses if you use fewer:

fun sumpairs x =
    if null x then []
    else if tl x = [] then x
    else hd x + hd (tl x) :: sumpairs (tl (tl x))

An editor that can show which parentheses match also helps.

Most modern programmer's editors can do that, if you find the magic setting.

I would recommend that you get comfortable with pattern matching - it's usually much easier to follow the logic with patterns than with a chain of conditionals:

fun sumpairs [] = []
  | sumpairs [x] = [x]
  | sumpairs (x::y::xs) = x + y :: sumpairs xs


问:
Tomcat has OutOfMemoryError in Java heap space(InvocationTargetException)
Only do a simple Form post action in browser, The tomcat report

java.lang.OutOfMemoryError: Java heap space

  java.lang.reflect.InvocationTargetException

likes below. But only one computer (all browsers) has that problem, other computer has no problem.

```<code>Struts Problem Report
Struts has detected an unhandled exception:
Messages:
Java heap space
Stacktraces
java.lang.reflect.InvocationTargetException
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:314)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1366)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:748)

java.lang.OutOfMemoryError: Java heap space

You are seeing this page because development mode is enabled. Development mode, or devMode, enables extra debugging behaviors and reports to assist developers. To disable this mode, set:
  struts.devMode=false
in your WEB-INF/classes/struts.properties file.
</code>```

I'm not familiar with Tomcat, Thank you ALL!

答:
If you want to add more memory to your tomcat you should change the following lines in setenv.sh script on your tomcat directory under bin/:

```<code>export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxPermSize=256m"
</code>```

Body:
Only do a simple Form post action in browser, The tomcat report

java.lang.OutOfMemoryError: Java heap space

  java.lang.reflect.InvocationTargetException

likes below. But only one computer (all browsers) has that problem, other computer has no problem.

Struts Problem Report
Struts has detected an unhandled exception:
Messages:
Java heap space
Stacktraces
java.lang.reflect.InvocationTargetException
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:133)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:207)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:314)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:142)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:166)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:190)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:248)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1366)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:748)

java.lang.OutOfMemoryError: Java heap space

You are seeing this page because development mode is enabled. Development mode, or devMode, enables extra debugging behaviors and reports to assist developers. To disable this mode, set:
  struts.devMode=false
in your WEB-INF/classes/struts.properties file.

I'm not familiar with Tomcat, Thank you ALL!

Body:
If you want to add more memory to your tomcat you should change the following lines in setenv.sh script on your tomcat directory under bin/:

export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxPermSize=256m"


问:
minimum Age validation laravel
I want to validation a users information like date of birth for that i have used following line of statement in validation, But how do i make it dynamic so users minimum age could be 13. below that can't register?</p>

```<code>  return Validator::make($data, [
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6',
            'date_of_birth' =>'required|date|before:2011-06-08',
        ]);
</code>```

答:
According to the docs at https://laravel.com/docs/5.5/validation, you should be able to use any valid string that works with the strtotime() function. In this case strtotime('13 years ago') is a valid descriptor for the dynamic date you are after. Hence, the following should work:</p>

```<code>return Validator::make($data, [
    'first_name' => 'required|string|max:255',
    'last_name' => 'required|string|max:255',
    'email' => 'required|string|email|max:255|unique:users',
    'password' => 'required|string|min:6',
    'date_of_birth' =>'required|date|before:13 years ago',
]);
</code>```

Title: minimum Age validation laravel

Body:
I want to validation a users information like date of birth for that i have used following line of statement in validation, But how do i make it dynamic so users minimum age could be 13. below that can't register?

  return Validator::make($data, [
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6',
            'date_of_birth' =>'required|date|before:2011-06-08',
        ]);

Body:
According to the docs at https://laravel.com/docs/5.5/validation, you should be able to use any valid string that works with the strtotime() function. In this case strtotime('13 years ago') is a valid descriptor for the dynamic date you are after. Hence, the following should work:

return Validator::make($data, [
    'first_name' => 'required|string|max:255',
    'last_name' => 'required|string|max:255',
    'email' => 'required|string|email|max:255|unique:users',
    'password' => 'required|string|min:6',
    'date_of_birth' =>'required|date|before:13 years ago',
]);


问:
SQL Server 2008 R2 to MongoDB - is it safe to migrate?
We are running a .Net 4.0 ASP.Net application with SQL Server 2008 R2. I often face database related issues and have to frequently look into possibilities of optimising my SQL code (procedures, triggers, jobs etc). I recently, came to know about MongoDB and read a few articles about it.

Invariably, all articles show that Mongo is much much faster than SQL Server 2008 R2 in CRUD operations.

I also read that sourceforge has migrated from MySQL to MongoDB and claim to be capable of handling 100x more data.

So, impressed with these stats, I went to the mongoDB site, I followed their short demo. It was nice. But I couldn't find much information about other database related aspects like SProcs, triggers, jobs, cursors, Key, indexes etc.

What is my main concern is that is MongoDB evolved enough that I can think of migrating from SQL Server 2008 R2. Also, things like Keys, Indexex, SProcs, triggers, SQL jobs etc do they exist in MongoDB as well? How good is their .Net integration API?

Does anybody have any idea about it?

Thanking in anticipation

答:
What kind of issues do you face with SQL Server 2008 R2??

One option might be to figure those out and fix them. If you optimize your stored procs, if you redesign your table and indices to be more efficient, that might be more than enough to keep your app up and running very well.

I don't know MongoDB that well - but the basic approach is very different - instead of rows and columns and relations, you have "documents". As far as I know, MongoDB does not have any construct similar to stored procedures or triggers - all that would have to be handled in your application.

So it really depends on what kind of app you have - something like an accounting application is probably better off in SQL Server 2008 R2, while something else might be more suitable for MongoDB.

I don't think switching to MongoDB is a "quick fix" just for any kind of performance problems...

Also check out this other SO post on the very same topic:

Reasons for and against moving from SQL server to MongoDB


问:
How to avoid multiple implementation of class functions
I am new to C++ and hence need some help.
Here is the code:

```<code>class InterfaceVehicle
{
  virtual int door() = 0;
  virtual int seats() = 0;
  virtual int enginepower() = 0;
}
class minicar: public InterfaceVehicle
{
    int door () {return 4;}
    int seats () {return 2;}
    int enginepower () {return 10;}
}

class bigcar: public InterfaceVehicle
{
    int door () {return 4;}
    int seats () {return 5;}
    int engine () {return 20;}
}

class truck: public InterfaceVehicle
{
    int door () {return 2;}
    int seats () {return 1;}
    int engine () {return 50;}
}
</code>```

I have an interface base class named Vehicle and three different classes that implements all the functions of the interface class. Here i want to avoid the same implementation of the door function.
I got some suggestions to have a new class that implements this door function and this class will be aggregated into bigcar and minicar. This way i can avoid this copy paste implementation of door(); I like this idea!

Can some please give an example on how i can implement that?
I read a lot about aggregation but did not understand how to implement that in my case.

答:
InterfaceVehicle is an interface because it has all its methods declared but not implemented, but to achieve your purpose the solution is build  ** AbstractVehicle** i.e. an abstract class instead of an interface.

As an interface, an abstract class cannot be instantied, but it can provide implementantion for some common behaviour.
For example, if Minicar and BigCar needs the same implementation of door() while Truck needs another one, you can specify the common behaviour in the base class as

```<code>class AbstractVehicle{
        virtual int door() { return 4;} ;
        virtual int seats() = 0;
        virtual int enginepower() = 0;
}

class Minicar: public virtual AbstractVehicle
{
    int seats () {return 2;}
    int enginepower () {return 10;}
}

class Bigcar: public virtual AbstractVehicle
{
    int seats () {return 5;}
    int engine () {return 20;}
}

class Truck: public virtual AbstractVehicle
{
    int door () {return 2;}
    int seats () {return 1;}
    int engine () {return 50;}
}
</code>```

In this way, subclasses don't have to respect a contract for method door(), they can ovverride it (in the case of Truck that needs another implementantion), but they are not forced to implement that, as they must do for pure abstract methods like seats() and enginepower().

Body:
I am new to C++ and hence need some help.
Here is the code:

class InterfaceVehicle
{
  virtual int door() = 0;
  virtual int seats() = 0;
  virtual int enginepower() = 0;
}
class minicar: public InterfaceVehicle
{
    int door () {return 4;}
    int seats () {return 2;}
    int enginepower () {return 10;}
}

class bigcar: public InterfaceVehicle
{
    int door () {return 4;}
    int seats () {return 5;}
    int engine () {return 20;}
}

class truck: public InterfaceVehicle
{
    int door () {return 2;}
    int seats () {return 1;}
    int engine () {return 50;}
}

I have an interface base class named Vehicle and three different classes that implements all the functions of the interface class. Here i want to avoid the same implementation of the door function.
I got some suggestions to have a new class that implements this door function and this class will be aggregated into bigcar and minicar. This way i can avoid this copy paste implementation of door(); I like this idea!

Can some please give an example on how i can implement that?
I read a lot about aggregation but did not understand how to implement that in my case.

Body:
InterfaceVehicle is an interface because it has all its methods declared but not implemented, but to achieve your purpose the solution is build  ** AbstractVehicle** i.e. an abstract class instead of an interface.

As an interface, an abstract class cannot be instantied, but it can provide implementantion for some common behaviour.
For example, if Minicar and BigCar needs the same implementation of door() while Truck needs another one, you can specify the common behaviour in the base class as

class AbstractVehicle{
        virtual int door() { return 4;} ;
        virtual int seats() = 0;
        virtual int enginepower() = 0;
}

class Minicar: public virtual AbstractVehicle
{
    int seats () {return 2;}
    int enginepower () {return 10;}
}

class Bigcar: public virtual AbstractVehicle
{
    int seats () {return 5;}
    int engine () {return 20;}
}

class Truck: public virtual AbstractVehicle
{
    int door () {return 2;}
    int seats () {return 1;}
    int engine () {return 50;}
}

In this way, subclasses don't have to respect a contract for method door(), they can ovverride it (in the case of Truck that needs another implementantion), but they are not forced to implement that, as they must do for pure abstract methods like seats() and enginepower().


问:
Draft JS - mention- plugins produce this: Warning: React does not recognize the isFocused prop on a DOM element
I'm facing a problem when it comes to involving the draft-js-mention-plugin, into my app. Please, have a look:

"Warning: React does not recognize the isFocused prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase isfocused instead. If you accidentally passed it from a parent component, remove it from the DOM element."

Please, find the print screen according to this problem:

Btw, this issue can be found in this example, too: https://codesandbox.io/s/x2r59zo4j4

Has anyone had the same warning?! Or anyone did a mention in reactjs using draftjs, or even in vanilla javascript? I just need to rely on an example to get things done (i'm a newbie on JS, React JS) ...thanks in advance :)!

答:
Maybe the reason is because in your component your declare

```<code>const { blabla, foo, bar} = this.props
</code>```

And in your render :

```<code><Component
    blabla={blabla}
    foo={foo}
    bar={bar}
    {...this.props} />
</code>```

React interprets you pass twice your props and give you a warning in the console

Body:
Maybe the reason is because in your component your declare

const { blabla, foo, bar} = this.props

And in your render :

<Component
    blabla={blabla}
    foo={foo}
    bar={bar}
    {...this.props} />

React interprets you pass twice your props and give you a warning in the console


问:
Linq to entities does not recognize the method system.string get_Item
I am trying to have an orderByExpression to passed to a function which uses it on the dbContext object in the entity framework

```<code>> Dictionary<int, string> dict = new Dictionary<int, string>();
> Expression<Func<DbQuestion, string>> orderByExpression = r => dict[r.Id];
</code>```

This throws the following error.

Exception=Exceptions.DBConnectionException: LINQ
  to Entities does not recognize the method 'System.String
  get_Item(Int32)' method, and this method cannot be translated into a
  store expression.

I understand that I cannot access the [ ] in Linq to Sql queries. Can you please suggest an alternative or point me in the right direction?

Edit:

Few more details about the problem I am trying to solve:

The dict have 15-20 items and keys remain constant and only values change dynamically

I am trying to order the questions based on the range of r.Id i.e if floor(r.Id)==14 then I return "a" if it's between floor(r.Id)==15 then I return "b" and if it's between floor(r.id)==13 I return "c"(as decided by the values in the dict) this helps in ordering the rows

Here's the actual expression:

```<code>List<int> cqh;
List<int> iqh;
Expression<Func<DbQuestion, string>> orderByExpression = r => cqh.Contains(r.QuestionID)? dict[(int)Math.Floor(r.SearchKey1)] +"2"+Guid.NewGuid() :
                    iqh.Contains(r.QuestionID)? dict[(int)Math.Floor(r.SearchKey1)] + "1"+Guid.NewGuid() :
                    dict[(int)Math.Floor(r.SearchKey1)] + "0"+Guid.NewGuid();
</code>```

Thanks,

答:
I see two options, that stay with LINQ to Entities

Put the data in the dictionary in a separate table, save it, and then join the table. This solution can apply even if you need to have per query data.

Example:

```<code>public class SortKey
{
    [Key]
    public int SortKeyId { get; set; }
    public long SearchId { get; set; }
    public int EntityId { get; set; }
    public string SortId { get; set; }
}

using (var db = new Db())
{
    Dictionary<int, string> dict = new Dictionary<int, string>();
    long searchId = DateTime.Now.Ticks; // Simplfied, either use a guid or a FK to another table
    db.Keys.AddRange(dict.Select(kv => new SortKey { SearchId = searchId, EntityId = kv.Key, SortId = kv.Value }));
    db.SaveChanges();

    var query = from e in db.Entity
                join k in db.Keys.Where(k => k.SearchId == searchId) on (int)e.Id equals k.EntityId
                orderby k.SortId
                select e;
}

// Cleanup the sort key table
</code>```

Build the condition dynamically. This can be achieved using Expression manipulation

Example:

```<code>Expression exp = Expression.Constant(""); //Default order key
var p = Expression.Parameter(typeof(Entity));
foreach (var kv in dict)
{
    exp = Expression.Condition(
        Expression.Equal(
            Expression.Convert(
                Expression.MakeMemberAccess(p, p.Type.GetProperty("Id")), typeof(int)
            ),
            Expression.Constant(kv.Key)
        ),
        Expression.Constant(kv.Value),
        exp
    );
}

var orderByExp = Expression.Lambda<Func<Entity, string>>(exp, p);

var query = db.Entity.OrderBy(orderByExp);
</code>```

Which option you use depend on the amount of data in the dictionary. The condition built for the OrderBy might get very inefficient for a large amount of data

Edit

Based on the changed question, you can use an expression visitor to replace the dic[...] call with a conditional testing for each value in the dictionary. The advantage of this approach is that you can easily change the expression, the replace will work the same way

The class:

```<code>class DictionaryReplaceVisitor : ExpressionVisitor
{
    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        if(node.Object != null && node.Object.Type == typeof(Dictionary<int, string>) && node.Method.Name == "get_Item")
        {
            Expression exp = Expression.Constant(""); //Default order key
            // Compile the tahrget of the index and execute it to get the value
            // If you know there is a single dictionary you could replace this with a class property intead and set it from the Visit call site,
            // but this is the more general appraoch
            var dict = Expression.Lambda<Func<Dictionary<int, string>>>(node.Object).Compile()();
            foreach (var kv in dict)
            {
                exp = Expression.Condition(
                    Expression.Equal(
                        node.Arguments.Single(),
                        Expression.Constant(kv.Key)
                    ),
                    Expression.Constant(kv.Value),
                    exp
                );
            }

            return exp;
        }
        return base.VisitMethodCall(node);
    }
}
</code>```

Usage:

```<code>Expression<Func<Entity, string>> orderByExpression = r => cqh.Contains(r.QuestionID) ? dict[(int)Math.Floor(r.SearchKey1)] + "2" + Guid.NewGuid() :
        iqh.Contains(r.QuestionID) ? dict[(int)Math.Floor(r.SearchKey1)] + "1" + Guid.NewGuid() :
        dict[(int)Math.Floor(r.SearchKey1)] + "0" + Guid.NewGuid();
var replace = (Expression<Func<Entity, string>>)new DictionaryReplaceVisitor().Visit(orderByExpression);

var query = db.Entity.OrderBy(replace).ToString();
</code>```

The resulting SQL will not be pretty but it should work.

Solution 3:

If the amount of data is not very big, you can do a ToList or AsEnumerable on the query and do the ordering in memory (by calling the OrderBy after one of the above methods). It might actually perform better in this case

Body:
I am trying to have an orderByExpression to passed to a function which uses it on the dbContext object in the entity framework

> Dictionary<int, string> dict = new Dictionary<int, string>();
> Expression<Func<DbQuestion, string>> orderByExpression = r => dict[r.Id];

This throws the following error.

Exception=Exceptions.DBConnectionException: LINQ
  to Entities does not recognize the method 'System.String
  get_Item(Int32)' method, and this method cannot be translated into a
  store expression.

I understand that I cannot access the [ ] in Linq to Sql queries. Can you please suggest an alternative or point me in the right direction?

Edit:

Few more details about the problem I am trying to solve:

The dict have 15-20 items and keys remain constant and only values change dynamically

I am trying to order the questions based on the range of r.Id i.e if floor(r.Id)==14 then I return "a" if it's between floor(r.Id)==15 then I return "b" and if it's between floor(r.id)==13 I return "c"(as decided by the values in the dict) this helps in ordering the rows

Here's the actual expression:

List<int> cqh;
List<int> iqh;
Expression<Func<DbQuestion, string>> orderByExpression = r => cqh.Contains(r.QuestionID)? dict[(int)Math.Floor(r.SearchKey1)] +"2"+Guid.NewGuid() :
                    iqh.Contains(r.QuestionID)? dict[(int)Math.Floor(r.SearchKey1)] + "1"+Guid.NewGuid() :
                    dict[(int)Math.Floor(r.SearchKey1)] + "0"+Guid.NewGuid();

Thanks,

Body:
I see two options, that stay with LINQ to Entities

Put the data in the dictionary in a separate table, save it, and then join the table. This solution can apply even if you need to have per query data.

Example:

public class SortKey
{
    [Key]
    public int SortKeyId { get; set; }
    public long SearchId { get; set; }
    public int EntityId { get; set; }
    public string SortId { get; set; }
}

using (var db = new Db())
{
    Dictionary<int, string> dict = new Dictionary<int, string>();
    long searchId = DateTime.Now.Ticks; // Simplfied, either use a guid or a FK to another table
    db.Keys.AddRange(dict.Select(kv => new SortKey { SearchId = searchId, EntityId = kv.Key, SortId = kv.Value }));
    db.SaveChanges();

    var query = from e in db.Entity
                join k in db.Keys.Where(k => k.SearchId == searchId) on (int)e.Id equals k.EntityId
                orderby k.SortId
                select e;
}

// Cleanup the sort key table

Build the condition dynamically. This can be achieved using Expression manipulation

Example:

Expression exp = Expression.Constant(""); //Default order key
var p = Expression.Parameter(typeof(Entity));
foreach (var kv in dict)
{
    exp = Expression.Condition(
        Expression.Equal(
            Expression.Convert(
                Expression.MakeMemberAccess(p, p.Type.GetProperty("Id")), typeof(int)
            ),
            Expression.Constant(kv.Key)
        ),
        Expression.Constant(kv.Value),
        exp
    );
}

var orderByExp = Expression.Lambda<Func<Entity, string>>(exp, p);

var query = db.Entity.OrderBy(orderByExp);

Which option you use depend on the amount of data in the dictionary. The condition built for the OrderBy might get very inefficient for a large amount of data

Edit

Based on the changed question, you can use an expression visitor to replace the dic[...] call with a conditional testing for each value in the dictionary. The advantage of this approach is that you can easily change the expression, the replace will work the same way

The class:

class DictionaryReplaceVisitor : ExpressionVisitor
{
    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        if(node.Object != null && node.Object.Type == typeof(Dictionary<int, string>) && node.Method.Name == "get_Item")
        {
            Expression exp = Expression.Constant(""); //Default order key
            // Compile the tahrget of the index and execute it to get the value
            // If you know there is a single dictionary you could replace this with a class property intead and set it from the Visit call site,
            // but this is the more general appraoch
            var dict = Expression.Lambda<Func<Dictionary<int, string>>>(node.Object).Compile()();
            foreach (var kv in dict)
            {
                exp = Expression.Condition(
                    Expression.Equal(
                        node.Arguments.Single(),
                        Expression.Constant(kv.Key)
                    ),
                    Expression.Constant(kv.Value),
                    exp
                );
            }

            return exp;
        }
        return base.VisitMethodCall(node);
    }
}

Usage:

Expression<Func<Entity, string>> orderByExpression = r => cqh.Contains(r.QuestionID) ? dict[(int)Math.Floor(r.SearchKey1)] + "2" + Guid.NewGuid() :
        iqh.Contains(r.QuestionID) ? dict[(int)Math.Floor(r.SearchKey1)] + "1" + Guid.NewGuid() :
        dict[(int)Math.Floor(r.SearchKey1)] + "0" + Guid.NewGuid();
var replace = (Expression<Func<Entity, string>>)new DictionaryReplaceVisitor().Visit(orderByExpression);

var query = db.Entity.OrderBy(replace).ToString();

The resulting SQL will not be pretty but it should work.

Solution 3:

If the amount of data is not very big, you can do a ToList or AsEnumerable on the query and do the ordering in memory (by calling the OrderBy after one of the above methods). It might actually perform better in this case


问:
Is it possible to set standard output in Java both to a file and to the standard output?
There is a Java command to redirect standard output to a file or back to the
 standart output:

```<code>PrintStream stdout = System.out;
System.setOut(new PrintStream(logFile));
// ...
System.setOut(stdout);
</code>```

But I need to have both of them. Is it possible to set standard output in Java both to the file and to the standard output?

答:
I am not aware of a standard class doing that, but it is pretty simple:

first fetch the "ordinary" stdout PrintStream

write your own PrintStream implementation that writes to a file and to another Printstream

simply pass the original stdout to your new DoublePrintingPrintStream, and use setOut() to use that "double printing" stream

Alternatively, there are tools such as tee that can do that for you. So instead of bothering your Java code with that - simply have something outside read stdout, print to console and write to a file.

Body:
There is a Java command to redirect standard output to a file or back to the
 standart output:

PrintStream stdout = System.out;
System.setOut(new PrintStream(logFile));
// ...
System.setOut(stdout);

But I need to have both of them. Is it possible to set standard output in Java both to the file and to the standard output?