Of course you can. Rust would be a severely limited systems language if it couldn't support dynamic loading. E.g. see
- https://michael-f-bryan.github.io/rust-ffi-guide/dynamic_loa...
The Log4j "lookup" behaviour was, first of all, a really dumb design decision even in Java but it's just wrong to pretend that it would be equally easy for it to be so catastrophic in most languages, not just Rust, even in C++ I think you'd probably realise you'd screwed up while developing a way for the log framework to run arbitrary code.
You're much less likely to see a deserialization bug in Rust or Go than in Java.
There is nothing intrinsic to Rust or Go that prevents deserialization bugs; they're just not encouraged by idiom like in Java.
Many Java projects, but not all. Class-loading permissions in a Java program are subject to the security-manager policy for the program; class loading can be moderated or even fully disabled (once the main program is loaded, of course).
The default is to allow anything to be loaded, however.
The root of the log4j problem is a failure to distinguish between log format strings and the formatted log string, beyond that what happens is that Java allows a lot of flexibility at runtime which simply doesn't exist in Rust. In Java it's fine to, at runtime pull in classes you've never used before and run them, you can't do that in Rust - the types only existed at compile time. Indeed this is a key feature of Rust, because it means wrapper types are free at runtime, invaluable to the embedded firmware community who love type checking and other safety features but can't afford runtime overhead.