Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JAXB Unmarshaller not unlocking after failure #3238

Closed
lafual opened this issue Apr 2, 2020 · 6 comments
Closed

JAXB Unmarshaller not unlocking after failure #3238

lafual opened this issue Apr 2, 2020 · 6 comments
Assignees
Milestone

Comments

@lafual
Copy link

lafual commented Apr 2, 2020

Hi,
In Windows I am reading a file that "should" contain XML using @InboundChannelAdapter FileReadingMesageSource and passing on to @Transformer UnmarshallingTransformer.

If the un-marshall works, the correct object is forwarded. When the XML is invalid or not the file didn't contain XML a MessageTransformerException is forwarded.

When the un-marshall is successful, the incoming file is un-locked and I can remove it from the incoming directory. However, when I get a MessageTransformerException the file's lock is not released. When I try to move it get java.nio.file.FileSystemException: The process cannot access the file because it is being used by another process

In the FileReadingMessageSource I have tried without setLocker, setLocker with NIOFileLocker and an implementation of FileLocker which creates an additional file with a .locked extension. None of these solutions work.

I am using the following to Transform;

@Bean
public Jaxb2Marshaller unmarshaller() {
   Jaxb2Marshaller x = new Jaxb2Marshaller();
   x.unmarshaller(MyClass.class);
   return x;
}

@Bean
@Transformer
public UnmarshallingTranformer umt() {
   return new UnmarshallingTransformer(unmarshaller());
}

How do I cause the lock to be released?

Shouldn't the transformer somehow share/re-use the lock of the original file reader? It seems as if it is using its own locking and not releasing after failure.

@artembilan artembilan self-assigned this Apr 2, 2020
@artembilan
Copy link
Member

Confirmed.

Now need to figure out how to fix...

@artembilan
Copy link
Member

OK. I found that xcerces opens an InputStream for the file XMLEntityManager to build an Entity.ScannedEntity.
This entity is closed in case of XMLEntityManager.endEntity() when we have already parsed the current entity and ready to go for the next one, what is not a case for us because of that failure during parsing.

It was probably fixed in some later Java version, but it really still fails for me on Java 8 on Windows...

I will try to workaround it with an explicit InputStream reading in the UnmarshallingTranformer instead of delegation to the target JaxB impl...

artembilan added a commit to artembilan/spring-integration that referenced this issue Apr 2, 2020
Fixes spring-projects#3238

* Extract an `InputStream` from a `File` payload in the `UnmarshallingTransformer`
before parsing an XML.
Close this `InputStream` in the `finally` block to release the file resource

**Cherry-pick to 5.2.x, 5.1.x & 4.3.x**
@artembilan
Copy link
Member

The fix is not reviewed yet.

@artembilan artembilan reopened this Apr 2, 2020
artembilan added a commit that referenced this issue Apr 2, 2020
Fixes #3238

* Extract an `InputStream` from a `File` payload in the `UnmarshallingTransformer`
before parsing an XML.
Close this `InputStream` in the `finally` block to release the file resource

**Cherry-pick to 5.2.x, 5.1.x & 4.3.x**
artembilan added a commit that referenced this issue Apr 3, 2020
Fixes #3238

* Extract an `InputStream` from a `File` payload in the `UnmarshallingTransformer`
before parsing an XML.
Close this `InputStream` in the `finally` block to release the file resource

**Cherry-pick to 5.2.x, 5.1.x & 4.3.x**

# Conflicts:
#	spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/UnmarshallingTransformer.java
#	spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/jaxbmarshaling/JaxbMarshallingIntegrationTests.java
artembilan added a commit that referenced this issue Apr 3, 2020
Fixes #3238

* Extract an `InputStream` from a `File` payload in the `UnmarshallingTransformer`
before parsing an XML.
Close this `InputStream` in the `finally` block to release the file resource

**Cherry-pick to 5.2.x, 5.1.x & 4.3.x**

# Conflicts:
#	spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/UnmarshallingTransformer.java
#	spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/jaxbmarshaling/JaxbMarshallingIntegrationTests.java

# Conflicts:
#	spring-integration-xml/src/main/java/org/springframework/integration/xml/transformer/UnmarshallingTransformer.java
#	spring-integration-xml/src/test/java/org/springframework/integration/xml/transformer/jaxbmarshaling/JaxbMarshallingIntegrationTests.java
@artembilan
Copy link
Member

Fixed according merged PR with an appropriate back-port to all the supported versions.

@lafual
Copy link
Author

lafual commented Apr 3, 2020

Thanks very much for the fast turn-around!

FYI - I was using Java 10 (the 'last chance saloon' before Java 11 and modules), not 8.

I managed to work around the problem by adding a FileToStringTransformer before the UnmarshallingTransformer, so it was dealing with a String and not a File.

@artembilan
Copy link
Member

Thanks, @lafual , for feedback! So, sounds like the problem remains in the Java 10 as well, but anyway we can't rely on the latest Java version because of backward compatibility with existing application based on our Spring artifacts.

Nice trick with the FileToStringTransformer though! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants