Search in sources :

Example 16 with JsonException

use of javax.json.JsonException in project sling by apache.

the class ResourceInventoryPrinterFactory method print.

/**
     * @see org.apache.felix.inventory.InventoryPrinter#print(java.io.PrintWriter, org.apache.felix.inventory.Format, boolean)
     */
@Override
public void print(PrintWriter printWriter, Format format, boolean isZip) {
    if (this.path == null || !format.equals(Format.JSON)) {
        return;
    }
    ResourceResolver resolver = null;
    try {
        resolver = factory.getAdministrativeResourceResolver(null);
        final Resource rootResource = resolver.getResource(this.path);
        if (rootResource != null) {
            final ResourceTraversor rt = new ResourceTraversor(rootResource);
            rt.collectResources();
            StringWriter writer = new StringWriter();
            Json.createGenerator(writer).write(rt.getJsonObject()).close();
            printWriter.write(writer.toString());
        }
    } catch (final LoginException e) {
    // ignore
    } catch (final JsonException ignore) {
        LoggerFactory.getLogger(this.getClass()).warn("Unable to create resource json", ignore);
    } finally {
        if (resolver != null) {
            resolver.close();
        }
    }
}
Also used : JsonException(javax.json.JsonException) StringWriter(java.io.StringWriter) ResourceResolver(org.apache.sling.api.resource.ResourceResolver) Resource(org.apache.sling.api.resource.Resource) LoginException(org.apache.sling.api.resource.LoginException)

Example 17 with JsonException

use of javax.json.JsonException in project sling by apache.

the class AdapterWebConsolePlugin method addBundle.

@SuppressWarnings("unchecked")
private void addBundle(final Bundle bundle) {
    final List<AdaptableDescription> descs = new ArrayList<>();
    try {
        final Enumeration<URL> files = bundle.getResources("SLING-INF/adapters.json");
        if (files != null) {
            while (files.hasMoreElements()) {
                final InputStream stream = files.nextElement().openStream();
                final String contents = IOUtils.toString(stream);
                IOUtils.closeQuietly(stream);
                Map<String, Object> config = new HashMap<>();
                config.put("org.apache.johnzon.supports-comments", true);
                final JsonObject obj = Json.createReaderFactory(config).createReader(new StringReader(contents)).readObject();
                for (final Iterator<String> adaptableNames = obj.keySet().iterator(); adaptableNames.hasNext(); ) {
                    final String adaptableName = adaptableNames.next();
                    final JsonObject adaptable = obj.getJsonObject(adaptableName);
                    for (final Iterator<String> conditions = adaptable.keySet().iterator(); conditions.hasNext(); ) {
                        final String condition = conditions.next();
                        String[] adapters;
                        final Object value = adaptable.get(condition);
                        if (value instanceof JsonArray) {
                            adapters = toStringArray((JsonArray) value);
                        } else {
                            adapters = new String[] { unbox(value).toString() };
                        }
                        descs.add(new AdaptableDescription(bundle, adaptableName, adapters, condition, false));
                    }
                }
            }
        }
        if (!descs.isEmpty()) {
            synchronized (this) {
                adapterBundles.put(bundle, descs);
                update();
            }
        }
    } catch (final IOException e) {
        logger.error("Unable to load adapter descriptors for bundle " + bundle, e);
    } catch (final JsonException e) {
        logger.error("Unable to load adapter descriptors for bundle " + bundle, e);
    } catch (IllegalStateException e) {
        logger.debug("Unable to load adapter descriptors for bundle " + bundle);
    }
}
Also used : JsonException(javax.json.JsonException) HashMap(java.util.HashMap) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) JsonObject(javax.json.JsonObject) JsonString(javax.json.JsonString) IOException(java.io.IOException) URL(java.net.URL) JsonArray(javax.json.JsonArray) StringReader(java.io.StringReader) JsonObject(javax.json.JsonObject)

Example 18 with JsonException

use of javax.json.JsonException in project sling by apache.

the class TopologyConnectorClient method ping.

/** ping the server and pass the announcements between the two **/
void ping(final boolean force) {
    if (autoStopped) {
        // then we suppress any further pings!
        logger.debug("ping: autoStopped=true, hence suppressing any further pings.");
        return;
    }
    if (force) {
        backoffPeriodEnd = -1;
    } else if (backoffPeriodEnd > 0) {
        if (System.currentTimeMillis() < backoffPeriodEnd) {
            logger.debug("ping: not issueing a heartbeat due to backoff instruction from peer.");
            return;
        } else {
            logger.debug("ping: backoff period ended, issuing another ping now.");
        }
    }
    final String uri = connectorUrl.toString() + "." + clusterViewService.getSlingId() + ".json";
    if (logger.isDebugEnabled()) {
        logger.debug("ping: connectorUrl=" + connectorUrl + ", complete uri=" + uri);
    }
    final HttpClientContext clientContext = HttpClientContext.create();
    final CloseableHttpClient httpClient = createHttpClient();
    final HttpPut putRequest = new HttpPut(uri);
    // setting the connection timeout (idle connection, configured in seconds)
    putRequest.setConfig(RequestConfig.custom().setConnectTimeout(1000 * config.getSocketConnectTimeout()).build());
    Announcement resultingAnnouncement = null;
    try {
        String userInfo = connectorUrl.getUserInfo();
        if (userInfo != null) {
            Credentials c = new UsernamePasswordCredentials(userInfo);
            clientContext.getCredentialsProvider().setCredentials(new AuthScope(putRequest.getURI().getHost(), putRequest.getURI().getPort()), c);
        }
        Announcement topologyAnnouncement = new Announcement(clusterViewService.getSlingId());
        topologyAnnouncement.setServerInfo(serverInfo);
        final ClusterView clusterView;
        try {
            clusterView = clusterViewService.getLocalClusterView();
        } catch (UndefinedClusterViewException e) {
            // SLING-5030 : then we cannot ping
            logger.warn("ping: no clusterView available at the moment, cannot ping others now: " + e);
            return;
        }
        topologyAnnouncement.setLocalCluster(clusterView);
        if (force) {
            logger.debug("ping: sending a resetBackoff");
            topologyAnnouncement.setResetBackoff(true);
        }
        announcementRegistry.addAllExcept(topologyAnnouncement, clusterView, new AnnouncementFilter() {

            public boolean accept(final String receivingSlingId, final Announcement announcement) {
                // filter out announcements that are of old cluster instances
                // which I dont really have in my cluster view at the moment
                final Iterator<InstanceDescription> it = clusterView.getInstances().iterator();
                while (it.hasNext()) {
                    final InstanceDescription instance = it.next();
                    if (instance.getSlingId().equals(receivingSlingId)) {
                        // all fine then
                        return true;
                    }
                }
                // then I should also not propagate that announcement anywhere
                return false;
            }
        });
        final String p = requestValidator.encodeMessage(topologyAnnouncement.asJSON());
        if (logger.isDebugEnabled()) {
            logger.debug("ping: topologyAnnouncement json is: " + p);
        }
        requestValidator.trustMessage(putRequest, p);
        if (config.isGzipConnectorRequestsEnabled()) {
            // tell the server that the content is gzipped:
            putRequest.addHeader("Content-Encoding", "gzip");
            // and gzip the body:
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            final GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
            gzipOut.write(p.getBytes("UTF-8"));
            gzipOut.close();
            final byte[] gzippedEncodedJson = baos.toByteArray();
            putRequest.setEntity(new ByteArrayEntity(gzippedEncodedJson, ContentType.APPLICATION_JSON));
            lastRequestEncoding = "gzip";
        } else {
            // otherwise plaintext:
            final StringEntity plaintext = new StringEntity(p, "UTF-8");
            plaintext.setContentType(ContentType.APPLICATION_JSON.getMimeType());
            putRequest.setEntity(plaintext);
            lastRequestEncoding = "plaintext";
        }
        // independent of request-gzipping, we do accept the response to be gzipped,
        // so indicate this to the server:
        putRequest.addHeader("Accept-Encoding", "gzip");
        final CloseableHttpResponse response = httpClient.execute(putRequest, clientContext);
        if (logger.isDebugEnabled()) {
            logger.debug("ping: done. code=" + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase());
        }
        lastStatusCode = response.getStatusLine().getStatusCode();
        lastResponseEncoding = null;
        if (response.getStatusLine().getStatusCode() == HttpServletResponse.SC_OK) {
            final Header contentEncoding = response.getFirstHeader("Content-Encoding");
            if (contentEncoding != null && contentEncoding.getValue() != null && contentEncoding.getValue().contains("gzip")) {
                lastResponseEncoding = "gzip";
            } else {
                lastResponseEncoding = "plaintext";
            }
            // limiting to 16MB, should be way enough
            final String responseBody = requestValidator.decodeMessage(putRequest.getURI().getPath(), response);
            if (logger.isDebugEnabled()) {
                logger.debug("ping: response body=" + responseBody);
            }
            if (responseBody != null && responseBody.length() > 0) {
                Announcement inheritedAnnouncement = Announcement.fromJSON(responseBody);
                final long backoffInterval = inheritedAnnouncement.getBackoffInterval();
                if (backoffInterval > 0) {
                    // then reset the backoffPeriodEnd:
                    /* minus 1 sec to avoid slipping the interval by a few millis */
                    this.backoffPeriodEnd = System.currentTimeMillis() + (1000 * backoffInterval) - 1000;
                    logger.debug("ping: servlet instructed to backoff: backoffInterval=" + backoffInterval + ", resulting in period end of " + new Date(backoffPeriodEnd));
                } else {
                    logger.debug("ping: servlet did not instruct any backoff-ing at this stage");
                    this.backoffPeriodEnd = -1;
                }
                if (inheritedAnnouncement.isLoop()) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("ping: connector response indicated a loop detected. not registering this announcement from " + inheritedAnnouncement.getOwnerId());
                    }
                    if (inheritedAnnouncement.getOwnerId().equals(clusterViewService.getSlingId())) {
                        if (config.isAutoStopLocalLoopEnabled()) {
                            // results in connected -> false and representsloop -> true
                            inheritedAnnouncement = null;
                            // results in isAutoStopped -> true
                            autoStopped = true;
                        }
                    }
                } else {
                    inheritedAnnouncement.setInherited(true);
                    if (announcementRegistry.registerAnnouncement(inheritedAnnouncement) == -1) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("ping: connector response is from an instance which I already see in my topology" + inheritedAnnouncement);
                        }
                        statusDetails = "receiving side is seeing me via another path (connector or cluster) already (loop)";
                        return;
                    }
                }
                resultingAnnouncement = inheritedAnnouncement;
                statusDetails = null;
            } else {
                statusDetails = "no response body received";
            }
        } else {
            statusDetails = "got HTTP Status-Code: " + lastStatusCode;
        }
        // SLING-2882 : reset suppressPingWarnings_ flag in success case
        suppressPingWarnings_ = false;
    } catch (IOException e) {
        // SLING-2882 : set/check the suppressPingWarnings_ flag
        if (suppressPingWarnings_) {
            if (logger.isDebugEnabled()) {
                logger.debug("ping: got IOException: " + e + ", uri=" + uri);
            }
        } else {
            suppressPingWarnings_ = true;
            logger.warn("ping: got IOException [suppressing further warns]: " + e + ", uri=" + uri);
        }
        statusDetails = e.toString();
    } catch (JsonException e) {
        logger.warn("ping: got JSONException: " + e);
        statusDetails = e.toString();
    } catch (RuntimeException re) {
        logger.warn("ping: got RuntimeException: " + re, re);
        statusDetails = re.toString();
    } finally {
        putRequest.releaseConnection();
        lastInheritedAnnouncement = resultingAnnouncement;
        lastPingedAt = System.currentTimeMillis();
        try {
            httpClient.close();
        } catch (IOException e) {
            logger.error("disconnect: could not close httpClient: " + e, e);
        }
    }
}
Also used : ClusterView(org.apache.sling.discovery.ClusterView) JsonException(javax.json.JsonException) Announcement(org.apache.sling.discovery.base.connectors.announcement.Announcement) AnnouncementFilter(org.apache.sling.discovery.base.connectors.announcement.AnnouncementFilter) HttpPut(org.apache.http.client.methods.HttpPut) StringEntity(org.apache.http.entity.StringEntity) ByteArrayEntity(org.apache.http.entity.ByteArrayEntity) GZIPOutputStream(java.util.zip.GZIPOutputStream) Iterator(java.util.Iterator) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Date(java.util.Date) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials) Header(org.apache.http.Header) AuthScope(org.apache.http.auth.AuthScope) UndefinedClusterViewException(org.apache.sling.discovery.base.commons.UndefinedClusterViewException) InstanceDescription(org.apache.sling.discovery.InstanceDescription) Credentials(org.apache.http.auth.Credentials) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials)

Example 19 with JsonException

use of javax.json.JsonException in project sling by apache.

the class TopologyConnectorServlet method doPut.

@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if (!isWhitelisted(request)) {
        // in theory it would be 403==forbidden, but that would reveal that
        // a resource would exist there in the first place
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    final String[] pathInfo = request.getPathInfo().split("\\.");
    final String extension = pathInfo.length == 3 ? pathInfo[2] : "";
    if (!"json".equals(extension)) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    final String selector = pathInfo.length == 3 ? pathInfo[1] : "";
    String topologyAnnouncementJSON = requestValidator.decodeMessage(request);
    if (logger.isDebugEnabled()) {
        logger.debug("doPost: incoming topology announcement is: " + topologyAnnouncementJSON);
    }
    final Announcement incomingTopologyAnnouncement;
    try {
        incomingTopologyAnnouncement = Announcement.fromJSON(topologyAnnouncementJSON);
        if (!incomingTopologyAnnouncement.getOwnerId().equals(selector)) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        String slingId = clusterViewService.getSlingId();
        if (slingId == null) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            logger.info("doPut: no slingId available. Service not ready as expected at the moment.");
            return;
        }
        incomingTopologyAnnouncement.removeInherited(slingId);
        final Announcement replyAnnouncement = new Announcement(slingId);
        long backoffInterval = -1;
        ClusterView clusterView = clusterViewService.getLocalClusterView();
        if (!incomingTopologyAnnouncement.isCorrectVersion()) {
            logger.warn("doPost: rejecting an announcement from an incompatible connector protocol version: " + incomingTopologyAnnouncement);
            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        } else if (ClusterViewHelper.contains(clusterView, incomingTopologyAnnouncement.getOwnerId())) {
            if (logger.isDebugEnabled()) {
                logger.debug("doPost: rejecting an announcement from an instance that is part of my cluster: " + incomingTopologyAnnouncement);
            }
            // marking as 'loop'
            replyAnnouncement.setLoop(true);
            backoffInterval = config.getBackoffStandbyInterval();
        } else if (ClusterViewHelper.containsAny(clusterView, incomingTopologyAnnouncement.listInstances())) {
            if (logger.isDebugEnabled()) {
                logger.debug("doPost: rejecting an announcement as it contains instance(s) that is/are part of my cluster: " + incomingTopologyAnnouncement);
            }
            // marking as 'loop'
            replyAnnouncement.setLoop(true);
            backoffInterval = config.getBackoffStandbyInterval();
        } else {
            backoffInterval = announcementRegistry.registerAnnouncement(incomingTopologyAnnouncement);
            if (logger.isDebugEnabled()) {
                logger.debug("doPost: backoffInterval after registration: " + backoffInterval);
            }
            if (backoffInterval == -1) {
                if (logger.isDebugEnabled()) {
                    logger.debug("doPost: rejecting an announcement from an instance that I already see in my topology: " + incomingTopologyAnnouncement);
                }
                // marking as 'loop'
                replyAnnouncement.setLoop(true);
                backoffInterval = config.getBackoffStandbyInterval();
            } else {
                // normal, successful case: replying with the part of the topology which this instance sees
                replyAnnouncement.setLocalCluster(clusterView);
                announcementRegistry.addAllExcept(replyAnnouncement, clusterView, new AnnouncementFilter() {

                    public boolean accept(final String receivingSlingId, Announcement announcement) {
                        if (announcement.getPrimaryKey().equals(incomingTopologyAnnouncement.getPrimaryKey())) {
                            return false;
                        }
                        return true;
                    }
                });
            }
        }
        if (backoffInterval > 0) {
            replyAnnouncement.setBackoffInterval(backoffInterval);
            if (logger.isDebugEnabled()) {
                logger.debug("doPost: backoffInterval for client set to " + replyAnnouncement.getBackoffInterval());
            }
        }
        final String p = requestValidator.encodeMessage(replyAnnouncement.asJSON());
        requestValidator.trustMessage(response, request, p);
        // gzip the response if the client accepts this
        final String acceptEncodingHeader = request.getHeader("Accept-Encoding");
        if (acceptEncodingHeader != null && acceptEncodingHeader.contains("gzip")) {
            // tell the client that the content is gzipped:
            response.setHeader("Content-Encoding", "gzip");
            // then gzip the body
            final GZIPOutputStream gzipOut = new GZIPOutputStream(response.getOutputStream());
            gzipOut.write(p.getBytes("UTF-8"));
            gzipOut.close();
        } else {
            // otherwise plaintext
            final PrintWriter pw = response.getWriter();
            pw.print(p);
            pw.flush();
        }
    } catch (JsonException e) {
        logger.error("doPost: Got a JSONException: " + e, e);
        response.sendError(500);
    } catch (UndefinedClusterViewException e) {
        logger.warn("doPost: no clusterView available at the moment - cannot handle connectors now: " + e);
        // "please retry, but atm I can't help since I'm isolated"
        response.sendError(503);
    }
}
Also used : ClusterView(org.apache.sling.discovery.ClusterView) JsonException(javax.json.JsonException) Announcement(org.apache.sling.discovery.base.connectors.announcement.Announcement) GZIPOutputStream(java.util.zip.GZIPOutputStream) AnnouncementFilter(org.apache.sling.discovery.base.connectors.announcement.AnnouncementFilter) UndefinedClusterViewException(org.apache.sling.discovery.base.commons.UndefinedClusterViewException) PrintWriter(java.io.PrintWriter)

Example 20 with JsonException

use of javax.json.JsonException in project sling by apache.

the class AnnouncementRegistryImpl method registerAnnouncement.

@Override
public synchronized long registerAnnouncement(final Announcement topologyAnnouncement) {
    if (topologyAnnouncement == null) {
        throw new IllegalArgumentException("topologyAnnouncement must not be null");
    }
    if (!topologyAnnouncement.isValid()) {
        logger.warn("topologyAnnouncement is not valid");
        return -1;
    }
    if (resourceResolverFactory == null) {
        logger.error("registerAnnouncement: resourceResolverFactory is null");
        return -1;
    }
    final CachedAnnouncement cachedAnnouncement = ownAnnouncementsCache.get(topologyAnnouncement.getOwnerId());
    if (cachedAnnouncement != null) {
        if (logger.isDebugEnabled()) {
            logger.debug("registerAnnouncement: got existing cached announcement for ownerId=" + topologyAnnouncement.getOwnerId());
        }
        try {
            if (topologyAnnouncement.correspondsTo(cachedAnnouncement.getAnnouncement())) {
                // then nothing has changed with this announcement, so just update
                // the heartbeat and fine is.
                // this should actually be the normal case for a stable connector
                logger.debug("registerAnnouncement: nothing has changed, only updating heartbeat in-memory.");
                return cachedAnnouncement.registerPing(topologyAnnouncement, config);
            }
            logger.debug("registerAnnouncement: incoming announcement differs from existing one!");
        } catch (JsonException e) {
            logger.error("registerAnnouncement: got JSONException while converting incoming announcement to JSON: " + e, e);
        }
        // otherwise the repository and the cache require to be updated
        // resetting the cache therefore at this point already
        ownAnnouncementsCache.remove(topologyAnnouncement.getOwnerId());
    } else {
        logger.debug("registerAnnouncement: no cached announcement yet for ownerId=" + topologyAnnouncement.getOwnerId());
    }
    logger.debug("registerAnnouncement: getting the list of all local announcements");
    final Collection<Announcement> announcements = new LinkedList<Announcement>();
    fillWithCachedAnnouncements(announcements);
    if (logger.isDebugEnabled()) {
        logger.debug("registerAnnouncement: list returned: " + (announcements == null ? "null" : announcements.size()));
    }
    for (Iterator<Announcement> it1 = announcements.iterator(); it1.hasNext(); ) {
        Announcement announcement = it1.next();
        if (announcement.getOwnerId().equals(topologyAnnouncement.getOwnerId())) {
            // then this is from the same owner - skip this
            continue;
        }
        // analyse to see if any of the instances in the announcement
        // include the new owner
        Collection<InstanceDescription> attachedInstances = announcement.listInstances();
        for (Iterator<InstanceDescription> it2 = attachedInstances.iterator(); it2.hasNext(); ) {
            InstanceDescription instanceDescription = it2.next();
            if (topologyAnnouncement.getOwnerId().equals(instanceDescription.getSlingId())) {
                logger.info("registerAnnouncement: already have this instance attached: " + instanceDescription.getSlingId());
                return -1;
            }
        }
    }
    ResourceResolver resourceResolver = null;
    try {
        resourceResolver = resourceResolverFactory.getServiceResourceResolver(null);
        final Resource announcementsResource = ResourceHelper.getOrCreateResource(resourceResolver, config.getClusterInstancesPath() + "/" + slingId + "/announcements");
        topologyAnnouncement.persistTo(announcementsResource);
        resourceResolver.commit();
        ownAnnouncementsCache.put(topologyAnnouncement.getOwnerId(), new CachedAnnouncement(topologyAnnouncement, config));
    } catch (LoginException e) {
        logger.error("registerAnnouncement: could not log in administratively: " + e, e);
        throw new RuntimeException("Could not log in to repository (" + e + ")", e);
    } catch (PersistenceException e) {
        logger.error("registerAnnouncement: got a PersistenceException: " + e, e);
        throw new RuntimeException("Exception while talking to repository (" + e + ")", e);
    } catch (JsonException e) {
        logger.error("registerAnnouncement: got a JSONException: " + e, e);
        throw new RuntimeException("Exception while converting json (" + e + ")", e);
    } finally {
        if (resourceResolver != null) {
            resourceResolver.close();
        }
    }
    return 0;
}
Also used : JsonException(javax.json.JsonException) Resource(org.apache.sling.api.resource.Resource) LinkedList(java.util.LinkedList) ResourceResolver(org.apache.sling.api.resource.ResourceResolver) PersistenceException(org.apache.sling.api.resource.PersistenceException) LoginException(org.apache.sling.api.resource.LoginException) InstanceDescription(org.apache.sling.discovery.InstanceDescription)

Aggregations

JsonException (javax.json.JsonException)27 IOException (java.io.IOException)11 JsonObject (javax.json.JsonObject)11 HashMap (java.util.HashMap)9 JsonString (javax.json.JsonString)7 Map (java.util.Map)6 JsonArray (javax.json.JsonArray)6 JsonObjectBuilder (javax.json.JsonObjectBuilder)6 StringReader (java.io.StringReader)5 Resource (org.apache.sling.api.resource.Resource)5 InputStream (java.io.InputStream)4 ArrayList (java.util.ArrayList)4 JsonArrayBuilder (javax.json.JsonArrayBuilder)4 LoginException (org.apache.sling.api.resource.LoginException)4 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)4 File (java.io.File)3 StringWriter (java.io.StringWriter)3 JsonValue (javax.json.JsonValue)3 MojoExecutionException (org.apache.maven.plugin.MojoExecutionException)3 FileInputStream (java.io.FileInputStream)2