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

GEODE-3306: Remove whitespace StringBuffers/nodes created by Apache X… #668

Closed
wants to merge 8 commits into from

Conversation

darrenfoong
Copy link
Contributor

@darrenfoong darrenfoong commented Jul 29, 2017

…erces

This commit makes Geode compatible with the official Apache Xerces
implementation, which calls characters() when it reads ignorable
whitespace in cache.xml.

The while loop is required to handle comments in cache.xml, i.e.
a comment with whitespace before and after will generate two
empty StringBuffers (one for each set of whitespace before and after)
on the parse stack. The while loop removes all "consecutive" whitespace
StringBuffers from the top of the stack.


Tested with https://github.com/darrenfoong/geode-parser-poc/blob/master/src/test/java/server/ServerTest.java


Thank you for submitting a contribution to Apache Geode.

In order to streamline the review of the contribution we ask you
to ensure the following steps have been taken:

For all changes:

  • Is there a JIRA ticket associated with this PR? Is it referenced in the commit message?

  • Has your PR been rebased against the latest commit within the target branch (typically develop)?

  • Is your initial contribution a single, squashed commit?

  • Does gradlew build run cleanly?

  • Have you written or updated unit tests to verify your changes?

  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?

Note:

Please ensure that once the PR is submitted, you check travis-ci for build issues and
submit an update to your PR as soon as possible. If you need help, please send an
email to dev@geode.apache.org.

…erces

This commit makes Geode compatible with the official Apache Xerces
implementation, which calls `characters()` when it reads ignorable
whitespace in `cache.xml`.

The while loop is required to handle comments in `cache.xml`, i.e.
a comment with whitespace before and after will generate two
empty StringBuffers (one for each set of whitespace before and after)
on the parse stack. The while loop removes all "consecutive" whitespace
StringBuffers from the top of the stack.
Copy link

@pdxrunner pdxrunner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Darren, thank you for your contribution.

The product code changes look OK, but per the project guidelines, the tests for your changes should be incorporated into the project as unit tests - same package declaration as the changed file but put the test class under the 'geode-core/src/testjava' directory. (See the Geode wiki: https://cwiki.apache.org/confluence/display/GEODE/Criteria+for+Code+Submissions and https://cwiki.apache.org/confluence/display/GEODE/Writing+tests.) In particular, note the distinction between unit tests, integration tests (one JVM, but touches filesystem or other external resource), and distributed unit tests (multiple JVMs). If you mock your test XMLs, add the tests as unit tests (preferred), otherwise if you create test files to read in then they would be Integration tests.

Modified existing `testCacheXmlParserWithSimplePool()` to be able to
close the created cache, otherwise there will be an
IllegalStateException thrown about an "incomplete shutdown of a previous
cache".
@darrenfoong
Copy link
Contributor Author

I just realised I'll need to unset the property to prevent any side effects in the other tests; working on it now.

@darrenfoong
Copy link
Contributor Author

I've added code to unset/clear the temporarily-set system properties for testing.

Thank you Kenneth for your feedback.

@jaredjstewart
Copy link
Contributor

Hi Darren,

It looks like xercesImpl may need to be declared as a testCompile dependency rather than testRuntime in case people are building with a JDK which does not include Xerxes. I also think it would be prudent to solicit feedback from the community via dev@geode.apache.org before we add this library, since I know that Xerces can sometimes be troublesome. (See e.g. https://stackoverflow.com/questions/11677572/dealing-with-xerces-hell-in-java-maven)

Thank you,
Jared Stewart

@darrenfoong
Copy link
Contributor Author

Hi Jared, thank you for your feedback.

The initial use case that I was thinking of involved a user wanting to:

  • use Geode with another JDK (which doesn't have the com.sun.org.apache... Xerces implementation that the Oracle JDK uses), or
  • use Geode in an application where he/she wants to use the Apache Xerces implementation (which will be a dependency of the application) and sets the system property javax.xml.parsers.SAXParserFactory to org.apache.xerces.jaxp.SAXParserFactoryImpl.

In these cases xercesImpl is part of the environment (JDK, app) so I chose to use xercesImpl at only test runtime and "load" it via System.setProperty() in my unit tests.

I don't see why it's needed at test compile time and I don't really understand your point about people building with (and I presume, for) a JDK that doesn't include Xerces: in that case, shouldn't xercesImpl be a dependency for main too?

I do symphatise with Xerces hell though!

Copy link
Contributor

@jaredjstewart jaredjstewart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you may be right about using testRuntime for xercesImpl instead of testCompile. The first time I tried to run the test with your PR I think I forgot to refresh Gradle first, which led me to believe testRuntime was not sufficient.

I still think it would be a good idea to email dev@geode.apache.org to ensure that the community has no objections to adding this dependency.

while (!stack.empty()) {
Object o = stack.peek();
if (o instanceof StringBuffer
&& ((StringBuffer) o).toString().replaceAll("\\s", "").equals("")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think StringUtils.isBlank( (StringBuffer o).toString()) might be simpler here as well as in endElement.


testCacheXmlParserWithSimplePool();

if (prevParserFactory != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cleanup of system properties can be made simpler by using the RestoreSystemProperties JUnit rule. All you need to do is add this member variable to your test class:

  public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();

(For an example, see LocatorLauncherTest.)

@darrenfoong
Copy link
Contributor Author

Thanks Jared! Will find time to make the changes and get feedback on the mailing list.

Remove previous setup code for `parse()`, which is already called in
`CacheFactory.create()`.

The end result is a simpler `CacheFactory.create()` call. The path of
`cache.xml` is different because the `GemFireCacheImpl` class is the one
that retrieves `cache.xml`, but its package is
`org.apache.geode.internal.cache` and not
`org.apache.geode.internal.cache.xmlcache` (where this class resides).

Hence the additional `xmlcache` is needed for `GemFireCacheImpl` to find
the resource for the unit test.
Copy link
Contributor

@kirklund kirklund left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@asfgit asfgit closed this in f289179 Aug 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants