Excluding the transitive com.google.http-client:google-http-client:1.42.1 child dependency from included dependencies in Gradle - google-app-engine

I'm facing this weird java.lang.NoSuchMethodError in my Groovy project, and I have it pretty much down to that there's some transitive grand-child dependency, that is being included by multiple child dependencies (below is just the compileClasspath):
compileClasspath - Compile classpath for source set 'main'.
+--- com.github.javafaker:javafaker:1.0.2
| +--- org.apache.commons:commons-lang3:3.5
| +--- org.yaml:snakeyaml:1.23
| \--- com.github.mifmif:generex:1.0.2
| \--- dk.brics.automaton:automaton:1.11-8
+--- com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0
| \--- com.google.api-client:google-api-client:2.0.0
| +--- com.google.oauth-client:google-oauth-client:1.34.1
| | _+--- com.google.http-client:google-http-client:1.42.0 -> 1.42.1_
| | | +--- org.apache.httpcomponents:httpclient:4.5.13
| | | | +--- org.apache.httpcomponents:httpcore:4.4.13 -> 4.4.15
| | | | +--- commons-logging:commons-logging:1.2
| | | | \--- commons-codec:commons-codec:1.11
| | | +--- org.apache.httpcomponents:httpcore:4.4.15
| | | +--- com.google.code.findbugs:jsr305:3.0.2
| | | +--- com.google.guava:guava:30.1.1-android -> 31.1-jre
| | | | +--- com.google.guava:failureaccess:1.0.1
| | | | +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
| | | | +--- com.google.code.findbugs:jsr305:3.0.2
| | | | +--- org.checkerframework:checker-qual:3.12.0
| | | | +--- com.google.errorprone:error_prone_annotations:2.11.0
| | | | \--- com.google.j2objc:j2objc-annotations:1.3
| | | +--- com.google.j2objc:j2objc-annotations:1.3
| | | +--- io.opencensus:opencensus-api:0.31.1
| | | | \--- io.grpc:grpc-context:1.27.2
| | | \--- io.opencensus:opencensus-contrib-http-util:0.31.1
| | | +--- io.opencensus:opencensus-api:0.31.1 (*)
| | | \--- com.google.guava:guava:29.0-android -> 31.1-jre (*)
| | +--- com.google.http-client:google-http-client-gson:1.42.0 -> 1.42.1
| | | _+--- com.google.http-client:google-http-client:1.42.1 (*)_
| | | \--- com.google.code.gson:gson:2.9.0
| | \--- com.google.guava:guava:31.1-android -> 31.1-jre (*)
| +--- com.google.http-client:google-http-client-gson:1.42.1 (*)
| +--- com.google.guava:guava:31.1-jre (*)
| +--- com.google.http-client:google-http-client-apache-v2:1.42.1
| | _+--- com.google.http-client:google-http-client:1.42.1 (*)_
| | +--- org.apache.httpcomponents:httpclient:4.5.13 (*)
| | \--- org.apache.httpcomponents:httpcore:4.4.15
| +--- org.apache.httpcomponents:httpcore:4.4.15
| +--- org.apache.httpcomponents:httpclient:4.5.13 (*)
| \--- _com.google.http-client:google-http-client:1.42.1 (*)_
\--- org.codehaus.groovy:groovy-all:2.4.7
My build.gradle looks like this :
plugins {
id 'java'
id "com.katalon.gradle-plugin" version "0.1.1"
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.github.javafaker:javafaker:1.0.2'
implementation 'com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0'
}
Notice that there are multiple instances of this com.google.http-client:google-http-client:1.42.1 across different child dependencies!
I try to get rid of those transitive dependencies with:
configurations.all {
exclude group: 'com.google.http-client', module: 'google-http-client'
}
but then my compileClasspath looks like:
compileClasspath - Compile classpath for source set 'main'.
+--- com.github.javafaker:javafaker:1.0.2
| +--- org.apache.commons:commons-lang3:3.5
| +--- org.yaml:snakeyaml:1.23
| \--- com.github.mifmif:generex:1.0.2
| \--- dk.brics.automaton:automaton:1.11-8
+--- com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0
| \--- com.google.api-client:google-api-client:2.0.0
| +--- com.google.oauth-client:google-oauth-client:1.34.1
| | +--- com.google.http-client:google-http-client-gson:1.42.0 -> 1.42.1
| | | \--- com.google.code.gson:gson:2.9.0
| | \--- com.google.guava:guava:31.1-android -> 31.1-jre
| | +--- com.google.guava:failureaccess:1.0.1
| | +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
| | +--- com.google.code.findbugs:jsr305:3.0.2
| | +--- org.checkerframework:checker-qual:3.12.0
| | +--- com.google.errorprone:error_prone_annotations:2.11.0
| | \--- com.google.j2objc:j2objc-annotations:1.3
| +--- com.google.http-client:google-http-client-gson:1.42.1 (*)
| +--- com.google.guava:guava:31.1-jre (*)
| +--- com.google.http-client:google-http-client-apache-v2:1.42.1
| | +--- org.apache.httpcomponents:httpclient:4.5.13
| | | +--- org.apache.httpcomponents:httpcore:4.4.13 -> 4.4.15
| | | +--- commons-logging:commons-logging:1.2
| | | \--- commons-codec:commons-codec:1.11
| | \--- org.apache.httpcomponents:httpcore:4.4.15
| +--- org.apache.httpcomponents:httpcore:4.4.15
| \--- org.apache.httpcomponents:httpclient:4.5.13 (*)
\--- org.codehaus.groovy:groovy-all:2.4.7
There's NO instances of the com.google.http-client:google-http-client:1.42.1 ANYWHERE! It also doesn't resolve the Error.
java.lang.NoSuchMethodError: com.google.api.client.http.HttpTransport.isMtls()Z
at com.google.api.services.gmail.Gmail$Builder.chooseEndpoint(Gmail.java:11179)
at com.google.api.services.gmail.Gmail$Builder.<init>(Gmail.java:11212)
at com.signaturemd.utils.GmailQuickstart.GetLabels(GmailQuickstart.groovy:72)
at com.signaturemd.utils.GmailQuickstart$GetLabels.call(Unknown Source)
at SMDEmailUtils.run(SMDEmailUtils:6)
What should I do to make sure that only ONE instance of com.google.http-client:google-http-client:1.42.1 is in the project, and that this Error goes away?

When you are saying "multiple instances" of the dependency what do you mean? I would assume you are confused by seeing multiple versions of the same dependency in the dependency graph.
But that has nothing to do with how many physical instances (jar files) will be packed up into the resulting artifact of your own. There is always just one physical instance of any dependency in the resulting artifact managed by either Gradle or Maven. However, if there are multiple different versions of the same dependency in the dependency graph they both choose the most appropriate version of that one physical instance as they see fit:
Gradle
In case of conflict, Gradle by default uses the newest of conflicting versions.
Maven
Dependency mediation - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.
And you can override that version. So, in case of Gradle, instead of configuration.all { exclude {...} } that excludes the dependency from everywhere you can try configuring the resolutionStrategy like this:
configuration.all {
resolutionStrategy {
force "com.google.http-client:google-http-client:1.42.1"
}
}
That would (snippet from the doc below):
Allows forcing certain versions of dependencies, including transitive dependencies
This is what you need as per your original question. Like obviously, you don't want to exclude the dependency but rather you want to enforce the specific version of it.
For more info you can refer to the official documentation:
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html#org.gradle.api.artifacts.ResolutionStrategy:force(java.lang.Object[])

Related

Getting NoSuchMethodException when migrating to endpoints framework version 2

I am getting NoSuchMethod exception when I try to migrate existing endpoints version 1.o code to endpoints framework version 2.
I am using the guide in this url here
https://cloud.google.com/endpoints/docs/frameworks/java/migrating
but I keep getting this error message
java.lang.NoSuchMethodException: sampe-package-path.EndpointClassEndpoint.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
at com.google.api.server.spi.EndpointsServlet.createService(EndpointsServlet.java:143)
at com.google.api.server.spi.EndpointsServlet.createSystemService(EndpointsServlet.java:128)
at com.google.api.server.spi.EndpointsServlet.init(EndpointsServlet.java:57)
I have used the exact web.xml in the example on migrating here
https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/appengine/endpoints-frameworks-v2/migration-example/src/main/webapp/WEB-INF/web.xml
Could there be something I am missing out?
In the Endpoint class above I just have a single parameter constructor like this
#Inject
public EndpointClassEndpoint(EndpointClassContext context) {
this.context = context;
}
I would appreciate any help to resolve this error
Adding the complete web.xml as requested by #saiyr
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>
somethpath.bootstrap.CompanyOneGSCL
</listener-class>
</listener>
<listener>
<listener-class>
somethpath.bootstrap.listeners.ObjectifyLoaderContextListener
</listener-class>
</listener>
<!-- GUICE -->
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/_ah/spi/*</url-pattern>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ENDPOINTS -->
<servlet>
<servlet-name>EndpointsServlet</servlet-name>
<servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>
somethpath.endpoints.PraxoneV1API,
somethpath.endpoints.EmpresasEndpoint,
csomethpath.endpoints.AdministrationEndpoint,
somethpath.endpoints.CentrosEndpoint,
somethpath.endpoints.CargosEndpoint,
somethpath.endpoints.TrabajadoresEndpoint,
somethpath.endpoints.EvaluacionEndpoint,
somethpath.endpoints.EpidemiologiaEndpoint,
somethpath.endpoints.ActividadEndpoint,
somethpath.endpoints.TrabajadoresOpenEndpoint,
somethpath.endpoints.AsyncJobEndpoint
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>EndpointsServlet</servlet-name>
<url-pattern>/_ah/api/*</url-pattern>
</servlet-mapping>
<!-- MonitorCompanyTask Servlet -->
<servlet>
<servlet-name>MonitorCompanyTask</servlet-name>
<servlet-class>reducted-path.MonitorCompanyTask</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MonitorCompanyTask</servlet-name>
<url-pattern>/tasks/v1/monitor/company</url-pattern>
</servlet-mapping>
<!--servlet>
<servlet-name>appstats</servlet-name>
<servlet-class>com.google.appengine.tools.appstats.AppstatsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>appstats</servlet-name>
<url-pattern>/appstats/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>appstats</web-resource-name>
<url-pattern>/appstats/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint -->
<!-- All app must use HTTPS -->
<security-constraint>
<web-resource-collection>
<web-resource-name>any</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
When I do gradle dependencies this is what I get
+--- com.google.endpoints:endpoints-framework:2.0.8
| +--- javax.servlet:servlet-api:2.5
| +--- com.google.guava:guava:19.0 -> 20.0
| +--- com.fasterxml.jackson.core:jackson-annotations:2.6.4 -> 2.9.0
| +--- com.fasterxml.jackson.core:jackson-core:2.6.4 -> 2.9.6
| +--- com.fasterxml.jackson.core:jackson-databind:2.6.4 -> 2.9.6
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.9.0
| | \--- com.fasterxml.jackson.core:jackson-core:2.9.6
| +--- com.google.appengine:appengine-api-1.0-sdk:1.9.49 -> 1.9.64
| +--- com.google.http-client:google-http-client-jackson2:1.21.0 -> 1.23.0
| | +--- com.google.http-client:google-http-client:1.23.0
| | | +--- com.google.code.findbugs:jsr305:1.3.9 -> 3.0.1
| | | \--- org.apache.httpcomponents:httpclient:4.0.1 -> 4.5.2
| | | +--- org.apache.httpcomponents:httpcore:4.4.4
| | | +--- commons-logging:commons-logging:1.2
| | | \--- commons-codec:commons-codec:1.9 -> 1.10
| | \--- com.fasterxml.jackson.core:jackson-core:2.1.3 -> 2.9.6
| +--- com.google.api-client:google-api-client:1.21.0 -> 1.23.0
| | +--- com.google.oauth-client:google-oauth-client:1.23.0
| | | +--- com.google.http-client:google-http-client:1.23.0 (*)
| | | \--- com.google.code.findbugs:jsr305:1.3.9 -> 3.0.1
| | +--- com.google.http-client:google-http-client-jackson2:1.23.0 (*)
| | \--- com.google.guava:guava-jdk5:17.0
| +--- com.google.api-client:google-api-client-appengine:1.21.0 -> 1.23.0
| | +--- com.google.oauth-client:google-oauth-client-appengine:1.23.0
| | | +--- com.google.http-client:google-http-client-appengine:1.23.0
| | | | \--- com.google.http-client:google-http-client:1.23.0 (*)
| | | +--- com.google.oauth-client:google-oauth-client:1.23.0 (*)
| | | \--- com.google.oauth-client:google-oauth-client-servlet:1.23.0
| | | +--- com.google.oauth-client:google-oauth-client:1.23.0 (*)
| | | +--- com.google.http-client:google-http-client-jdo:1.23.0
| | | | +--- com.google.http-client:google-http-client:1.23.0 (*)
| | | | \--- javax.jdo:jdo2-api:2.3-eb
| | | | \--- javax.transaction:transaction-api:1.1
| | | \--- javax.jdo:jdo2-api:2.3-eb (*)
| | +--- com.google.api-client:google-api-client:1.23.0 (*)
| | +--- com.google.api-client:google-api-client-servlet:1.23.0
| | | +--- com.google.oauth-client:google-oauth-client-servlet:1.23.0 (*)
| | | +--- com.google.api-client:google-api-client:1.23.0 (*)
| | | +--- javax.servlet:servlet-api:2.5
| | | \--- javax.jdo:jdo2-api:2.3-eb (*)
| | \--- com.google.http-client:google-http-client-appengine:1.23.0 (*)
| +--- com.google.code.findbugs:jsr305:3.0.1
| +--- io.swagger:swagger-models:1.5.9
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.4.5 -> 2.9.0
| | +--- org.slf4j:slf4j-api:1.6.3 -> 1.7.21
| | \--- io.swagger:swagger-annotations:1.5.9
| +--- io.swagger:swagger-core:1.5.9
| | +--- org.apache.commons:commons-lang3:3.2.1
| | +--- org.slf4j:slf4j-api:1.6.3 -> 1.7.21
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.4.5 -> 2.9.0
| | +--- com.fasterxml.jackson.core:jackson-databind:2.4.5 -> 2.9.6 (*)
| | +--- com.fasterxml.jackson.datatype:jackson-datatype-joda:2.4.5
| | | +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0 -> 2.9.0
| | | +--- com.fasterxml.jackson.core:jackson-core:2.4.5 -> 2.9.6
| | | +--- com.fasterxml.jackson.core:jackson-databind:2.4.5 -> 2.9.6 (*)
| | | \--- joda-time:joda-time:2.2 -> 2.9.4
| | +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.4.5
| | | +--- com.fasterxml.jackson.core:jackson-core:2.4.5 -> 2.9.6
| | | \--- org.yaml:snakeyaml:1.12
| | +--- io.swagger:swagger-models:1.5.9 (*)
| | +--- com.google.guava:guava:18.0 -> 20.0
| | \--- javax.validation:validation-api:1.1.0.Final
| \--- org.slf4j:slf4j-nop:1.7.21
| \--- org.slf4j:slf4j-api:1.7.21
I can see com.google.appengine:appengine-api-1.0-sdk:1.9.49 -> 1.9.64 and others that look like endpoints 1 dependencies, are these fine here?
Since you are trying to use Guice, you need to configure Endpoints like in the migration guide. Note that some of the lines in the Guice module are not relevant unless you're using API management. The last line where configureEndpoints is called is the most important. Then add the module to your Guice configuration.

How to Structure React and bootstrap-react projects?

How to Structure React and bootstrap-react projects?
Here you can see my folder structure. Is this the best practice?
|-COPYRIGHT.md
|-dist
| |-app
| |-bundle.js
| |-bundle.js.map
|
|-index.html
|-.git
|-.gitignore
|- node_modules
|-package.js
|-README.md
|
|-src
| |-app
| | |-components
| | | |-Footer.js
| | | |-Header.js
| | | |-Home.js
| | |
| | |-index.js
| |
| |-css
| | |-bootstrap.min.css
| | |-footer.css
| | |-header.css
| | |-styles.css
| |
| |-fonts
| | |-glyphicons-halflings
| |
| |-images
| | |-logo.jpg
| |
| |-index.html
| |
| |-js
| | |-es5-sham.min.js
| | |-es5-shim.min.js
| | |-html5shiv.min.js
| | |-html5shiv-printshiv.min.js
| | |-react-bootstrap.js
| | |-react-bootstrap.min.js
|
|-webpack.config.js
In the next step I would make my homepage multilingual. I need three languages de, en, fr.
I would like separate the languages like this.
How to change the languages in the Navbar?
Which of you has something already programmed and sends me a link of his Github repository? How do I program the routes correctly? In Footer I'll use three images as a flag for switching languages. But to be recognized by the browser language principle.
|-Languanges
|-de
| |-Impressum.js
|
|-en
| |-Imprint.js
|
|-fr
| |-empreinte.js

Gradle build : wrong jars in exploded app while gradle reports correct runtime classpath dependencies

When I list the runtime dependencies for my webapp (uses AppEngine), all looks fine:
gradle sourcing-server:dependencies --configuration runtime
koen#desktop:~/workspace/criteriabuilder$ gradle sourcing-server:dependencies --configuration runtime
Incremental java compilation is an incubating feature.
:sourcing-server:dependencies
------------------------------------------------------------
Project :sourcing-server
------------------------------------------------------------
runtime - Runtime classpath for source set 'main'.
+--- project :sourcing-shared
| +--- org.hibernate:hibernate-validator:4.2.0.Final
| | +--- javax.validation:validation-api:1.0.0.GA
| | \--- org.slf4j:slf4j-api:1.6.1
| +--- com.google.gwt:gwt-servlet:2.7.0
| +--- com.googlecode.objectify:objectify:4.0rc1
| | +--- com.google.guava:guava:14.0.1
| | +--- com.google.appengine:appengine-api-1.0-sdk:1.7.6 -> 1.9.26
| | \--- com.google.appengine:appengine-api-labs:1.7.6 -> 1.9.26
| \--- com.fasterxml.jackson.core:jackson-annotations:2.4.4
+--- javax.servlet:servlet-api:2.5
+--- org.restlet.gae:org.restlet:2.3.1
| \--- com.google.appengine:appengine-api-1.0-sdk:1.9.15 -> 1.9.26
+--- org.restlet.gae:org.restlet.ext.jackson:2.3.1
| +--- com.fasterxml.jackson.core:jackson-core:2.4.4
| +--- com.fasterxml.jackson.core:jackson-annotations:2.4.4
| +--- com.fasterxml.jackson.core:jackson-databind:2.4.4
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0 -> 2.4.4
| | \--- com.fasterxml.jackson.core:jackson-core:2.4.4
| +--- com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.4.4
| | +--- com.fasterxml.jackson.core:jackson-core:2.4.4
| | \--- com.fasterxml.jackson.core:jackson-databind:2.4.4 (*)
| +--- com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.4.4
| | \--- com.fasterxml.jackson.core:jackson-core:2.4.4
| +--- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.4.4
| | +--- com.fasterxml.jackson.core:jackson-core:2.4.4
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0 -> 2.4.4
| | +--- com.fasterxml.jackson.core:jackson-databind:2.4.4 (*)
| | +--- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.4.4
| | | +--- com.fasterxml.jackson.core:jackson-core:2.4.4
| | | \--- com.fasterxml.jackson.core:jackson-databind:2.4.4 (*)
| | \--- org.codehaus.woodstox:stax2-api:3.1.4
| +--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.4.4
| | +--- com.fasterxml.jackson.core:jackson-core:2.4.4
| | \--- org.yaml:snakeyaml:1.12 -> 1.13
| +--- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.4.4 (*)
| +--- com.fasterxml.jackson.module:jackson-module-jsonSchema:2.4.4
| | +--- com.fasterxml.jackson.core:jackson-annotations:2.4.0 -> 2.4.4
| | +--- com.fasterxml.jackson.core:jackson-core:2.4.4
| | \--- com.fasterxml.jackson.core:jackson-databind:2.4.4 (*)
| +--- org.codehaus.woodstox:woodstox-core-asl:4.3.0
| | +--- javax.xml.stream:stax-api:1.0-2
| | \--- org.codehaus.woodstox:stax2-api:3.1.4
| +--- org.codehaus.woodstox:stax2-api:3.1.4
| +--- org.yaml:snakeyaml:1.13
| \--- org.restlet.gae:org.restlet:2.3.1 (*)
+--- org.restlet.gae:org.restlet.ext.gae:2.3.1
| +--- com.google.appengine:appengine-api-1.0-sdk:1.9.15 -> 1.9.26
| \--- org.restlet.gae:org.restlet:2.3.1 (*)
+--- org.restlet.gae:org.restlet.ext.gwt:2.3.1
| +--- com.google.gwt:gwt-servlet:2.3.0 -> 2.7.0
| +--- org.restlet.gae:org.restlet:2.3.1 (*)
| \--- org.restlet.gae:org.restlet.ext.servlet:2.3.1
| \--- org.restlet.gae:org.restlet:2.3.1 (*)
+--- org.restlet.gae:org.restlet.ext.json:2.3.1
| +--- org.restlet.gae:org.restlet.lib.org.json:2.0
| \--- org.restlet.gae:org.restlet:2.3.1 (*)
+--- org.restlet.gae:org.restlet.ext.gson:2.3.1
| +--- com.google.code.gson:gson:2.3.1
| +--- joda-time:joda-time:2.3
| \--- org.restlet.gae:org.restlet:2.3.1 (*)
+--- org.apache.commons:commons-lang3:3.1
+--- com.google.api-client:google-api-client-appengine:1.20.0
| +--- com.google.oauth-client:google-oauth-client-appengine:1.20.0
| | +--- com.google.http-client:google-http-client-appengine:1.20.0
| | | \--- com.google.http-client:google-http-client:1.20.0
| | | +--- com.google.code.findbugs:jsr305:1.3.9
| | | \--- org.apache.httpcomponents:httpclient:4.0.1
| | | +--- org.apache.httpcomponents:httpcore:4.0.1
| | | +--- commons-logging:commons-logging:1.1.1
| | | \--- commons-codec:commons-codec:1.3
| | +--- com.google.oauth-client:google-oauth-client:1.20.0
| | | +--- com.google.http-client:google-http-client:1.20.0 (*)
| | | \--- com.google.code.findbugs:jsr305:1.3.9
| | +--- com.google.oauth-client:google-oauth-client-servlet:1.20.0
| | | +--- com.google.oauth-client:google-oauth-client:1.20.0 (*)
| | | +--- com.google.http-client:google-http-client-jdo:1.20.0
| | | | +--- com.google.http-client:google-http-client:1.20.0 (*)
| | | | \--- javax.jdo:jdo2-api:2.3-eb
| | | | \--- javax.transaction:transaction-api:1.1
| | | +--- javax.servlet:servlet-api:2.5
| | | \--- javax.jdo:jdo2-api:2.3-eb (*)
| | \--- javax.servlet:servlet-api:2.5
| +--- com.google.api-client:google-api-client:1.20.0
| | +--- com.google.oauth-client:google-oauth-client:1.20.0 (*)
| | +--- com.google.http-client:google-http-client-jackson2:1.20.0
| | | +--- com.google.http-client:google-http-client:1.20.0 (*)
| | | \--- com.fasterxml.jackson.core:jackson-core:2.1.3 -> 2.4.4
| | \--- com.google.guava:guava-jdk5:13.0
| +--- com.google.api-client:google-api-client-servlet:1.20.0
| | +--- com.google.oauth-client:google-oauth-client-servlet:1.20.0 (*)
| | +--- com.google.api-client:google-api-client:1.20.0 (*)
| | +--- javax.servlet:servlet-api:2.5
| | \--- javax.jdo:jdo2-api:2.3-eb (*)
| \--- com.google.http-client:google-http-client-appengine:1.20.0 (*)
+--- com.google.apis:google-api-services-oauth2:v2-rev96-1.20.0
| \--- com.google.api-client:google-api-client:1.20.0 (*)
\--- org.slf4j:slf4j-jdk14:1.6.1
\--- org.slf4j:slf4j-api:1.6.1
(*) - dependencies omitted (listed previously)
BUILD SUCCESSFUL
But the jars in build/exploded-app/WEB-INF/lib are very different (and so I run into version problems!).
I have a mixup of GAE libraries 1.9.25 and 1.9.26
For the Google API libraries, there is version 1.16.0 and 1.20.0 present.
And a problem with jackson-core.
How can this result be different from the output of above command?
koen#desktop:~/workspace/criteriabuilder$ ls server/build/exploded-app/WEB-INF/lib/
appengine-api-1.0-sdk-1.9.26.jar jackson-annotations-2.4.4.jar
appengine-api-1.0-sdk-1.9.5.jar jackson-core-2.1.3.jar
appengine-api-labs-1.9.26.jar jackson-core-2.4.4.jar
appengine-api-labs.jar jackson-core-asl-1.9.11.jar
appengine-endpoints-deps.jar jackson-databind-2.4.4.jar
appengine-endpoints.jar jackson-dataformat-csv-2.4.4.jar
appengine-jsr107cache-1.9.5.jar jackson-dataformat-smile-2.4.4.jar
appengine-remote-api.jar jackson-dataformat-xml-2.4.4.jar
commons-codec-1.3.jar jackson-dataformat-yaml-2.4.4.jar
commons-lang3-3.1.jar jackson-mapper-asl-1.9.3.jar
commons-logging-1.1.1.jar jackson-module-jaxb-annotations-2.4.4.jar
google-api-client-1.16.0-rc.jar jackson-module-jsonSchema-2.4.4.jar
google-api-client-1.20.0.jar jdo2-api-2.3-eb.jar
google-api-client-appengine-1.16.0-rc.jar joda-time-2.3.jar
google-api-client-appengine-1.20.0.jar jsr107cache-1.1.jar
google-api-client-servlet-1.16.0-rc.jar jsr305-1.3.9.jar
google-api-client-servlet-1.20.0.jar objectify-4.0rc1.jar
google-api-services-oauth2-v2-rev69-1.16.0-rc.jar org.json.jar
google-api-services-oauth2-v2-rev96-1.20.0.jar org.restlet-2.3.1.jar
google-http-client-1.16.0-rc.jar org.restlet.ext.gae-2.3.1.jar
google-http-client-1.20.0.jar org.restlet.ext.gae.jar
google-http-client-appengine-1.16.0-rc.jar org.restlet.ext.gson-2.3.1.jar
google-http-client-appengine-1.20.0.jar org.restlet.ext.gwt-2.3.1.jar
google-http-client-gson-1.16.0-rc.jar org.restlet.ext.gwt.jar
google-http-client-jackson-1.16.0-rc.jar org.restlet.ext.jackson-2.3.1.jar
google-http-client-jackson2-1.16.0-rc.jar org.restlet.ext.jackson.jar
google-http-client-jackson2-1.20.0.jar org.restlet.ext.json-2.3.1.jar
google-http-client-jdo-1.20.0.jar org.restlet.ext.json.jar
google-oauth-client-1.16.0-rc.jar org.restlet.ext.net.jar
google-oauth-client-1.20.0.jar org.restlet.ext.servlet-2.3.1.jar
google-oauth-client-appengine-1.16.0-rc.jar org.restlet.ext.servlet.jar
google-oauth-client-appengine-1.20.0.jar org.restlet.jar
google-oauth-client-servlet-1.16.0-rc.jar org.restlet.lib.org.json-2.0.jar
google-oauth-client-servlet-1.20.0.jar servlet-api-2.5.jar
gson-2.1.jar slf4j-api-1.6.1.jar
gson-2.3.1.jar slf4j-jdk14-1.6.1.jar
guava-14.0.1.jar snakeyaml-1.13.jar
guava-14.0-rc2.jar sourcing-shared-2015-01.jar
guava-jdk5-13.0.jar stax2-api-3.1.4.jar
gwt-servlet-2.7.0.jar stax-api-1.0-2.jar
gwt-servlet.jar transaction-api-1.1.jar
hibernate-validator-4.2.0.Final.jar validation-api-1.0.0.GA.jar
httpclient-4.0.1.jar woodstox-core-asl-4.3.0.jar
httpcore-4.0.1.jar xpp3-1.1.4c.jar
Well, there were jar files left in src/main/webapp/WEB-INF/lib from the pre-Gradle setup of the project.
These older libraries get copied over during build.

How to show several loops and doing stuff in it in a sequence diagramm?

I want to show what my UserControl/Control is doing when I plug a list of data in it, what happens when the user press certain keys, selecting text etc...
I feel somehow a sequence diagramm is not really suited for showing several loops and doing stuff within the loops.
Am I wrong or how can I cope with that case?
If you are talking about a loop, then you have a series of operations that take place for all elements in the loop.
I would model the operations done in the loop as a sequence diagram by itself, if the operation in the loop are fairly complex.
I don't think we can have rules of thumb here, but when the process with the loop itself is complex, and the loop is relatively less complex, we can have them in a single sequence diagram.
If the process that has the loop is not very complex, but the loop is complex, then I would draw a sequence diagram for the operations of the loop and have a note that this entire sequence is called by a loop.
You can also have both sequence diagrams if needed.
Update:
We have to add some notes to the diagram because it is not straightforward to denote a "condition" in a sequence diagram.
The validate is part is something like
do validation
if validation succeeds
proceed to next (business or other) logic
if validation fails
feedback to user (or some other logic)
+----+ +----+ +----------------+ +----------------+
|User| | UI | | Your Validator | | Business Logic |
+----+ +----+ +----------------+ +----------------+
| select | | |
|--------------->| doValidation | |
| |------------------>|----+ |
| | | | Validate |
| | |<---+ |
| | | |
| | | (validation fails: |
| | Validation Fail | feedback to client) |
| |<------------------| |
| | | |
| | | |
| | | (validation succeeds: |
| | | proceed to |
| | | business logic) |
| | | |
| | | someLogic |
| | |----------------------->|
| | | |
UPDATE 2
Why use sequence diagram in a case as mine?
Because you still have to show the sequence of operations, and the developer still needs this information for coding :-)
With UML, as you probably already know, nothing is imposed. You are at your freedom to denote something in some fashion, provided your team also understands it the way you intended. These notes are also helpful.
I should have mentioned this before, some use an "option" fragment to denote a if else. This is more or less a note (I see it this way) but is perhaps more evident. I use them only when both the IF and the ELSE parts are both complex.
+----+ +----+ +----------------+ +----------------+
|User| | UI | | UI - Backend | | Busines Logic |
+----+ +----+ +----------------+ +----------------+
| Add Record | | |
|--------------->| doinsertOrUpdate | |
| |------------------>| |
| | | exists(record) |
| | |----------------------->|
| | | |
____|________________|___________________|________________________|__________
|[Record exists] | | | |
| | | | Get Record | |
| | | |----------------------->| |
| | | | | |
| | | |--------+ | |
| | | | | Set UI Values | |
| | | |<-------+ | |
| | | | | |
| | | | Update Record | |
| | | |----------------------->| |
| | | | | |
| | | Send Message | | |
| | |<------------------| | |
| | | "Record found, | | |
| | | Updated" | | |
|___|________________|___________________|________________________|_________|
| | | |
| | | |
______|________________|___________________|________________________|_________
| [Record does not | | | |
| exist] | | | |
| | | |--------+ | |
| | | | | Generate | |
| | | | | Seqeuence | |
| | | |<-------+ | |
| | | | | |
| | | | Create New Record | |
| | | |----------------------->| |
| | | Send Message | | |
| | |<------------------| | |
| | | "New Record | | |
| | | Created" | | |
|_____|________________|___________________|________________________|_________|
| | | |
| | | |
| | | |
See this for an example using an alt block.

How do I find the most “Naturally" direct route using A-star (A*)

I have implemented the A* algorithm in AS3 and it works great except for one thing.
Often the resulting path does not take the most “natural” or smooth route to the target.
In my environment the object can move diagonally as inexpensively as it can move horizontally or vertically.
Here is a very simple example; the start point is marked by the S, and the end (or finish) point by the F.
| | | | | | | | | |
|S| | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
|F| | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
As you can see, during the 1st round of finding, nodes [0,2], [1,2], [2,2] will all be added to the list of possible node as they all have a score of N.
The issue I’m having comes at the next point when I’m trying to decide which node to proceed with. In the example above I am using possibleNodes[0] to choose the next node. If I change this to possibleNodes[possibleNodes.length-1] I get the following path.
| | | | | | | | | |
|S| | | | | | | | |
| |x| | | | | | | |
| | |x| | | | | | |
| | | |x| | | | | |
| | |x| | | | | | |
| |x| | | | | | | |
|F| | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
And then with possibleNextNodes[Math.round(possibleNextNodes.length / 2)-1]
| | | | | | | | | |
|S| | | | | | | | |
|x| | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
x| | | | | | | | | |
|F| | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
All these paths have the same cost as they all contain the same number of steps but, in this situation, the most sensible path would be as follows...
| | | | | | | | | |
|S| | | | | | | | |
|x| | | | | | | | |
|x| | | | | | | | |
|x| | | | | | | | |
|x| | | | | | | | |
|x| | | | | | | | |
|F| | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
Is there a formally accepted method of making the path appear more sensible rather than just mathematically correct?
You need to add a Tie-breaker to your heuristic function. The problem here is that there are many paths with the same costs.
For a simple Tie-breaker that favors the direct route you can use the cross-product. I.e. if S is the start and E is the end, and X is the current position in the algorithm, you could calculate the cross-products of S-E and X-E and add a penalty to the heuristic the further it deviates from 0 (= the direct route).
In code:
dx1 = current.x - goal.x
dy1 = current.y - goal.y
dx2 = start.x - goal.x
dy2 = start.y - goal.y
cross = abs(dx1*dy2 - dx2*dy1)
heuristic += cross*0.001
See also http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#S12, which is an excellent tutorial about A* in general.
If you want paths that look natural, you need to make sure that your costs correspond to the length on a cartesian coordinate system. That means the cost of moving diagonally should be sqrt(2) times the cost of moving vertically or horizontally.
You can add 'control effort' to the cost calculations for each square. The actor will try not to turn or change direction too much as that will add a cost to the path:
http://angryee.blogspot.com/2009/03/better-pathfinding.html
If I remember correctly, the trick to this is to add an extra parameter to the cost function (for every step between adjacent nodes, or squares in your case) that penalises turns slightly more than normal (for example, having a relative cost of greater than sqrt(2) for digonal moves). Now, there's probably a fine line between smoothing out the path and actually decreasing the optimality of the route (elongating it), however, and you're not going to be able to avoid this in any way. There's a certain trade-off you'll need to discover specific to your own application, and this can only really be achieved by testing.
There was an article on a game dev site, I believe, that detailed exactly how this could be done, but I can't seem to find it at the moment. Have a play around with your cost function anyway and see what results you get - I'm pretty sure that's the way to go.
What is more 'sensible'? Straighter? You need to quantify it properly if the algorithm is going to do anything about it.
Since moving diagonally is as inexpensive as moving horizontally/vertically, all the paths are equivalent according to all the criterion available to A*. If you want a more 'sensible' path, you need to tell the algorithm that some paths are more desirable than others, effectively weighting horizontal/vertical as 'better' than diagonal. As far as I can see, that would be altering the parameters of your environment.

Resources