com.landawn.abacus.http.JavaExecutionServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of abacus-android Show documentation
Show all versions of abacus-android Show documentation
A general and simple library for Android
/*
* Copyright (C) 2015 HaiYang Li
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.landawn.abacus.http;
import static com.landawn.abacus.http.HTTP.jsonParser;
import static com.landawn.abacus.http.HTTP.kryoParser;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.landawn.abacus.exception.AbacusException;
import com.landawn.abacus.exception.UncheckedIOException;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;
import com.landawn.abacus.util.IOUtil;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.RemoteExecutionRequest;
import com.landawn.abacus.util.RemoteExecutionResponse;
import com.landawn.abacus.util.RemoteTask;
/**
* Deploy JavaExecutionServlet
under Tomcat.
*
*
* {@code
*
* Hello javaExecution
* javaExecution
* javaExecution
* com.landawn.abacus.http.JavaExecutionServlet
*
*
*
* javaExecution
* /javaExecution/*
*
* }
*
*
* @since 0.8
*
* @author Haiyang Li
*/
@SuppressWarnings("deprecation")
public class JavaExecutionServlet extends AbstractHttpServlet {
private static final long serialVersionUID = 778742360481398056L;
private static final Logger logger = LoggerFactory.getLogger(JavaExecutionServlet.class);
private static final Method defineClassMethod;
static {
defineClassMethod = getDeclaredMethod(ClassLoader.class, "defineClass", String.class, byte[].class, int.class, int.class);
defineClassMethod.setAccessible(true);
}
private static final ClassLoader rootClassLoader = JavaExecutionServlet.class.getClassLoader();
static {
logger.warn(IOUtil.JAVA_VERSION);
}
@Override
public void init() throws ServletException {
super.init();
}
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
execute(request, response);
}
protected void execute(final HttpServletRequest request, final HttpServletResponse response) throws UncheckedIOException {
final ContentFormat contentFormat = getContentFormat(request);
final long startTime = System.currentTimeMillis();
final RemoteExecutionResponse remoteResponse = new RemoteExecutionResponse();
RemoteExecutionRequest remoteRequest = null;
InputStream is = null;
try {
is = getInputStream(request, contentFormat);
switch (contentFormat) {
case KRYO:
remoteRequest = kryoParser.deserialize(RemoteExecutionRequest.class, is);
break;
case JSON:
remoteRequest = jsonParser.deserialize(RemoteExecutionRequest.class, is);
break;
default:
remoteResponse.setErrorCode(getClassName(AbacusException.class));
remoteResponse.setErrorMessage("Unsupported content format: " + contentFormat + ". Only Kryo is supported");
}
if (remoteResponse.getErrorCode() == null) {
final String requestId = N.isNullOrEmpty(remoteRequest.getRequestId()) ? String.valueOf(System.currentTimeMillis())
: remoteRequest.getRequestId();
// remoteRequest.getRunMode() // TODO
// remoteRequest.getSchedule() // TODO
if (logger.isInfoEnabled()) {
logger.info("Start to execute task: " + requestId + " from host: " + remoteRequest.getRequestHost());
}
final DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(rootClassLoader);
final Map classBytesMap = remoteRequest.getClassBytesMap();
for (Map.Entry entry : classBytesMap.entrySet()) {
defineClass(dynamicClassLoader, entry.getKey(), entry.getValue());
}
@SuppressWarnings("rawtypes")
final Class extends RemoteTask, ?>> remoteTask = (Class) dynamicClassLoader.loadClass(remoteRequest.getClassName());
final RemoteTask