Übergeben und rufen Sie Lambdas auf dem Server auf und lassen Sie Docker / Deploy / ...

Bei der Entwicklung einer Client-Server-Anwendung habe ich immer eine Frage, aber wie werde ich sie auf dem Server bereitstellen, sie nach dem Schreiben des Codes in jar / war / docker packen und sie dann noch auf den Server übertragen müssen Ich habe viele Gesten, um einfach einen Code auf den Server zu schieben.





Es wäre schön, den Code einfach als Lambda an den Server zu übergeben, genauso wie wir ein Lambda an eine Funktion übergeben, und ihn auch an den Server weitergeben.





Aber ich hatte eine Idee, wie ich diesen Prozess vereinfachen könnte, und ich habe etwas getan.





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);
      
      



Hier ist der Java-Code,





  • Die Zeilen 1 bis 5 einschließlich und 10 - arbeiten am Kunden





  • 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





  1. , Client.java





  2. - - Client.class





  3. query.apply() - env -> env.proc...toList())





  4. query.apply():









    1. ( Client) ( lambda1)





    2. - (Client.class)





    3. -





      1. -





      2. -

















      1. //













  5. 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'
      
      



, groovy ( , , Java)





:





> 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 
      
      



, ,





(ClientTest.java)





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() ,





, github git pages





?

, , 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





,





  • (*)





    • / /













    • /





    • //





    • … (**)













    • (***)













    • (****)









  • (*)





    • Serializable





    • Proxy





  • (**)





    • Proxy -





  • (***)





    • -,





    • ,





  • (****)





    • ,





, ,









  • 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);
}
      
      



ASM





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();
}
      
      











    1. Kotlin , .. Kotlin , Scala





    2. (Groovy, JavaScript) - , AST - , .





  1. - - ,





  2. Möglicherweise ist Java auf dem Client neuer und hat einen anderen Bytecode als auf dem Server. Der Server kennt möglicherweise keine Konstrukte des neuen Java





  3. Die Bibliothek überträgt nicht den gesamten Bytecode. Dies liegt an der Tatsache, dass nicht der gesamte Bytecode eine Objektdarstellung aufweist - wahrscheinlich ist dies eine zu lösende Frage, eine Frage der Verfeinerung.





  4. Separat - es ist eine Frage der Netzwerkübertragung





    1. Sicherheitsproblem - technisch kann es gelöst werden, erfordert jedoch die Fertigstellung mit einer Datei





    2. Das Übertragungsprotokoll, meine Bibliothek verwendet TCP, aber diese Netzwerkschicht kann immer in eine für Sie geeignetere geändert werden, aber natürlich erfordert es seine Implementierung, tatsächlich schränkt die Serialisierung des Lambda und seine Wiederherstellung das Netzwerk nicht ein Schicht in irgendeiner Weise.








All Articles