クライアント/サーバーアプリケーションを開発するとき、私は常に質問がありますが、それをサーバーにデプロイし、コードを記述した後にjar / war / dockerにパックし、それでもサーバーに転送する必要があります。サーバー上でコードの一部をプッシュするための多くのジェスチャがあります。
ラムダを関数に渡すのと同じように、コードをラムダとしてサーバーに渡すだけで、サーバーにも渡すと便利です。
しかし、私はこのプロセスを簡単にする方法を考え、何かをしました。
1 | var query = TcpQuery
2 | .create(IEnv.class).host("myserver.com").port(9988)
3 | .build();
4 |
5 | query.apply(
6 | env -> env.processes().stream().filter(
7 | p -> p.getName().contains("java")
8 | )
9 | .collect(Collectors.toList())
10| ).forEach(System.out::println);
これがJavaコードです。
1行目から5行目までと10行目-クライアントで動作します
6 9 ( env->...)
, Java (11).
6 9 ( ) , , , - deploy, IDE (Idea/Eclipse/etc...).
, Serializable Lambda Java, - , , .. deploy api ( ).
IEnv:
public interface IEnv {
List<OsProc> processes();
}
public class OsProc implements Serializable {
public Optional<Integer> getPpid(){ return ... }
public int getPid(){ return ... }
public void setPid(int pid){ ... }
public String getName(){ return ... }
public Optional<String> getCmdline(){ return ... }
}
var query = TcpQuery
.create(IEnv.class).host("myserver.com").port(9988)
.build();
query.apply(
env -> env.processes().stream().filter(
p -> p.getName().contains("java")
)
.collect(Collectors.toList())
).forEach(System.out::println);
- ?
Java
, Client.java
- - Client.class
query.apply() - env -> env.proc...toList())
query.apply():
( Client) ( lambda1)
- (Client.class)
-
-
-
//
query.apply()
, -, IDE .
?
, pet project-:
v 1.0 https://github.com/gochaorg/trambda/releases/tag/1.0
maven
<dependency>
<groupId>xyz.cofe</groupId>
<artifactId>trambda</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>xyz.cofe</groupId>
<artifactId>trambda-core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>xyz.cofe</groupId>
<artifactId>trambda-tcp</artifactId>
<version>1.0</version>
</dependency>
, (TCP)
OsProc.java - ( )
IEnv.java - ( )
LinuxEnv.java - Linux - IEnv
:
package xyz.cofe.trambda.demo.api;
import org.junit.jupiter.api.Test;
public class LinuxEnvTest {
@Test
public void test(){
var env = new LinuxEnv();
env.processes().stream()
.filter(p->p.getName().equalsIgnoreCase("java"))
.forEach(System.out::println);
}
}
LinuxEnv - , :
package xyz.cofe.trambda.demo.api;
import java.util.ArrayList;
import java.util.List;
import xyz.cofe.io.fs.File;
public class LinuxEnv implements IEnv {
@Override
public List<OsProc> processes(){
ArrayList<OsProc> procs = new ArrayList<>();
File procDir = new File("/proc");
procDir.dirList().stream()
.filter( d -> d.getName().matches("\\d+") && d.isDir() )
.map(OsProc::linuxProc)
.forEach(procs::add);
return procs;
}
}
, /proc , ( Linux / /proc)
(git commit 67ec260)
> git clone https://github.com/gochaorg/trambda.git
«trambda»...
remote: Enumerating objects: 978, done.
remote: Counting objects: 100% (978/978), done.
remote: Compressing objects: 100% (464/464), done.
remote: Total 978 (delta 308), reused 862 (delta 195), pack-reused 0
: 100% (978/978), 715.70 KiB | 559.00 KiB/s, .
: 100% (308/308), .
user@user-Modern-14-A10RB:22:10:35:~//sample-tr:
> cd trambda/trambda-demo/tr-demo-api/
user@user-Modern-14-A10RB:22:10:49:~//sample-tr/trambda/trambda-demo/tr-demo-api:
> mvn clean package install
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.933 s
[INFO] Finished at: 2021-04-18T22:11:11+05:00
[INFO] ------------------------------------------------------------------------
target jar
user@user-Modern-14-A10RB:22:13:13:~//sample-tr/trambda/trambda-demo/tr-demo-api:
> ll target/
48
drwxrwxr-x 10 user user 4096 18 22:11 ./
drwxrwxr-x 4 user user 4096 18 22:11 ../
drwxrwxr-x 3 user user 4096 18 22:11 classes/
drwxrwxr-x 3 user user 4096 18 22:11 generated-sources/
drwxrwxr-x 3 user user 4096 18 22:11 generated-test-sources/
drwxrwxr-x 2 user user 4096 18 22:11 maven-archiver/
drwxrwxr-x 3 user user 4096 18 22:11 maven-status/
drwxrwxr-x 4 user user 4096 18 22:11 site/
drwxrwxr-x 2 user user 4096 18 22:11 surefire-reports/
drwxrwxr-x 3 user user 4096 18 22:11 test-classes/
-rw-rw-r-- 1 user user 6337 18 22:11 tr-demo-api-1.0-SNAPSHOT.jar
github
user@user-Modern-14-A10RB:22:37:25:~//sample-tr: > wget https://github.com/gochaorg/trambda/releases/download/1.0/trambda-tcp-serv-cli.zip --2021-04-18 22:37:31-- https://github.com/gochaorg/trambda/releases/download/1.0/trambda-tcp-serv-cli.zip github.com (github.com)... 140.82.121.4 github.com (github.com)|140.82.121.4|:443... . HTTP- . ... 302 Found : https://github-releases.githubusercontent.com/350075998/47380d00-9b40-11eb-90a4-4e353f42e67c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210418%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210418T173731Z&X-Amz-Expires=300&X-Amz-Signature=97ade1f58bfbe1eaa320805179987e8c4df730b9f5eddf24c05662fb676caafe&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=350075998&response-content-disposition=attachment%3B%20filename%3Dtrambda-tcp-serv-cli.zip&response-content-type=application%2Foctet-stream [] --2021-04-18 22:37:31-- https://github-releases.githubusercontent.com/350075998/47380d00-9b40-11eb-90a4-4e353f42e67c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210418%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210418T173731Z&X-Amz-Expires=300&X-Amz-Signature=97ade1f58bfbe1eaa320805179987e8c4df730b9f5eddf24c05662fb676caafe&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=350075998&response-content-disposition=attachment%3B%20filename%3Dtrambda-tcp-serv-cli.zip&response-content-type=application%2Foctet-stream github-releases.githubusercontent.com (github-releases.githubusercontent.com)... 185.199.111.154, 185.199.108.154, 185.199.109.154, ... github-releases.githubusercontent.com (github-releases.githubusercontent.com)|185.199.111.154|:443... . HTTP- . ... 200 OK : 12107487 (12M) [application/octet-stream] : «trambda-tcp-serv-cli.zip» trambda-tcp-serv-cli.zip 100%[========================================================================================================================================>] 11,55M 3,75MB/s 3,1s 2021-04-18 22:37:35 (3,75 MB/s) - «trambda-tcp-serv-cli.zip» [12107487/12107487] user@user-Modern-14-A10RB:22:37:35:~//sample-tr: > ll 11836 drwxrwxr-x 3 user user 4096 18 22:37 ./ drwxr-xr-x 11 user user 4096 18 22:00 ../ drwxrwxr-x 10 user user 4096 18 22:10 trambda/ -rw-rw-r-- 1 user user 12107487 12 03:36 trambda-tcp-serv-cli.zip user@user-Modern-14-A10RB:22:37:42:~//sample-tr: > unzip trambda-tcp-serv-cli.zip Archive: trambda-tcp-serv-cli.zip creating: trambda-tcp-serv-cli/ creating: trambda-tcp-serv-cli/jars/ inflating: trambda-tcp-serv-cli/jars/asm-9.1.jar inflating: trambda-tcp-serv-cli/jars/jline-2.14.6.jar inflating: trambda-tcp-serv-cli/jars/iofun-1.0.jar inflating: trambda-tcp-serv-cli/jars/groovy-swing-3.0.7.jar inflating: trambda-tcp-serv-cli/jars/groovy-console-3.0.7.jar inflating: trambda-tcp-serv-cli/jars/groovy-xml-3.0.7.jar inflating: trambda-tcp-serv-cli/jars/trambda-tcp-serv-cli-1.0.jar inflating: trambda-tcp-serv-cli/jars/ecolls-1.10.jar inflating: trambda-tcp-serv-cli/jars/trambda-core-1.0.jar inflating: trambda-tcp-serv-cli/jars/slf4j-api-1.7.25.jar inflating: trambda-tcp-serv-cli/jars/asm-tree-9.1.jar inflating: trambda-tcp-serv-cli/jars/asm-util-9.1.jar inflating: trambda-tcp-serv-cli/jars/fs-1.2.jar inflating: trambda-tcp-serv-cli/jars/logback-classic-1.2.3.jar inflating: trambda-tcp-serv-cli/jars/trambda-tcp-1.0.jar inflating: trambda-tcp-serv-cli/jars/groovy-groovysh-3.0.7.jar inflating: trambda-tcp-serv-cli/jars/groovy-templates-3.0.7.jar inflating: trambda-tcp-serv-cli/jars/asm-analysis-9.1.jar inflating: trambda-tcp-serv-cli/jars/text-1.0.jar inflating: trambda-tcp-serv-cli/jars/logback-core-1.2.3.jar inflating: trambda-tcp-serv-cli/jars/groovy-3.0.7.jar inflating: trambda-tcp-serv-cli/jars/cbuffer-1.3.jar creating: trambda-tcp-serv-cli/bin/ inflating: trambda-tcp-serv-cli/bin/trambda-tcp-serv.bat inflating: trambda-tcp-serv-cli/bin/trambda-tcp-serv user@user-Modern-14-A10RB:22:37:50:~//sample-tr: > rm trambda-tcp-serv-cli.zip
trambda-tcp-serv-cli/jars
ser@user-Modern-14-A10RB:22:40:47:~//sample-tr:
> cp -v trambda/trambda-demo/tr-demo-api/target/tr-demo-api-1.0-SNAPSHOT.jar trambda-tcp-serv-cli/jars/
'trambda/trambda-demo/tr-demo-api/target/tr-demo-api-1.0-SNAPSHOT.jar' -> 'trambda-tcp-serv-cli/jars/tr-demo-api-1.0-SNAPSHOT.jar'
:
> cat trambda/trambda-tcp-serv-cli/src/test/samples/sample-1.groov
// xyz.cofe.trambda.demo.api.LinuxEnv
// 9988, IP
app.service( "0.0.0.0:9988", new xyz.cofe.trambda.demo.api.LinuxEnv() ) {
daemon false
//
security {
// API/
allow {
// method("System") {
// methodOwner ==~ /java.lang.System/ && methodName in ['gc']
// }
// field( "System.out" ) {
// fieldOwner ==~ /java.lang.System/ && fieldName in ['out','in','err'] && readAccess
// }
invoke( 'Java compiler' ){
methodOwner ==~ /java\.lang\.invoke\.(LambdaMetafactory|StringConcatFactory)/
}
invoke( 'Java collections' ){
methodOwner ==~ /java\.util\.(stream\.(Stream|Collectors)|(List))/
}
invoke( 'Java lang' ){
methodOwner ==~ /java\.lang\.String/
}
invoke( 'Api '){
methodOwner ==~ /xyz\.cofe\.trambda\.demo\.api\.(IEnv|OsProc)/
}
}
// -
deny {
any("ban all")
}
}
}
user@user-Modern-14-A10RB:22:56:08:~//sample-tr:
> bash ./trambda-tcp-serv-cli/bin/trambda-tcp-serv -s trambda/trambda-tcp-serv-cli/src/test/samples/sample-1.groovy
# [main] INFO x.c.t.tcp.serv.cli.TcpServerCLI - starting xyz.cofe.trambda.tcp.serv.cli.TcpServerCLI
# [main] INFO x.c.t.tcp.serv.cli.TcpServerCLI - executeScript( "trambda/trambda-tcp-serv-cli/src/test/samples/sample-1.groovy", UTF-8 )
# [main] INFO x.c.t.tcp.serv.cli.TcpServerCLI - registry class xyz.cofe.trambda.demo.api.LinuxEnv on 0.0.0.0:9988
# [main] INFO x.c.t.tcp.serv.cli.TcpServerCLI - starting service xyz.cofe.trambda.demo.api.LinuxEnv@55e7a35c on /0.0.0.0:9988
# [main] DEBUG x.c.t.tcp.serv.cli.TcpServerCLI - create server socket
# [main] DEBUG x.c.t.tcp.serv.cli.TcpServerCLI - bind server socket /0.0.0.0:9988
# [main] DEBUG x.c.t.tcp.serv.cli.TcpServerCLI - server started
, ,
package xyz.cofe.trambda.demo.client;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import xyz.cofe.trambda.demo.api.IEnv;
import xyz.cofe.trambda.tcp.TcpQuery;
public class ClientTest {
@Test
public void test01(){
var query = TcpQuery
.create(IEnv.class).host("localhost").port(9988)
.build();
query.apply(
env -> env.processes().stream().filter(p ->
p.getName().contains("java"))
.collect(Collectors.toList())
).forEach(System.out::println);
}
}
, , - ..
?
- ..
, :
// TCP
ServerSocket ssocket = new ServerSocket(port);
//
ssocket.setSoTimeout(1000*5);
//
server = new TcpServer<IEnv>(
//
ssocket,
//
s -> new LinuxEnv(),
//
SecurityFilters.create(s -> {
// -
s.allow( a -> {
// API
a.invoke("demo api", c->
c.getOwner().matches(
"xyz\\.cofe\\.trambda\\.tcp\\.demo\\.([\\w\\d]+)"));
//
a.invoke("java collections api", c->c.getOwner().matches(
"java\\.util\\.(List)|java\\.util\\.stream\\.([\\w\\d]+)"));
// Java
a.invoke("java lang api", c->
c.getOwner().matches("java\\.lang\\.(String)"));
// Java
a.invoke("java compiler", c->
c.getOwner().matches(
"java\\.lang\\.invoke\\.(LambdaMetafactory|StringConcatFactory)"));
});
//
s.deny().any("by default");
})
);
// Thread
server.setDaemon(true);
//
server.start();// TCP
ServerSocket ssocket = new ServerSocket(port);
//
ssocket.setSoTimeout(1000*5);
,
,
,
Java
LambdaMetafactory
StringConcatFactory +
/ - . SecurityFilters.java / PredicateBuilder#field
, Object.toString() ,
?
, , RMI, gRPC ?
, . /:
/
/ /
/
//…
-
..
… ..
,
|
Java-RMI |
SOAP |
REST-JSON |
SQL |
GraphQL |
Hadoop |
|
+ |
+ |
+ |
+ |
+ |
+ |
|
+/- |
+/- |
- |
- |
+ |
- |
|
+/- |
+/- |
+ |
+ |
- |
+ |
|
- |
- |
- |
+ |
- |
+ |
|
- |
- |
- |
+ |
- |
+ |
/ |
- |
- |
- |
+ |
- |
+ |
/ |
- |
- |
- |
+ |
- |
+ |
… |
- |
- |
- |
? |
- |
? |
|
- |
- |
+ |
- |
- |
+ |
|
+ |
+ |
- |
+ |
+ |
- |
|
+ |
+ |
+ |
+ |
+ |
+ |
|
? |
? |
? |
+/- |
? |
? |
|
+ |
+ |
? |
- |
+ |
- |
|
- |
- |
? |
+ |
- |
+ |
|
+ |
+ |
? |
+ |
+ |
? |
(Java-RMI, SOAP, REST-JSON, GraphQL)
(Java-RMI, SOAP, GraphQL)
(REST-JSON, Hadoop)
- (SQL, Hadoop)
SQL
,
(*)
/ /
/
//
… (**)
(***)
(****)
, ,
Java SQL WHERE ( )
RPC/RMI/SOAP/… ( )
( )
JAVA/Kotlin/Scala (SQL, MongoDB, REST, …)
- AST/Java/…, JAD
.
?
, Java , - .class, java , : obj.getClass()
Class , Class.getResource(‘ ’) URL .
“ , ”
, …
, ?
package xyz.cofe.trambda.l1;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
public class SimpleLambdaTest {
@Test
public void javaLambda01(){
Function<Function<String,String>,String> test = (f) -> {
System.out.println("f="+f.getClass());
return null;
};
test.apply( x -> x.repeat(4) );
}
}
:
f=class xyz.cofe.trambda.l1.SimpleLambdaTest$$Lambda$235/0x0000000800142040
test-classes/ SimpleLambdaTest$$Lambda$235,
user@user-Modern-14-A10RB:00:41:32:~/code/trambda/trambda-core/target/test-classes/xyz/cofe/trambda/l1:
> ll
12
drwxrwxr-x 2 user user 4096 25 00:40 ./
drwxrwxr-x 5 user user 4096 25 00:40 ../
-rw-rw-r-- 1 user user 2162 25 00:40 SimpleLambdaTest.class
> javap -p SimpleLambdaTest.class
Compiled from "SimpleLambdaTest.java"
public class xyz.cofe.trambda.l1.SimpleLambdaTest {
public xyz.cofe.trambda.l1.SimpleLambdaTest();
public void javaLambda01();
private static java.lang.String lambda$javaLambda01$1(java.lang.String);
private static java.lang.String lambda$javaLambda01$0(java.util.function.Function);
}
- lambda$javaLambda01$1 lambda$javaLambda01$0 , ,
class Java , .
Java Serializable,
package xyz.cofe.trambda.l2;
import java.io.Serializable;
import java.util.function.Function;
public interface Fn<A,Z> extends Function<A,Z> , Serializable {
}
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");
Java ,
package xyz.cofe.trambda.l2;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
public class SerialLambdaTest {
@Test
public void serLambda01(){
Fn<Fn<String,String>,String> test = (lambda) -> {
System.out.println("lambda="+lambda.getClass());
Method writeReplace = null;
try{
writeReplace = lambda.getClass().getDeclaredMethod("writeReplace");
writeReplace.setAccessible(true);
SerializedLambda sl = (SerializedLambda) writeReplace.invoke(lambda);
System.out.println(sl);
} catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException e ) {
e.printStackTrace();
}
return null;
};
test.apply( x -> x.repeat(4) );
}
}
, .
lambda=class xyz.cofe.trambda.l2.SerialLambdaTest$$Lambda$235/0x0000000800142040
SerializedLambda[capturingClass=class xyz.cofe.trambda.l2.SerialLambdaTest,
functionalInterfaceMethod=xyz/cofe/trambda/l2/Fn.apply:(Ljava/lang/Object;)
Ljava/lang/Object;,
implementation=invokeStatic
xyz/cofe/trambda/l2/SerialLambdaTest.lambda$serLambda01$3fed5817$1:
(Ljava/lang/String;)Ljava/lang/String;,
instantiatedMethodType=(Ljava/lang/String;)Ljava/lang/String;, numCaptured=0]
user@user-Modern-14-A10RB:00:51:48:~/code/trambda/trambda-core/target/test-classes/xyz/cofe/trambda/l2:
> javap -p SerialLambdaTest.class
Compiled from "SerialLambdaTest.java"
public class xyz.cofe.trambda.l2.SerialLambdaTest {
public xyz.cofe.trambda.l2.SerialLambdaTest();
public void serLambda01();
private static java.lang.Object $deserializeLambda$(java.lang.invoke.SerializedLambda);
private static java.lang.String lambda$serLambda01$3fed5817$1(java.lang.String);
private static java.lang.String lambda$serLambda01$47b6c34$1(xyz.cofe.trambda.l2.Fn);
}
- $deserializeLambda$ , Serializable .
java.lang.invoke.SerializedLambda - final , ,
String getImplClass() - , .
String getImplMethodName() - .
stdout
implementation=invokeStatic xyz/cofe/trambda/l2/SerialLambdaTest.lambda$serLambda01$3fed5817$1:(Ljava/lang/String;)Ljava/lang/String;
:
private static java.lang.String lambda$serLambda01$3fed5817$1(java.lang.String);
.. -
, - , :
SerializedLambda sl = (SerializedLambda)writeReplace.invoke(lambda);
var implClassName = sl.getImplClass()
var implClassUrl =
labmda.getClass().getResource("/"+implClassName.replace(".","/")+".class");
implClassUrl -
URL
byte[] classByteCode = null;
try{
classByteCode = IOFun.readBytes(implClassUrl);
} catch( IOException e ) {
throw new IOError(e);
}
var classReader = new ClassReader(classByteCode);
ClassVisitor cv = new ClassVisitor(Opcodes.ASM9) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
if( methName.equals(name) && descriptor!=null && descriptor.equals(methSign) ){
mdef0.set(new MethodDef(access,name,descriptor,signature,exceptions));
return dump(byteCodes::add);
}
return null;
}
};
cr.accept(cv, 0);
MethodVisior
- . , MethodDump extends MethodVisitor
:
package xyz.cofe.trambda;
public class MethodDump extends MethodVisitor implements Opcodes {
...
@Override
public void visitParameter(String name, int access){
emit(new MParameter(name,access));
}
@Override
public void visitInsn(int opcode){
emit(new MInsn(opcode));
}
...
}
visitXXXX(...) - ( )
, visitInsn( op ) new MInsn(op), emit(..)
, ( )
xyz.cofe.trambda.MethodRestore
public synchronized byte[] generate(){
//
binClassName = className.replace('.', '/');
// ClassWriter ( ASM)
// visitXXXX( op )
var cw = new ClassWriter(ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V11,
Opcodes.ACC_PUBLIC|Opcodes.ACC_SUPER,
binClassName,null,
"java/lang/Object", null
);
//
var mv = cw.visitMethod(
acc, // static public
name, //
desc, //
sign, // Generic
excepts); //
//
// visitXXXX()
// ,
for( var bc : byteCodes ){
if( bc instanceof MCode )build((MCode) bc);
else if( bc instanceof MEnd )build((MEnd) bc);
else if( bc instanceof MLabel )build((MLabel) bc);
else if( bc instanceof MLineNumber )build((MLineNumber) bc);
else if( bc instanceof MVarInsn )build((MVarInsn) bc);
...
}
//
return cw.toByteArray();
}
// visitCode() -
protected void build(MCode code){ mv.visitCode(); }
// visitEnd() -
protected void build(MEnd end){ mv.visitEnd(); }
protected void build(MTypeInsn tinst){
mv.visitTypeInsn(tinst.getOpcode(), tinst.getOperand());
}
,
ClassLoader
var byteCode = new MethodRestore()
.className(clName)
.methodName("lambda1")
.methodDef(mdef)
.generate();
ClassLoader cl = new ClassLoader(ClassLoader.getSystemClassLoader()) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException{
if( name!=null && name.equals(clName) ){
return defineClass(name,byteCode,0,byteCode.length);
}
return super.findClass(name);
}
};
System.out.println("try read class "+clName);
Class c = null;
try{
c = Class.forName(clName,true,cl);
System.out.println("class found "+c);
} catch( ClassNotFoundException e ) {
e.printStackTrace();
return;
}
Method m = null;
System.out.println("methods");
for( var delMeth : c.getDeclaredMethods() ){
System.out.println(""+delMeth);
if( delMeth.getName().equals(methName) ){
m = delMeth;
}
}
try{
Object arg0 = "abc";
System.out.println("call with "+arg0);
Object res = m.invoke(null, arg0);
System.out.println("result "+res);
} catch( IllegalAccessException | InvocationTargetException e ) {
e.printStackTrace();
}
Kotlin , .. Kotlin , Scala
(Groovy, JavaScript) - , AST - , .
- - ,
クライアントでは、Javaが新しく、サーバーとはバイトコードが異なる可能性があり、サーバーは新しいJavaの構成を認識していない可能性があります。
ライブラリはすべてのバイトコードを転送しません。これは、すべてのバイトコードがオブジェクト表現を持っているわけではないという事実によるものです。おそらくこれは解決すべき問題であり、改良の問題です。
別に-それはネットワーク伝送の問題です
セキュリティの問題-技術的には解決できますが、ファイルで終了する必要があります
転送プロトコル、私のライブラリはTCPを使用していますが、このネットワーク層はいつでもより適切なものに変更できますが、もちろんその実装が必要になります。実際、ラムダのシリアル化とその回復によってネットワークが制限されることはありません。何らかの方法でレイヤー。