Spring Integration: Calling transformer before handler denies transactional context - java

I am still fighting to realize the following flow using Spring Integration 5.5:
read a file from remote SFTP service as InputStream
transform that stream into a custom entity
persist the entity via JPA
delete remote file from SFTP server
So, I have the following flow using Java DSL:
#Configuration
public class Flow {
#Bean
public StandardIntegrationFlow createFlow() {
return IntegrationFlows
.from(source())
.publishSubscribeChannel(pubSub -> pubSub
.subscribe(sub1 -> sub1
.transform(Message.class, this::transform)
.handle(persist(), e -> e.transactional(false))
)
.subscribe(sub2 -> sub2
.handle(remove())
)
)
.get();
}
public MessageSource<InputStream> source() {
return null;
}
public Message<MyEntity> transform(Message<InputStream> message) {
return null;
}
public JpaOutboundGateway persist() {
return null;
}
public AbstractMessageHandler remove() {
return null;
}
}
My IDE (VSCode) is giving me no warning about this code, however when trying to compile it using Apache Maven 3.8 / JDK 17, I get the following compilation error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project amqp: Compilation failure
[ERROR] /C:/Users/.../src/main/java/com/example/Flow.java:[25,46] cannot find symbol
[ERROR] symbol: method transactional(boolean)
[ERROR] location: variable e of type java.lang.Object
The reason seems to the the transformation (transform()), because as soon as I remove that transformation, the code compiles. Of course it fails during runtime, because persist() method expects a Message, not Message.
Any ideas on what is wrong with my transform-methods signature?

Confirmed. Looks like some bug in Java compiler by itself.
When I swap those transform() and handle() it compiles.
Or if I remove it or modify some other way...
You can use this as a workaround for now:
.transform(this, "transform")
That compiler error is fully not relevant to your transform() definition.
I might be mistaken judging Java compiler, so will be glad to see some other explanations and hints what is wrong with our code.

Related

Kotlin's JvmDefault - still need to declare the method ?

I am building my Spring Boot 1.5 + Kotlin 1.2.41 project into a jar. One of the interfaces in the jar has the #JvmDefault and it compiles fine with the flag (if I remove the flag, it fails).
Now, I am trying to use this interface in another java project, in which I define the Kotlin project as a dependency.
In one implementing class, I don't override the default method. Intellij seems to be OK with it, as it doesn't complain. However, when I compile with Maven, I get :
[ERROR] attempting to assign weaker access privileges; was public
If I implement the method (with some dummy implementation), then it compiles... but it defeats the purpose of the default interface.
Any idea what could be wrong ?
When opening the Kotlin interface code from the java project, here's the decompiled code I see :
public interface CrawlerOutput {
#kotlin.jvm.JvmDefault public open fun finalize(): kotlin.Unit { /* compiled code */ }
public abstract fun output(analyzedRepository: com.myCompany.Repository): kotlin.Unit
}
My java code implementing the interface :
public class CsvOutput implements CrawlerOutput {
#Override
public void output(Repository repository) throws IOException {
log.info("own output is receiving some data !");
}
/**
* IF I REMOVE BELOW METHOD, MAVEN CAN'T COMPILE IT ANYMORE,
* COMPLAINING OF WEAKER ACCESS PRIVILEGE
*/
#Override
public void finalize(){
}
}
Am I missing something ?
Thanks
Vincent
Your method name conflicts with java.lang.Object.finalize(). The error should be fixed if you choose a different method name.
Android Studio and JVM always update its versions. As a result of that some of you may experience this error message.
Inheritance from an interface with '#JvmDefault' members is only allowed with -Xjvm-default option
Don't worry . The solution is very simple. Just add below code part to the end of android block of your app level build.gradle file and sync.
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += [
"-Xjvm-default=all",
]
}
}

Google GIN, GWT, and com.google.inject.Inject(optional=true) not working

I have a GIN #Inject invocation where I use the optional=true attribute, but it is simply not honored / not working (and an error is being thrown because my class is not bound, which is true).
I'm using GIN via .gwt.xml file like this:
<extend-configuration-property name="gin.ginjector.modules" value="com.example.client.ClientModule" />
In the above example ClientModule extends com.google.gwt.inject.client.AbstractGinModule.
Then I have a class where I requestStaticInjection like this:
requestStaticInjection(Example.class);
In Example.java I have:
class Example {
#com.google.inject.Inject(optional=true)
protected static SomeUnboundInterface someUnboundInterface = null;
...
}
But I get an error during app startup like this:
[INFO] [ERROR] No binding found for com.example.SomeUnboundInterface in com.gwtplatform.mvp.client.DesktopGinjector
[INFO] [ERROR] Errors in 'gen/com/gwtplatform/mvp/client/DesktopGinjectorProvider.java'
[INFO] [ERROR] Line 8: Failed to resolve 'com.gwtplatform.mvp.client.DesktopGinjector' via deferred binding
Well, that's actually true; My SomeUnboundInterface is indeed not bound; however I was hoping that using the optional=true attribute would work.
Please note that the official documentation does not say that for GIN, this attribute is supported. However, it does say so for GUICE, so I was hoping it would work for GIN as well.
Do you know of any solution so that I don't get an error if a particular dependency is not bound?
Edit: Forgot to mention version. GWT 2.8.1; GIN 2.1; GWTP 1.6
Optional should works, this example compiles and prints 'null' using GWT 2.8.1 and GIN 2.1.2.
static class Foo {
#Inject(optional = true) Runnable bar;
}
static class MyModule extends AbstractGinModule {
#Override protected void configure() { bind(Foo.class); }
}
#GinModules(MyModule.class) interface MyGinjector extends Ginjector {
Foo foo();
}
#Override public void onModuleLoad() {
L.log(GWT.<MyGinjector>create(MyGinjector.class).foo().bar);
}
But if you add a static injection, like you have in your example, it fails. You can either bind it to something or remove the "requestStaticInjection".

java web application failing to build

I'm new with annotations and building applications, so I apologize if it's too easy or I asked the wrong type question. I have a custom annotation like this :
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Handler {
Class value();
}
Now in a java file, say AB.java, I used this annotation like this
#Handler(Msg.class)
public void handleMsg(Msg msg) {
...//some code
}
Now when I tried to build the application, by doing this from the location of my build.xml file
ant rebuild content
it says
BUILD FAILED
for this reason
/home/../somePath/AB.java:800 error: cannot find symbol
#Handler(Msg.class)
symbol: method value()
location: #interface Handler
I'm running java version "1.7.0_101" if it matters. Does it matter if maybe this was written with java version "1.7.0_45". Can someone explain why this's happening even though the class Msg exists in my project files?

Cannot test Play application with junit because of actors

UPDATE/SOLUTION
The problem was more of a conception problem than anything else.
We could resolve it by using the Application.isTest() method and NOT start/end the actors if we are unit-testing the program.
ORIGINAL POST
Hi there,
since my (small) team started using actors in Play!, we get this nice error message each time we want to unit-test our application. FYI, the application is being developed in Java.
[error] Test utils.JsonUtilsTest.testBuildingJsonResponseWithPermissionsThrowsNullPointerException failed: java.lang.IllegalStateException: cannot create children while terminating or terminated, took 0.48 sec
[error] at akka.actor.dungeon.Children$class.makeChild(Children.scala:266)
...
[error] at Global.startActors(Global.java:1248)
so let's take a look at the startActors method in the Global class, which extends GlobalSettings :
private void startActors() {
ActorRef measureFrequencyMaster = RemoteActorsUtils.getInstance().getSystem()
.actorOf(Props.create(MeasureFrequencyMaster.class), "MeasureFrequencyMaster");
BatchMessage msg = new BatchMessage();
msg.setMessage(MSG.GO_SCHEDULE);
RemoteActorsUtils.getInstance().getBatchMonitor().tell(msg, ActorRef.noSender());
}
Well, I'm not sure this helps a lot. But I also have this onStop method in the Global.java file, which is apparently never called :
#Override
public void onStop(Application app) {
super.onStop(app);
RemoteActorsUtils.getInstance().getSystem().shutdown();
if (!RemoteActorsUtils.getInstance().getSystem().isTerminated()) {
RemoteActorsUtils.getInstance().getSystem().shutdown();
}
}
Thanks for the insight.

How to use protobuf in google endpoints

I'm writing Google Endpoints application and I want to return protobuf object in my #Api class.
All the time I'm getting this error:
Error:Gradle: Execution failed for task ':ExploreBackend:appengineEndpointsGetClientLibs'.
There was an error running endpoints command get-client-lib: Object type ? extends xxx.model.proto.MainProtos$PlaceOrBuilder not supported.
This is my code:
#Api( ... )
public class CityApi {
public List<MainProto.City> getCities() {
return new ArrayList<MainProto.City>();
}
}
How to use protobuf in google endpoints
You can not

Categories