How to resolve a Zlib issue — Java migration from 8 to 11 - spring-mvc

I am working on upgrading Java version from 8 to 11 for an application (maven/spring-framework- no spring boot). The code compiles fine, war is deployed, and application is up and running.
But, it is unable to process incoming client requests. It's throwing java.io.EOFException unexpected end of zlib input stream java.
Below is the request the client sends to the Tomcat server where the Java application is deployed:
Hypertext Transfer Protocol
POST /xxxx/clients/events/inventory HTTP/1.1\r\n
content-encoding: deflate\r\n
User-Agent: Java/1.8.0_131\r\n
Host: xx.xx.xxx.xx:81\r\n
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n
Connection: keep-alive\r\n
Content-type: application/x-www-form-urlencoded\r\n
Transfer-Encoding: chunked\r\n
\r\n
[Full request URI: http://xx.xx.xxx.xx:81/xxxx/clients/events/inventory]
[HTTP request 1/1]
[Response in frame: 10]
HTTP chunked response
Content-encoded entity body (deflate): 147 bytes -> 183 bytes
File Data: 183 byte
HTML Form URL Encoded: application/x-www-form-urlencoded
Form item: "b4
{"Number":"1","EventType":"Inventory","ID":"3c65ec84-cfeb-4ab1-959d-ce8da7b5907c","EquipmentType":"Train","Timestamp":"1671523655021","Train":[{"SystemType":"Train"}],"System":"1"}" = ""
On the server side we have InflaterFilter and InflaterRequestWrapper around HttpServletRequestWrapper to handle the compressed data, and in the controller we have this method below:
#RequestMapping(value = { "inventory", "alarms" }, method = RequestMethod.POST)
#ResponseBody public ResponseEntity<HttpStatus> handleInventoryOrAlarmEvents(ServletInputStream is) {
return new ResponseEntity<HttpStatus>(service.handleEvents(is) ? HttpStatus.OK
: HttpStatus.INTERNAL_SERVER_ERROR);
}
handleEvents method:
#Override public boolean handleEvents(InputStream is) {
ThreadLocal<Boolean> success =
new ThreadLocal<Boolean>() {
/**
* #see ThreadLocal#initialValue()
*/
#Override protected Boolean initialValue() {
return true;
}
};
DispatchMessageExceptionListener exceptionListener = new DispatchMessageExceptionListener(success);
StringInputStream sis = new StringInputStream(is);
try {
String string = null;
while ((string = sis.readString()) != null) {
ClientEvent event = null;
try {
event = parser.parse(string);
if (event == null) {
LOGGER.error("-handleEvents, could not parse event={}", string);
continue;
}
LOGGER.debug("+handleEvents, incoming event={}", event);
if(event.hasProperty("BandwidthEconomyQuota")){
LOGGER.info("Received Fleet Counter for Train Id: {}", event.getString("System"));
}
eventManager.send(event, exceptionListener);
}
catch (Exception e) {
LOGGER.debug("Failed to handle event={}", event, e);
success.set(false);
}
} // end while
}
catch (Exception e) {
LOGGER.debug("Failed to handle all events.", e);
success.set(false);
}
finally {
IOUtil.close(is);
}
return exceptionListener.isSuccess();
} // end method handleEvents
The StringInputStream class:
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Reads strings from an underlying input stream.
*
* #author Marco Soeima
* #version 2013/11/13
*/
public class StringInputStream extends FilterInputStream {
/**
* Creates a new {#link StringInputStream} object.
*
* #param is The input stream to wrap.
*/
public StringInputStream(InputStream is) {
super(is);
}
/**
* Reads the string size from the backing input stream.
*
* #return The string size.
*
* #throws IOException If an I/O error occurs.
*/
private int readSize() throws IOException {
int c = in.read();
if (c < 0) {
return -1;
}
StringBuilder buf = new StringBuilder();
while ((c != -1) && (c != '\n')) {
buf.append((char)c);
c = in.read();
}
return Integer.parseInt(buf.toString(), 16);
}
/**
* Fully reads the <code>size</code> number of bytes into a byte array.
*
* #param size The number of bytes to read.
*
* #return The byte array with the given bytes.
*
* #throws IOException If an I/O error occurs.
*/
private byte[] readFully(int size) throws IOException {
int read = 0;
int count = 0;
byte[] buf = new byte[size];
while ((count >= 0) && (read < size)) {
count = in.read(buf, read, size - read);
read += count;
}
return buf;
}
/**
* Reads a string from the underlying input stream.
*
* #return A string or <code>null</code> if no more string are available for reading.
*
* #throws IOException If an I/O error occurs.
*/
public String readString() throws IOException {
int size = readSize();
if (size < 0) {
return null;
}
return new String(readFully(size), "UTF-8");
}
}
I have googled many solutions. However I have not resolved the issue. Please help me with what is causing the issue and how to resolve this.
Note: I upgraded Tomcat from 7 to 9 along with Java from 8 to 11.
Thanks in advance.

Related

How To Configure log4j2.xml for HTTP-Appender

I need assistance in configuring HTTP-Appender in log4j2.xml. I have made multiple attempt to configure it using both JSONLayout and PatternLayout, neither worked. Here is my code snippet.
<Http name="HTTP_APPENDER" url="http://localhost:8080/test/logRest" method="POST">
<Property name="x-java-runtime" value="$${java:runtime}" />
<PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n"/>
</Http>
=====================================================================
#RequestMapping(value = "/logRest", method = RequestMethod.POST)
public void logRest(HttpServletRequest request,HttpServletResponse response, Model model){
Enumeration<String> y = request.getHeaderNames();
while (y.hasMoreElements()) {
String param = y.nextElement();
String value = request.getHeader(param);
System.out.println(param + "=" + value);
}
System.out.println("====================================");
Enumeration<String> x = request.getParameterNames();
while (x.hasMoreElements()) {
String param = x.nextElement();
String value = request.getParameter(param);
System.out.println(param + "=" + value);
}
}
==================================================================
I need to get the logged data, but it's not showing in the header,parameter or even the request attributes. I will appreciate any form of assistance to get the logged data sent to the URL endpoint.
Cheers.
See the solution below
/**
* Reads the request body from the request and returns it as a String.
*
* #param request HttpServletRequest that contains the request body
* #return request body as a String or null
*/
private String readRequestBody(HttpServletRequest request) {
try {
// Read from request
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (Exception e) {
//logger.error("Failed to read the request body from the request.");
}
return null;
}

How to check if public X509Certificate is trusted

I've signed XML which I validate by code below
<ThreeDSecure>
<Message id="pareq_1514467844949">
<PARes id="WkTyB5IWvmwx1d846aVCTg">
<version>1.0.2</version>
<Merchant>
<acqBIN>454589</acqBIN>
<merID>P2P_WEB</merID>
</Merchant>
<Purchase>
<xid>MTUxNDQ2Nzg0NDk0OTAwMDAwMDA=</xid>
<date>20171228 16:30:44</date>
<purchAmount>1000</purchAmount>
<currency>810</currency>
<exponent>2</exponent>
</Purchase>
<pan>0000000000002635</pan>
<TX>
<time>20171228 13:31:04</time>
<status>Y</status>
<cavv>AAABB3YieEkDliVhUyJ4AAAAAAA=</cavv>
<eci>05</eci>
<cavvAlgorithm>2</cavvAlgorithm>
</TX>
</PARes>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
<Reference URI="#WkTyB5IWvmwx1d846aVCTg">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>vjiyJgkYUPKeX79NBcvZNcZuH7g=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>LcITisdhnjQSLaQnL/VPg8EWCFbmfDhDpOLo8xGntbcCiubVCi6o+luhu38JA2Vo8G8fcSTH/2GvkFm1NTeOyzHDlqV5LCKXY+gNX8U+Toot+TYux9QQ0Ro1D5T2152Sn86SARNyOsnOxSzf7I0+/sAfaCD2kjbNyZb5YWPNvezM9iMaJVgLhZmAZCUmnb9vBP9HXAgEm5E2pSUhdiaXSLcp3hnccbNsqQUlRejOCOixXPbIExiwguaqYg4XbGx9mnHTin6shHPVqfZ2MvTMjTEkf+S5+yMiXVa1Sjzt7q2iJcDoDAKu5RYrC/zxjZqlNxWzeMqHbeFARUA3eRaQwQ==</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIFOjCCBCKgAwIBAgIQd/2aPtSfIJO8W8DTHLSRPTANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xIjAgBgNVBAMTGVZpc2EgZUNvbW1lcmNlIElzc3VpbmcgQ0EwHhcNMTYxMTAyMjAwNjIxWhcNMTgxMTAyMjAwNjIxWjBsMQ8wDQYDVQQHEwZNb3Njb3cxDzANBgNVBAgTBlJ1c3NpYTELMAkGA1UEBhMCUlUxEDAOBgNVBAoTB0JJTkJBTksxEDAOBgNVBAsTB0JJTkJBTksxFzAVBgNVBAMTDlZlcmlmaWVkQnlWaXNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7eXO8hN2IQh26zBkJ7zh4ckR3kTLK613smqmVggNJ4GweXHuMEhhlc+cYcOAO6pniMlzaWxDyexXg+2JSVrbvW15bsHYbYHaot2ZndOvvELL79SNe3pPv3vMuZLeXwJ4KNsV26/PIbK2Mc+Eo9FlkQbl5E1kY07N/5g4K/+/o7WjcsVizdp467AJebGduO9xYyQbG17SzXUjzwICBzBPRsgsan3PJuYctJjHbTIwoNnNr82ZYVkeRE7yOo/QroB5sDeNnVTgSOUYaM4qHbbGVUy3Zc+qyq4p6Km+EcKCRjxGpShPRZPKKvyHlUOgwlMk/oX7BQ4sDJ3EmnH1uaLVCQIDANfJo4IB0TCCAc0wZQYIKwYBBQUHAQEEWTBXMCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC52aXNhLmNvbS9vY3NwMC4GCCsGAQUFBzAChiJodHRwOi8vZW5yb2xsLnZpc2FjYS5jb20vZWNvbW0uY2VyMB8GA1UdIwQYMBaAFN/DKlUuL0I6ekCdkqD3R3nXj4eKMAwGA1UdEwEB/wQCMAAwgcoGA1UdHwSBwjCBvzAooCagJIYiaHR0cDovL0Vucm9sbC52aXNhY2EuY29tL2VDb21tLmNybDCBkqCBj6CBjIaBiWxkYXA6Ly9FbnJvbGwudmlzYWNhLmNvbTozODkvY249VmlzYSBlQ29tbWVyY2UgSXNzdWluZyBDQSxjPVVTLG91PVZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2aWNlIEFzc29jaWF0aW9uLG89VklTQT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0MA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQUm3YBohISsKwqb9YvSJ3ponmhTyowOQYDVR0gBDIwMDAuBgVngQMBATAlMCMGCCsGAQUFBwIBFhdodHRwOi8vd3d3LnZpc2EuY29tL3BraTANBgkqhkiG9w0BAQsFAAOCAQEABJhweDeYad6xAwRkYEbh1aFNzjKA0U/pHcFHUx1EQlcMcdi0G3sl6TrVh9GMi5DIe4uuoH8d3uBPS/AOGtvo/9Qnx7O423bAKkD56G5xJZYGrgTeh97SbIRdsiltnECehCGfUdtyiAirWzs7kcWgmMFDaGjk/GPra7dAkfCTuH68zwv79ae/z855/xoqbyeXu/B1oJ0ccd1YFNa+HwKcgkjOPFWrL1MEMRFK986Ic7ipnoooKBe1PyQCUc0hIUZ52tKy2pbNp/JoxpspNO+XJvCe6fa5lxAht70/V2xIh1xXOv77dkgnWfMP3aNPoj+HhMpBudNcxlCqlnoG5rd2WQ==</X509Certificate><X509Certificate>MIIFGzCCBAOgAwIBAgIRANLvVGMwl5OFbHV13pkMjIUwDQYJKoZIhvcNAQEFBQAwazELMAkGA1UEBhMCVVMxDTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2aWNlIEFzc29jaWF0aW9uMRwwGgYDVQQDExNWaXNhIGVDb21tZXJjZSBSb290MB4XDTExMDMyMTE3MzMzN1oXDTIyMDYyMjIzMTYzN1owcTELMAkGA1UEBhMCVVMxDTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2aWNlIEFzc29jaWF0aW9uMSIwIAYDVQQDExlWaXNhIGVDb21tZXJjZSBJc3N1aW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArkmC50Q+GkmQyZ29kKxp1d+nJ43JwXhGZ7aFF1PiM5SlCESQ22qV/lBA3wHYYP8i17/GQQYNBiF3u4r6juXIHFwjwvKyFMF6kmBYXvcQa8Pd75FC1n3ffIrhEj+ldbmxidzK0hPfYyXEZqDpHhkunmvD7qz1BEWKE7NUYVFREfopViflKiVZcYrHi7CJAeBNY7dygvmIMnHUeH4NtDS5qf/n9DQQffVyn5hJWi5PeB87nTlty8zdji2tj7nA2+Y3PLKRJU3y1IbchqGlnXqxaaKfkTLNsiZq9PTwKaryH+um3tXf5u4mulzRGOWh2U+Uk4LntmMFCb/LqJkWnUVe+wIDAQABo4IBsjCCAa4wHwYDVR0jBBgwFoAUFTiDDz8sP3AzHs1G/geMIODXw7cwEgYDVR0TAQH/BAgwBgEB/wIBADA5BgNVHSAEMjAwMC4GBWeBAwEBMCUwIwYIKwYBBQUHAgEWF2h0dHA6Ly93d3cudmlzYS5jb20vcGtpMIIBCwYDVR0fBIIBAjCB/zA2oDSgMoYwaHR0cDovL0Vucm9sbC52aXNhY2EuY29tL1Zpc2FDQWVDb21tZXJjZVJvb3QuY3JsMDygOqA4hjZodHRwOi8vd3d3LmludGwudmlzYWNhLmNvbS9jcmwvVmlzYUNBZUNvbW1lcmNlUm9vdC5jcmwwgYaggYOggYCGfmxkYXA6Ly9FbnJvbGwudmlzYWNhLmNvbTozODkvY249VmlzYSBlQ29tbWVyY2UgUm9vdCxvPVZJU0Esb3U9VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFN/DKlUuL0I6ekCdkqD3R3nXj4eKMA0GCSqGSIb3DQEBBQUAA4IBAQAl3lDasc/q3yjspKOIgONgNnAgX3JCOqFtapWU1LJHLVyV47RhgKV7/Kj2m3vYFsyp+Uwis4aQM6sA7w3CHoJoWDg6OjhWUuhoIbMNR8BnNmN+ic3+IG9rUm2eFNz8r/QoUDFRPQGFD/NtIqvx9m+hk+8p7HS8aLaOPxNjPzmes96qIjBD+n0xJSu+F+3gWx7b5B6qTHq3jsA5kji2K5pSLN+v/bJriS5GNkTLzLSSWLNaKQ8fPmhlJnO4Z1x9zuZTKsepiNDA6TrpUaYDyzR15aWiO+rdElFEjl8BhDtMVK+3ncfcFV7BVZ75CGp/gzopwUtT8ORhW3+o7jrfu7zK</X509Certificate><X509Certificate>MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8 bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt398znM/jra6O1I7mT1GvFpLgXPYHDw==</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</Message>
</ThreeDSecure>
Validation xml signature
private void getSignature (String xmlDoc){
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlDoc));
Document doc = builder.parse(is);
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
throw new Exception("Cannot find Signature element");
}
// Overwrite ID
NodeList elList = doc.getElementsByTagName("PARes");
if (elList != null && elList.getLength() > 0 && ((Element)elList.item(0)).hasAttribute("id")) {
Attr id = ((Element)elList.item(0)).getAttributeNode("id");
((Element)elList.item(0)).setIdAttributeNode(id, true);
}
DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(), nl.item(0));
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
// Unmarshal the XMLSignature.
XMLSignature signature = factory.unmarshalXMLSignature(valContext);
// Validate the XMLSignature.
boolean coreValidity = signature.validate(valContext);
log.error("Validated :" + (coreValidity?"True":"False"));
} catch (Exception e){
log.error("Exception : "+e.getMessage());
}
}
public class X509KeySelector extends KeySelector {
public KeySelectorResult select(KeyInfo keyInfo,
KeySelector.Purpose purpose,
AlgorithmMethod method,
XMLCryptoContext context)
throws KeySelectorException {
Iterator ki = keyInfo.getContent().iterator();
while (ki.hasNext()) {
XMLStructure info = (XMLStructure) ki.next();
if (!(info instanceof X509Data))
continue;
X509Data x509Data = (X509Data) info;
Iterator xi = x509Data.getContent().iterator();
while (xi.hasNext()) {
Object o = xi.next();
if (!(o instanceof X509Certificate))
continue;
final PublicKey key = ((X509Certificate)o).getPublicKey();
// Make sure the algorithm is compatible
// with the method.
if (algEquals(method.getAlgorithm(), key.getAlgorithm())) {
return new KeySelectorResult() {
public Key getKey() {
return key;
}
};
}
}
}
throw new KeySelectorException("No key found!");
}
private static boolean algEquals(String algURI, String algName) {
if ((algName.equalsIgnoreCase("DSA") &&
algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) ||
(algName.equalsIgnoreCase("RSA") &&
algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1))) {
return true;
} else {
return false;
}
}
Everything is ok, but I should check that public key is trusted.XML's signed by different issuers. I have jssecacerts which contain 14 root CA. How to verify that this public key was signed one of this CA. Thank you for your advices
I've found decision
private boolean checkServerTrusted(X509Certificate cert) throws KeySelectorException {
try {
final File file = new File("C:\\TMP\\jssecacerts");
InputStream inStream = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance("JKS");
//String password = "";
//keystore.load(inStream, password.toCharArray());
keystore.load(inStream, null);
X509Certificate[] certs = new X509Certificate[keystore.size()];
int i = 0;
Enumeration<String> alias = keystore.aliases();
while (alias.hasMoreElements()) {
certs[i++] = (X509Certificate) keystore.getCertificate(alias
.nextElement());
}
return validateKeyChain(cert, certs);
} catch (Exception e){
throw new KeySelectorException ("Key verify exception reason :"+ e.getMessage());
}
}
/**
* Validate keychain
* #param client is the client X509Certificate
* #param trustedCerts is Array containing all trusted X509Certificate
* #return true if validation until root certificate success, false otherwise
* #throws CertificateException
* #throws InvalidAlgorithmParameterException
* #throws NoSuchAlgorithmException
* #throws NoSuchProviderException
*/
private boolean validateKeyChain(X509Certificate client,
X509Certificate... trustedCerts) throws CertificateException,
InvalidAlgorithmParameterException, NoSuchAlgorithmException,
NoSuchProviderException {
boolean found = false;
int i = trustedCerts.length;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
TrustAnchor anchor;
Set anchors;
CertPath path;
List list;
PKIXParameters params;
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
while (!found && i > 0) {
anchor = new TrustAnchor(trustedCerts[--i], null);
anchors = Collections.singleton(anchor);
list = Arrays.asList(new Certificate[] { client });
path = cf.generateCertPath(list);
params = new PKIXParameters(anchors);
params.setRevocationEnabled(false);
if (client.getIssuerDN().equals(trustedCerts[i].getSubjectDN())) {
try {
validator.validate(path, params);
if (isSelfSigned(trustedCerts[i])) {
// found root ca
found = true;
System.out.println("validating root" + trustedCerts[i].getSubjectX500Principal().getName());
} else if (!client.equals(trustedCerts[i])) {
// find parent ca
System.out.println("validating via:" + trustedCerts[i].getSubjectX500Principal().getName());
found = validateKeyChain(trustedCerts[i], trustedCerts);
}
} catch (CertPathValidatorException e) {
// validation fail, check next certificate in the trustedCerts array
}
}
}
return found;
}
/**
*
* #param cert is X509Certificate that will be tested
* #return true if cert is self signed, false otherwise
* #throws CertificateException
* #throws NoSuchAlgorithmException
* #throws NoSuchProviderException
*/
private boolean isSelfSigned(X509Certificate cert)
throws CertificateException, NoSuchAlgorithmException,
NoSuchProviderException {
try {
PublicKey key = cert.getPublicKey();
cert.verify(key);
return true;
} catch (SignatureException sigEx) {
return false;
} catch (InvalidKeyException keyEx) {
return false;
}
}

CSV File Not Being Read from Servlet

As the title says, I have a CSV file that will not load from within my web application. I am using Netbeans to build the project.
Whenever I launch the project from Netbeans, it works like it should however when I take the war file and try to deploy it from within the Glassfish interface it shows the variables as undefined which tells me that it is not reading the file. Screenshots below show what is happening and my folder structure.
I have read many posts here and #BalusC has some great information here, but its not working for me and I believe this is somehow my fault, but I need a bit more specific help here than just reading another post.
I have put the CSV file that I am intending to load into the /src/main/resources folder as noted here by BalusC. The code I am using to load the file is as follows.
As a side note, I have a JSP that I am using to check the location and access to the file. The JSP can access and display the file without any problems when the application is deployed manually.
Edit: I ran a debug and could not find anything wrong, so I ran glassfish in verbose mode and loaded the page, once the page was up, it started reading from the file and sending the data but still shows "undefined" in all fields.
Here is the output data from running glassfish in verbose mode.
[#|2017-05-05T16:34:37.609+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=33;_ThreadName=http-listener-1(3);_TimeMillis=1493969677609;_LevelValue=800;|
Connection open.|#]
[#|2017-05-05T16:34:38.014+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=109;_ThreadName=__ejb-thread-pool3;_TimeMillis=1493969678014;_LevelValue=800;|
Sent: ABRN / Arbor Realty Trust 7.375% Senior / 25.32 / 25.11 / 25.24 / 12000 / 24.27 / 26.15 / Fri May 05 16:34:38 JST 2017|#]
[#|2017-05-05T16:34:38.016+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=109;_ThreadName=__ejb-thread-pool3;_TimeMillis=1493969678016;_LevelValue=800;|
Connection closed.|#]
[#|2017-05-05T16:34:38.024+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=34;_ThreadName=http-listener-1(4);_TimeMillis=1493969678024;_LevelValue=800;|
Connection open.|#]
[#|2017-05-05T16:34:38.029+0900|INFO|glassfish 4.1|DukeETFServlet|_ThreadID=119;_ThreadName=__ejb-thread-pool4;_TimeMillis=1493969678029;_LevelValue=800;|
Sent: ABT / Abbott Laboratories / 44.01 / 43.60 / 43.65 / 7487400 / 36.76 / 45.84 / Fri May 05 16:34:38 JST 2017|#]
Here is the data for loading the file.
Servlet
#WebServlet(urlPatterns={"/dukeetf"}, asyncSupported=true)
public class DukeETFServlet extends HttpServlet {
private static final Logger logger = Logger.getLogger("DukeETFServlet");
private static final long serialVersionUID = 2114153638027156979L;
private Queue<AsyncContext> requestQueue;
#EJB private PriceVolumeBean pvbean;
#Override
public void init(ServletConfig config) {
/* Queue for requests */
requestQueue = new ConcurrentLinkedQueue<>();
/* Register with the bean that provides price/volume updates */
pvbean.registerServlet(this);
}
/* PriceVolumeBean calls this method every second to send updates */
public void send(String ticker, String name, float highPrice, float lowPrice,
float closingPrice, int volume, float fiftyTwoWeekHigh, float fiftyTwoWeekLow,
String currentTime) {
/* Send update to all connected clients */
for (AsyncContext acontext : requestQueue) {
try {
String msg = String.format("%s / %s / %.2f / %.2f / %.2f / %d /"
+ " %.2f / %.2f / %s",
ticker, name, highPrice, lowPrice, closingPrice, volume,
fiftyTwoWeekHigh, fiftyTwoWeekLow, currentTime);
PrintWriter writer = acontext.getResponse().getWriter();
writer.write(msg);
logger.log(Level.INFO, "Sent: {0}", msg);
/* Close the connection
* The client (JavaScript) makes a new one instantly */
acontext.complete();
} catch (IOException ex) {
logger.log(Level.INFO, ex.toString());
}
}
}
/* Service method */
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
/* Put request in async mode. */
final AsyncContext acontext = request.startAsync();
/* Remove from the queue when done */
acontext.addListener(new AsyncListener() {
#Override
public void onComplete(AsyncEvent ae) throws IOException {
requestQueue.remove(acontext);
logger.log(Level.INFO, "Connection Being Closed.");
}
#Override
public void onTimeout(AsyncEvent ae) throws IOException {
requestQueue.remove(acontext);
logger.log(Level.INFO, "Connection Has Timed Out.");
}
#Override
public void onError(AsyncEvent ae) throws IOException {
requestQueue.remove(acontext);
logger.log(Level.INFO, "Connection error.");
}
#Override
public void onStartAsync(AsyncEvent ae) throws IOException { }
});
/* Add to the queue */
requestQueue.add(acontext);
logger.log(Level.INFO, "Connection Being Opened.");
}
}
Class to get information from CSV
//Get Stock Data From CSV File
public static ArrayList<Stock> getListOfStocks() throws IOException {
ArrayList<Stock> stocks = new ArrayList();
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
InputStream is =
StockService.class.getResourceAsStream("/stockdata.csv");
// create an instance of BufferedReader
// using try with resource, Java 7 feature to close resources
try (CSVReader reader = new CSVReader(new InputStreamReader(is))) {
// read the first line from the text file
String[] nextLine;
reader.readNext();
// loop until all lines are read
while ((nextLine = reader.readNext()) != null) {
Stock newStock = new Stock(nextLine[0], nextLine[1],
Float.valueOf(nextLine[2]), Float.valueOf(nextLine[3]),
Float.valueOf(nextLine[4]), Integer.valueOf(nextLine[5]),
Float.valueOf(nextLine[6]), Float.valueOf(nextLine[7]));
stocks.add(newStock);
}
}
return stocks;
}
Bean that retrieves and sends information
/* Updates price and volume information every second */
#Startup
#Singleton
public class PriceVolumeBean {
/* Use the container's timer service */
#Resource TimerService tservice;
private DukeETFServlet servlet;
//Set Variable for Counter
private int i = 0;
//Set date time variable
String currentTime;
//Set Variables for Stock Data
private String ticker;
private String name;
private float highPrice;
private float lowPrice;
private float closingPrice;
private int volume;
private float fiftyTwoWeekHigh;
private float fiftyTwoWeekLow;
private static final Logger logger = Logger.getLogger("PriceVolumeBean");
#PostConstruct
public void init() {
/* Intialize the EJB and create a timer */
logger.log(Level.INFO, "Initializing EJB.");
servlet = null;
tservice.createIntervalTimer(2000, 2000, new TimerConfig());
}
public void registerServlet(DukeETFServlet servlet) {
/* Associate a servlet to send updates to */
this.servlet = servlet;
}
#Timeout
public void timeout() throws IOException {
// Update Date
Date date = new Date();
// Set stock variables //
ticker = StockService.getListOfStocks().get(i).getTicker();
name = StockService.getListOfStocks().get(i).getName();
highPrice = StockService.getListOfStocks().get(i).getHighPrice();
lowPrice = StockService.getListOfStocks().get(i).getLowPrice();
closingPrice = StockService.getListOfStocks().get(i).getClosingPrice();
volume = StockService.getListOfStocks().get(i).getVolume();
fiftyTwoWeekHigh = StockService.getListOfStocks().get(i).getFiftyTwoWeekHigh();
fiftyTwoWeekLow = StockService.getListOfStocks().get(i).getFiftyTwoWeekLow();
currentTime = date.toString();
// Send updated information
if (servlet != null)
servlet.send(ticker, name, highPrice, lowPrice, closingPrice,
volume, fiftyTwoWeekHigh, fiftyTwoWeekLow, currentTime);
// Counter that keeps from going beyond size of arraylist
i++;
if (i == 100) {
i = 0;
}
}
}

crawler4j compile error with class CrawlConfig - VariableDeclaratorId Expected

The code will not compile. I changed the JRE to 1.7. The compiler does not highlight the class in Eclipse and the CrawlConfig appears to fail in the compiler. The class should be run from the command line in Linux.
Any ideas?
Compiler Error -
Description Resource Path Location Type
Syntax error on token "crawlStorageFolder", VariableDeclaratorId expected after this token zeocrawler.java /zeowebcrawler/src/main/java/com/example line 95 Java Problem
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
import edu.uci.ics.crawler4j.crawler.CrawlController;
import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
import edu.uci.ics.crawler4j.parser.HtmlParseData;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
import edu.uci.ics.crawler4j.url.WebURL;
public class Controller {
String crawlStorageFolder = "/data/crawl/root";
int numberOfCrawlers = 7;
CrawlConfig config = new CrawlConfig();
config.setCrawlStorageFolder(crawlStorageFolder);
PageFetcher pageFetcher = new PageFetcher(config);
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
controller.addSeed("http://www.senym.com");
controller.addSeed("http://www.merrows.co.uk");
controller.addSeed("http://www.zeoic.com");
controller.start(MyCrawler.class, numberOfCrawlers);
}
public URLConnection connectURL(String strURL) {
URLConnection conn =null;
try {
URL inputURL = new URL(strURL);
conn = inputURL.openConnection();
int test = 0;
}catch(MalformedURLException e) {
System.out.println("Please input a valid URL");
}catch(IOException ioe) {
System.out.println("Can not connect to the URL");
}
return conn;
}
public static void updatelongurl()
{
// System.out.println("Short URL: "+ shortURL);
// urlConn = connectURL(shortURL);
// urlConn.getHeaderFields();
// System.out.println("Original URL: "+ urlConn.getURL());
/* connectURL - This function will take a valid url and return a
URL object representing the url address. */
}
public class MyCrawler extends WebCrawler {
private Pattern FILTERS = Pattern.compile(".*(\\.(css|js|bmp|gif|jpe?g"
+ "|png|tiff?|mid|mp2|mp3|mp4"
+ "|wav|avi|mov|mpeg|ram|m4v|pdf"
+ "|rm|smil|wmv|swf|wma|zip|rar|gz))$");
/**
* You should implement this function to specify whether
* the given url should be crawled or not (based on your
* crawling logic).
*/
#Override
public boolean shouldVisit(WebURL url) {
String href = url.getURL().toLowerCase();
return !FILTERS.matcher(href).matches() && href.startsWith("http://www.ics.uci.edu/");
}
/**
* This function is called when a page is fetched and ready
* to be processed by your program.
*/
#Override
public void visit(Page page) {
String url = page.getWebURL().getURL();
System.out.println("URL: " + url);
if (page.getParseData() instanceof HtmlParseData) {
HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
String text = htmlParseData.getText();
String html = htmlParseData.getHtml();
List<WebURL> links = htmlParseData.getOutgoingUrls();
System.out.println("Text length: " + text.length());
System.out.println("Html length: " + html.length());
System.out.println("Number of outgoing links: " + links.size());
}
}
}
This is a pretty strange error since the code seems to be clean. Try to start eclipse with the -clean option on command line.
Change
String crawlStorageFolder = "/data/crawl/root";
to
String crawlStorageFolder = "./data/crawl/root";
i.e. add a leading .

parse dicomdir to display available images

We are thinking to add image management function by parse the existing dicomdir file and display the content with a tree structure. The existing application is using Java with Dcm4Che.
My qestion is how to parse the dicomdir file to get enough information to display its content in Java tree?
More Refer here :: DICOMDIR READ IMAGES
public void getFilePath(DicomObject firstRecord) throws IOException {
int i = 1;
for (DicomObject rec = firstRecord; rec != null; rec = dicomDir
.findNextSiblingRecord(rec), ++i) {
if (rec.get(Tag.ReferencedFileID) != null) {
File f = dicomDir.toReferencedFile(rec);
System.out.println(f.getAbsolutePath());
}
getFilePath(dicomDir.findFirstChildRecord(rec));
}
Click Here for Same Code
private DicomDirReader dirReader;
public ReadDicomDir(File file) throws IOException {
dirReader = new DicomDirReader(file);
}
public List<File> getFiles() throws IOException {
List<File> listDirFiles = new ArrayList<File>();
getFilePath(dirReader.findFirstRootRecord(), listDirFiles);
return listDirFiles;
}
/**
* Get Filepath of Dicom File
*
* #param firstRecord
* #param listDirFiles
* #throws IOException
*/
public void getFilePath(DicomObject firstRecord, List<File> listDirFiles)
throws IOException {
int i = 1;
for (DicomObject rec = firstRecord; rec != null; rec = dirReader
.findNextSiblingRecord(rec), ++i) {
if (rec.contains(Tag.ReferencedFileID)) {
File f = dirReader.toReferencedFile(rec);
// System.out.println(f.getAbsolutePath());
listDirFiles.add(f);
}
getFilePath(dirReader.findFirstChildRecord(rec), listDirFiles);
}

Resources