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

Cannot connect to Nextcloud #53

Open
penguineer opened this issue Jun 20, 2022 · 13 comments
Open

Cannot connect to Nextcloud #53

penguineer opened this issue Jun 20, 2022 · 13 comments
Assignees

Comments

@penguineer
Copy link

I am trying to connect to NextCloud, but run into some trouble.

Setup

I'm using these dependencies:

    <dependency>
      <groupId>org.mnode.ical4j</groupId>
      <artifactId>ical4j</artifactId>
      <version>3.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.mnode.ical4j</groupId>
      <artifactId>ical4j-connector</artifactId>
      <version>2.0.0-alpha1</version>
    </dependency>

My test code looks like this:

        CalDavCalendarStore store = new CalDavCalendarStore(
                "CalMixer",
                URI.create("https://nc.example.com/remote.php/dav").toURL(),
                PathResolver.Defaults.ICAL_SERVER);
        store.connect("alice", "password".toCharArray());

        for (CalDavCalendarCollection col : store.getCollections()) {
            System.out.println(col.getDisplayName());
        }

The initial login (connect) works fine.

Problems

Then two things happen:

1) Path resolution

  • store.getCollections does a call to CalDavCalendarStore.findCalendarHomeSet with the propfindUri == "https://nc.example.com/remote.php/dav/principals/users/alice/"
  • Two steps further into the call stack, we end up at DefaultDavClient.resolvePath with the same path. Here the repositoryPath is added, transforming the correct path into /remote.php/dav/https://nc.example.com/remote.php/dav/principals/users/alice/ - not what we want.
  • I can change path in the debugger, so that the initial path will be returned as /remote.php/dav/principals/alice. I do not really understand what this method is supposed to do when a complete path is already provided.

With my change, the path following call works out.

2) Class cast exception

  • A bit further down the line in CalDavCalendarStore.findCalendarHomeSet is the following line:
return (String) props.get(CalDavPropertyName.CALENDAR_HOME_SET).getValue();
  • With the result from my (modified) call (see 1) I get a class cast exception:
Exception in thread "main" java.lang.ClassCastException: class com.sun.org.apache.xerces.internal.dom.DeferredElementNSImpl cannot be cast to class java.lang.String (com.sun.org.apache.xerces.internal.dom.DeferredElementNSImpl is in module java.xml of loader 'bootstrap'; java.lang.String is in module java.base of loader 'bootstrap')
	at net.fortuna.ical4j.connector.dav.CalDavCalendarStore.findCalendarHomeSet(CalDavCalendarStore.java:181)
	at net.fortuna.ical4j.connector.dav.CalDavCalendarStore.findCalendarHomeSet(CalDavCalendarStore.java:161)
	at net.fortuna.ical4j.connector.dav.CalDavCalendarStore.getCollections(CalDavCalendarStore.java:198)
	at Testframe.main(Testframe.java:82)

What to do?

At this point I am not sure how to proceed:

  • Is this a bug in the code? Other projects are using it tho.
  • Is there an error in my setup or PathResolver? What are the right settings for NextCloud?

Unfortunately I cannot find any example code. I appreciate that the project is still under development, but at this point I cannot see how things are supposed to be and how to proceed.

Any help woudl be greatly appreciated!

@benfortuna
Copy link
Member

benfortuna commented Jun 21, 2022

Hi, thanks for the feedback. Yes, I think it's a bug and at this stage I don't recommend using version 2.0.0-alpha1 as it had a major refactor and is probably still broken at this stage.

You may have more success with release 1.0.5, but let me know if you see any other issues and I'll try to address them.

https://search.maven.org/artifact/org.mnode.ical4j/ical4j-connector/1.0.5/jar

I hope to release a new alpha build for 2.0.0 soon to fix some of these issues.

P.S. And the specific error you are seeing is because DefaultDavClient is now expecting a path (not the fully qualified URI) to a resource, but CalDavCalendarStore is still sending the URI. I will make the required fixes shortly.

@penguineer
Copy link
Author

Thank you for your quick reply!

I have tried 1.0.5 and stumbled over another problem:

My URL is of the form https://nc.example.com/remote.php/dav. When I use PathResolver.ICAL_SERVER I get the correct paths for NextCloud (at least as far as I could get with testing).

However, in DavClient.DavClient the path portion of this URI is ignored. The principal call then goes to /principals/users/alice instead of /remote.php/dav/principals/users/alice. If I manually correct the URI parameters in the DavClient constructor, login works but I get more errors further down the line when the initial URI is completely used.

How can I help to fix this?
My preference is working with version two, if the change will come, as this makes my new code more durable.

@benfortuna
Copy link
Member

The hardest (most time-consuming) part at the moment is testing, so I think providing these bug reports is the best way to contribute. If you want to have a look at the code for v2 you can check out this branch:

https://github.com/ical4j/ical4j-connector/tree/feature/refactor

You'll note I am also splitting into a multi-module project so the coordinates for the next release will change, but hopefully the API won't change too much.

I'll try to push out a new v2 release in a few days.

@penguineer
Copy link
Author

The new structure looks good and the API (code examples in the README 🥳 ) seems much more accessible.

Unfortunately I could not manage to build the library locally (missing dependencies?):

→ make build
./gradlew build

> Configure project :
Project :ical4j-connector-api => no module-info.java found
Project :ical4j-connector-dav => no module-info.java found
Project :ical4j-connector-jcr => no module-info.java found

> Task :ical4j-connector-api:compileJava FAILED
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateCalendarCommand.java:7: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateCalendarCommand.java:9: error: package CommandLine does not exist
@CommandLine.Command(name = "create-calendar", description = "Persist calendar object from input data")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateCalendarCollectionCommand.java:5: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateCalendarCollectionCommand.java:7: error: package CommandLine does not exist
@CommandLine.Command(name = "create-calendar-collection", description = "Create a new calendar collection")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/UpdateVCardCommand.java:7: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/UpdateVCardCommand.java:9: error: package CommandLine does not exist
@CommandLine.Command(name = "update-card", description = "Persist vCard object from input data")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteCalendarCollectionCommand.java:5: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteCalendarCollectionCommand.java:7: error: package CommandLine does not exist
@CommandLine.Command(name = "delete-calendar-collection", description = "Remove a vCard collection")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetCalendarCommand.java:6: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetCalendarCommand.java:8: error: package CommandLine does not exist
@CommandLine.Command(name = "get-calendar", description = "Retrieve a calendar object with specified UID")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteVCardCommand.java:6: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteVCardCommand.java:8: error: package CommandLine does not exist
@CommandLine.Command(name = "delete-card", description = "Delete vCard objects with specified UID")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteCalendarCommand.java:7: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteCalendarCommand.java:9: error: package CommandLine does not exist
@CommandLine.Command(name = "delete-calendar", description = "Delete calendar objects with specified UID")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateVCardCollectionCommand.java:5: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateVCardCollectionCommand.java:7: error: package CommandLine does not exist
@CommandLine.Command(name = "create-card-collection", description = "Create a new vCard collection")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetVCardCommand.java:7: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetVCardCommand.java:9: error: package CommandLine does not exist
@CommandLine.Command(name = "get-card", description = "Retrieve a vCard object with specified UID")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteVCardCollectionCommand.java:5: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/DeleteVCardCollectionCommand.java:7: error: package CommandLine does not exist
@CommandLine.Command(name = "delete-card-collection", description = "Remove a vCard collection")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetVCardCollectionCommand.java:5: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetVCardCollectionCommand.java:7: error: package CommandLine does not exist
@CommandLine.Command(name = "get-card-collection", description = "Retrieve a vCard collection")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/UpdateCalendarCommand.java:7: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/UpdateCalendarCommand.java:9: error: package CommandLine does not exist
@CommandLine.Command(name = "update-calendar", description = "Update calendar object matching input parameters")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetCalendarCollectionCommand.java:5: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/GetCalendarCollectionCommand.java:7: error: package CommandLine does not exist
@CommandLine.Command(name = "get-calendar-collection", description = "Retrieve a calendar collection")
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateVCardCommand.java:7: error: package picocli does not exist
import picocli.CommandLine;
^
/home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/command/CreateVCardCommand.java:9: error: package CommandLine does not exist
@CommandLine.Command(name = "create-card", description = "Persist vCard object from input data")
^
Note: /home/tux/Projekte/ical4j-connector/ical4j-connector-api/src/main/java/org/ical4j/connector/local/LocalCalendarCollection.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
28 errors

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':ical4j-connector-api:compileJava'.
> Compilation failed; see the compiler error output for details.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 532ms
1 actionable task: 1 executed
make: *** [Makefile:22: build] Error 1

Intellij, however, could build. (not a gradle expert here)

Build instructions in the README would be very helpful to verify that I am doing the right thing.

@benfortuna
Copy link
Member

Yup sorry I have a few uncommitted changes locally. I've just added the dependencies that should help it to build.

I have a couple more changes coming based on your earlier feedback, just trying to validate/test the change before committing it.

@benfortuna benfortuna self-assigned this Jun 25, 2022
@penguineer
Copy link
Author

penguineer commented Jun 25, 2022

Thank you!

The current branch ends up like this:

→ make build
./gradlew build

> Configure project :
Project :ical4j-connector-api => no module-info.java found
Project :ical4j-connector-dav => no module-info.java found
Project :ical4j-connector-jcr => no module-info.java found

> Task :ical4j-connector-dav:compileTestGroovy FAILED
startup failed:
General error during conversion: PermittedSubclasses requires ASM9

java.lang.UnsupportedOperationException: PermittedSubclasses requires ASM9
at groovyjarjarasm.asm.ClassVisitor.visitPermittedSubclass(ClassVisitor.java:266)
at groovyjarjarasm.asm.ClassReader.accept(ClassReader.java:683)
at groovyjarjarasm.asm.ClassReader.accept(ClassReader.java:401)
at org.codehaus.groovy.ast.decompiled.AsmDecompiler.parseClass(AsmDecompiler.java:81)
at org.codehaus.groovy.control.ClassNodeResolver.findDecompiled(ClassNodeResolver.java:251)
at org.codehaus.groovy.control.ClassNodeResolver.tryAsLoaderClassOrScript(ClassNodeResolver.java:189)
at org.codehaus.groovy.control.ClassNodeResolver.findClassNode(ClassNodeResolver.java:169)
at org.codehaus.groovy.control.ClassNodeResolver.resolveName(ClassNodeResolver.java:125)
at org.codehaus.groovy.ast.decompiled.AsmReferenceResolver.resolveClassNullable(AsmReferenceResolver.java:57)
at org.codehaus.groovy.ast.decompiled.AsmReferenceResolver.resolveClass(AsmReferenceResolver.java:44)
at org.codehaus.groovy.ast.decompiled.TypeSignatureParser.visitEnd(TypeSignatureParser.java:110)
at groovyjarjarasm.asm.signature.SignatureReader.parseType(SignatureReader.java:206)
at groovyjarjarasm.asm.signature.SignatureReader.parseType(SignatureReader.java:235)
at groovyjarjarasm.asm.signature.SignatureReader.accept(SignatureReader.java:114)
at org.codehaus.groovy.ast.decompiled.MemberSignatureParser.createMethodNode(MemberSignatureParser.java:97)
at org.codehaus.groovy.ast.decompiled.DecompiledClassNode.lambda$createMethodNode$1(DecompiledClassNode.java:230)
at org.codehaus.groovy.ast.decompiled.DecompiledClassNode.createMethodNode(DecompiledClassNode.java:236)
at org.codehaus.groovy.ast.decompiled.DecompiledClassNode.lazyInitMembers(DecompiledClassNode.java:203)
at org.codehaus.groovy.ast.decompiled.DecompiledClassNode.getDeclaredField(DecompiledClassNode.java:116)
at org.apache.groovy.ast.tools.ClassNodeUtils.getField(ClassNodeUtils.java:412)
at org.apache.groovy.ast.tools.ClassNodeUtils.getField(ClassNodeUtils.java:417)
at org.codehaus.groovy.control.StaticImportVisitor.findStaticField(StaticImportVisitor.java:552)
at org.codehaus.groovy.control.StaticImportVisitor.findStaticFieldOrPropAccessorImportFromModule(StaticImportVisitor.java:436)
at org.codehaus.groovy.control.StaticImportVisitor.transformVariableExpression(StaticImportVisitor.java:223)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:124)
at org.codehaus.groovy.ast.expr.Expression.transformExpressions(Expression.java:49)
at org.codehaus.groovy.ast.expr.ArgumentListExpression.transformExpression(ArgumentListExpression.java:66)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:142)
at org.codehaus.groovy.control.StaticImportVisitor.transformMethodCallExpression(StaticImportVisitor.java:248)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:133)
at org.codehaus.groovy.control.StaticImportVisitor.transformMethodCallExpression(StaticImportVisitor.java:246)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:133)
at org.codehaus.groovy.control.StaticImportVisitor.transformMethodCallExpression(StaticImportVisitor.java:246)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:133)
at org.codehaus.groovy.ast.expr.Expression.transformExpressions(Expression.java:49)
at org.codehaus.groovy.ast.expr.ArgumentListExpression.transformExpression(ArgumentListExpression.java:66)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:142)
at org.codehaus.groovy.control.StaticImportVisitor.transformMethodCallExpression(StaticImportVisitor.java:248)
at org.codehaus.groovy.control.StaticImportVisitor.transform(StaticImportVisitor.java:133)
at org.codehaus.groovy.ast.ClassCodeExpressionTransformer.visitExpressionStatement(ClassCodeExpressionTransformer.java:108)
at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40)
at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:86)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:164)
at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:69)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:138)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:111)
at org.codehaus.groovy.ast.ClassCodeExpressionTransformer.visitConstructorOrMethod(ClassCodeExpressionTransformer.java:66)
at org.codehaus.groovy.control.StaticImportVisitor.visitConstructorOrMethod(StaticImportVisitor.java:108)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitMethod(ClassCodeVisitorSupport.java:106)
at org.codehaus.groovy.ast.ClassNode.visitMethods(ClassNode.java:1099)
at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1092)
at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:52)
at org.codehaus.groovy.control.CompilationUnit.lambda$addPhaseOperations$3(CompilationUnit.java:209)
at org.codehaus.groovy.control.CompilationUnit$IPrimaryClassNodeOperation.doPhaseOperation(CompilationUnit.java:942)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:671)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:635)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:610)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:270)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:64)
at org.gradle.api.internal.tasks.compile.GroovyCompilerFactory$DaemonSideCompiler.execute(GroovyCompilerFactory.java:97)
at org.gradle.api.internal.tasks.compile.GroovyCompilerFactory$DaemonSideCompiler.execute(GroovyCompilerFactory.java:76)
at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkAction.execute(AbstractDaemonCompiler.java:135)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:49)
at org.gradle.workers.internal.IsolatedClassloaderWorker.run(IsolatedClassloaderWorker.java:30)
at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:87)
at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:56)
at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:138)
at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:135)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)

1 error


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':ical4j-connector-dav:compileTestGroovy'.
> Compilation failed; see the compiler error output for details.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
16 actionable tasks: 1 executed, 15 up-to-date
make: *** [Makefile:22: build] Error 1

This seems to be a JDK17 thing?

I have:

→ java --version
openjdk 17.0.2 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-Debian-1deb11u1)
OpenJDK 64-Bit Server VM (build 17.0.2+8-Debian-1deb11u1, mixed mode, sharing)

@benfortuna
Copy link
Member

Ok, I am still running jdk11 locally. I've just added multiple JVMs to the build, and disabled module support for now (for java 8 compatibility).

Let me know if it still fails locally with jdk17 and I'll investigate further.

@penguineer
Copy link
Author

Sadly it still doesn't work.
I have opened #54 for the build problem.

@penguineer
Copy link
Author

Thanks to your hint in #54 I got a running test frame:

        DavClientFactory clientFactory = new DavClientFactory().withPreemptiveAuth(true).withFollowRedirects(true);

        CalDavSupport caldav = clientFactory.newInstance(
                "https://nextcloud.exampe.com/remote.php/dav/"
        );
        DefaultDavClient client = (DefaultDavClient) caldav;
        List<SupportedFeature> features = client.begin("alice", "secret".toCharArray());

        // /remote.php/caldav/calendars/alice/personal/
        Calendar calendar = caldav.getCalendar("alice/personal");

The calendar call goes to /remote.php/dav/alice/personal but should to go /remote.php/caldav/calendars/alice/personal/.

I guess some kind of custom path resolution is needed?

(Also I have to cast to the dav client and call begin, otherwise the calendar call fails with a missing HTTP client)

@benfortuna
Copy link
Member

benfortuna commented Jun 27, 2022

Yes, the DefaultDavClient has a fixed base path to the server (repository path), and any requests will combine the repository path with the request path. In this example you have:

So to have the request go to /remote.php/caldav/calendars/alice/personal/ you need:

The authentication does seem a bit clunky, I've just added support for credentials to the DavClientFactory, e.g:

Credentials credentials = new UsernamePasswordCredentials(username, password);

CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(new AuthScope(host, port), credentials);

DavClientFactory clientFactory = new DavClientFactory().withPreemptiveAuth(true).withFollowRedirects(true)
    .withCredentialsProvider(credentialsProvider);

CalDavSupport caldav = clientFactory.newInstance("https://nextcloud.exampe.com/remote.php/dav/");

If you don't supply a credentials provider it will initialise the http client without credentials.

@penguineer
Copy link
Author

The new Auth API makes it much more accessible. :) I am using

credentialsProvider.setCredentials(AuthScope.ANY, credentials);

to save myself from extracting host/port information.

I could not set the proper repository path before, because then the principal for authentication would not be found. This problem seems to be solved and I am accessing a calendar path that does not lead to an error during PROPFIND.

However, the next call is a GET /remote.php/caldav/calendars/alice/personal with the result 501 and the following output in my browser:

Sabre\DAV\Exception\NotImplemented There was no plugin in the system that was willing to handle this GET method. Enable the Browser plugin to get a better result here.
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
<s:exception>Sabre\DAV\Exception\NotImplemented</s:exception>
<s:message>There was no plugin in the system that was willing to handle this GET method. Enable the Browser plugin to get a better result here.</s:message>
...
</d:error>

CalDAV should be working because I am using DAVx to synchronize with my phone and extracted the URL from these calls. However, DAVx only does the PROPFIND call.

@penguineer
Copy link
Author

The new Auth API makes it much more accessible.

A thought regarding that:
The AuthScope can be extracted from the URL provided in DavClientFactory, but requires the Credentials to be provided there instead. This might make sense, since the Credentials and the URL belong together?

@benfortuna
Copy link
Member

benfortuna commented Jun 29, 2022

A GET request should be the simplest one, as I don't think there is anything specific to DAV for this. Unless there are some required headers we are missing.. (or the path is wrong).

I'll check for any examples in the Nextcloud documentation to confirm.

Also, you may be aware that DAVx has an extensive list of configurations for different CalDAV providers:

https://www.davx5.com/tested-with/nextcloud

I think I will be using this as a basis for validating the ical4j-connector implementation.

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

No branches or pull requests

2 participants