pledbrook / lazybones Goto Github PK
View Code? Open in Web Editor NEWA simple project creation tool that uses packaged project templates.
License: Apache License 2.0
A simple project creation tool that uses packaged project templates.
License: Apache License 2.0
bintray is great, but it would be nice to pull templates from private repositories.
So what happens if the post processing script fails? Should we delete the files and have the user try again? Or should we do nothing? What about user error, aka wrong inputs / no inputs? Should we not do anything and say it is up to the author to make an error proof lazybones.groovy script?
Just putting this in here so we remember to do this. Should hold off until 0.4 is released since this is not supported yet.
Lazybones should process the template files as they are extracted, replacing leading tabs with the user-preferred indent and setting the appropriate encoding.
By default, template files should be UTF-8 and have tabs for indent.
I was thinking it would be nice to automatically do a git init and stage the initial project for committing.
lazybones create dropwizard 0.1 newprojectdir --git-repository
would be the syntax and we would add the ability for the commands to have sub commands by adding a List subcommands to the AbstractCommand class. In the constructor you could add new subcommands that would then be atomically executed after the command was finished.
We could use jgit or shell out to the git process to create the repo.
We should probably use Vagrant for at least testing on Windows if not other platforms. I don't know what this will entail yet, but hopefully it's just a simple Vagrant configuration that we need to set up.
Rather than simply rename the method, we should keep the filterFiles()
and have it delegate to processTemplates()
after printing a deprecation warning. The warning should mention the last version of Lazybones for which filterFiles()
existed but wasn't deprecated.
If lazybones is to become more than a very basic utility, it needs some functional tests. This should involve executing the app as an external process and capturing its output. It will also need a URL for picking up packaged templates (probably from the file system) and a REST service that mocks BinTray.
The tests should verify command output, unpacked directory structure, and permissions on the unpacked files. With post install Groovy scripts, the tests will also have to ensure that those are run, which will probably mean testing the contents of some of the files.
This harness should also be usable by developers of templates so that they can test those too.
Any templates that use the post install script are going to be specific to a lazybones version. Or at least they will need to be installed by something at 0.4 or later. I can see templates using features that are introduced in later versions as well. We should be able to specify which version of lazybones can be used to create a template.
Automatically use latest version of a template if version argument is omitted
I have been seeing lazybones get a little love in twitter land. Maybe we should move this to its own github organization space. Maybe come up with a cool logo?
Simplest approach may be to have the build generate a properties file containing the project metadata. Gradle has this task:
task versionProperties(type: WriteVersionProperties) {
propertiesFile = new File(sourceSets.main.classesDir, GradleVersion.FILE_NAME)
}
The app then just needs to read the file from the classpath using getResourceAsStream()
.
if lazybones were embeddable, it could be used in other build tools.... such as gradle or grails. Relates to #62
Would you mind adding this link to the template?
http://dl.bintray.com/ingorichter/lazybones-templates/groovy-extended-app-template
Thank you.
An info command should pull the description of the package and the release notes for the specified (or latest) version from BinTray and display them, along with the package name, the list of versions, the owner, where to raise issues, and where to find the documentation.
The package description and release notes should also display "find out more" links to the relevant URLs if they are specified.
These are taking too long, and it's only going to get worse as more tests are added. As usual, there are two main vectors of attack:
Not sure we'll get very far with the first of these unless there is some problem causing Lazybones to execute slowly in some tests, perhaps because of network timeouts, or heap thrashing (unlikely). It might be worth considering running them in a single JVM, but then it's not being run quite the same way as a user runs it.
Due to the amount of IO involved, parallelisation should help a lot. The tricky part is ensuring that no tests try to access the same part of the filesystem at the same time and that the Betamax server is shared between all test cases. In addition, if there is any recording to tapes, the tests can't be run parallelised since there could be contended writes.
Steps:
lazybones create ratpack-lite 0.1 my-rat-app
cd my-rat-app
gradle run
Error:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring root project 'my-rat-app'.
> Could not resolve all dependencies for configuration ':classpath'.
> Could not resolve org.ratpack-framework.netty:ratpack-gradle:0.7.0-SNAPSHOT.
Required by:
:my-rat-app:unspecified
> Unable to load Maven meta-data from https://oss.sonatype.org/content/repositories/snapshots/org/ratpack-framework/netty/ratpack-gradle/0.7.0-SNAPSHOT/maven-metadata.xml.
> Could not GET 'https://oss.sonatype.org/content/repositories/snapshots/org/ratpack-framework/netty/ratpack-gradle/0.7.0-SNAPSHOT/maven-metadata.xml'.
> peer not authenticated
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.
BUILD FAILED
Seems to be nagging about some peer not authenticated error. Any clues?
As discussed in issue #40, Lazybones would benefit from supporting multiple template engines for the processTemplates()
method. It will continue to have Groovy's SimpleTemplateEngine
as the default, but allow post-install scripts to pull in other templating libraries via @Grab
.
The idea is to use Groovy's Template
and TemplateEngine
interfaces from with Lazybones, since the abstraction is already there. To confirm this is viable, one or more people need to do a spike with alternative template implementations, such as Handlebars.
The integration test framework should be made available for template authors so that they can easily write tests.
The current build works, but it's not that easy to maintain. For a start, the templates should really be kept separate from the application code. A refactoring of the build would also help with issue #29: creating a plugin for packaging and publishing templates. That build logic is currently embedded in the existing build.gradle
.
I suggest a simple multi-project build with:
When the user executes the create
command, Lazybones should check whether the target directory exists and whether it's empty or not. If it's not empty, then Lazybones should ask the user whether he or she really wants to install the template in that directory.
A few other options might be:
--force
argument to bypass the question and just do itβ’--non-interactive
option to automatically abort if the directory isn't empty?Maybe we can use Spring's AntPatternMatcher while not depending on spring. The class has only one other spring dependency, which is the interface that it implements. Maybe just copy, paste and repurpose.
When running lazybones info lazybones-project
, I get
Exception in thread "main" groovy.lang.GroovyRuntimeException: Could not find matching constructor for: uk.co.cacoethes.lazybones.PackageInfo(java.lang.String, wslite.json.JSONObject$Null)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1550)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1404)
at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:46)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:194)
at uk.co.cacoethes.lazybones.BintrayPackageSource.fetchPackageInfo(BintrayPackageSource.groovy:64)
at uk.co.cacoethes.lazybones.commands.InfoCommand$_execute_closure1.doCall(InfoCommand.groovy:39)
...
If you apply the lazybones script to a file that uses a gstring in it, the lazybones script will always attempt to iterpolate that string, even if it is part of the normal source of the file.
For example, I have a build.gradle file with the following:
task migrate(dependsOn: 'shadow', group: 'dropwizard', description: "Run migrations using the dev configuration") << {
javaexec {
main = '-jar'
args = ["${shadow.shadowJar.getPath()}", 'db', 'migrate', 'dev_config.yml']
}
}
If the lazybones.groovy script includes filterFiles("build.gradle", filterProperties)
then the SimpleTemplateEngine will try to interpolate "${shadow.shadowJar.getPath()}" resulting in an invalid build.gradle.
I have been working around this so far, but given that we're going to be templating groovy and gradle files a lot, I think SimpleTemplateEngine isn't going to work for us long term. What about using something like handlebars? There is a simple java implementation that I have used for server side templating.
Lazybones could do with a logo for the website, Twitter, etc.
I noticed while creating a bad lazybones.groovy script that the PlainFormatter will only print the message of a log and is incapable of printing a stacktrace. The PlainFormatter should inspect the LogRecord to see if there is an associated thrown
and print it in addition to the message.
Have people used http://commons.apache.org/proper/commons-cli/ before for this? I've used it a bit and liked it but I don't know of many other options.
We should create a simple website for Lazybones with:
This is listed in #2 as a feature. Figure this is involved enough that it deserves its own issue.
These should trigger the help
command.
see discussion in #11
We should create dedicated Lazybones organisations on GitHub and BinTray, preferably before a 1.0 release. Of course we have to be careful of the disruption this might cause.
I saw hints that grails 3 was going to support project templates. Is this really necessary if they have lazybones? If they do feel the need to support it in grails, can we make lazybones an api instead of just a cli tool?
If you do a fresh clone of lazybones and try to do anything it complains that repo.url
is not set from line 84 of app.gradle
. You can workaround this issue by adding appropriate variables to gradle.properties
. I imagine we should check for the existence of the variables in the uploadDist
task and throw an error if the task is called and they don't exist.
Several (if not all) lazybones integrated tests fail on windows 7 using cygwin. This makes it very difficult to effectively test new features and OS compatibility.
It's possible to install templates that are cached locally when offline, but other commands result in ugly stacktraces. Lazybones should really detect network issues and simply report the error without a stacktrace.
It should be possible to simply catch the various network-related exceptions from URL
and RESTClient
. It would be nice to have a "You can't use this command because you're offline", but how would we determine whether the user is offline or not?
One option may be to hit a couple of major sites via their IP addresses and domains (e.g. Google and Bing searches) on the assumption that the likelihood of both being down at the same time while Bintray et al. being available is close to zero. But of course these checks add to execution time of the command. Is it worth it?
hi and thanks for the work.
im getting this error when i run ./gradlew run
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:configureRun
:run
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/ratpackframework/groovy/bootstrap/RatpackMain : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: org.ratpackframework.groovy.bootstrap.RatpackMain. Program will exit.
:run FAILED
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':run'.
Process 'command '/usr/lib/jvm/java-6-openjdk-i386/bin/java'' finished with non-zero exit value 1
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 5.36 secs
any idea? and thanks from now
As a command line tool, it would be useful to have diagnostic information available through a simple command line option (such as --verbose
). The standard way to do this is through a logger.
The easiest way to do this is probably via Groovy's @log annotation, which uses the JDK's built-in logging framework (hence no extra dependencies).
If a template is cached locally, Lazybones should just use that without connecting to the internet. This will also enable the use of template packages that have been installed locally but aren't available in a public repository.
It seems that any default value passed to the ask()
method in post-install scripts is ignored, resulting in a value of null
for the corresponding property.
The post-install script is a dangerous beast, which could wreak havoc on a user's system. We can rely for a time on verifying the safety of various templates before including them in the main repository, but if the number of templates increases significantly, we just can't keep that up.
The post-install script should really run in a limited sandbox by default unless the user explicitly authorises the script to run with unlimited permissions. Ideally the script would have full filesystem access to the project directory, but nowhere else. Perhaps global read permissions would be OK, but even that might be too much.
Anyway, it's clear this issue needs to be researched and a general security policy decided upon before it's implemented.
Could we use git / github directly for pulling templates? It has tags for versioning and most people who use this tool, if not all, will also use git. There is also a java library to communicate with it (although I have never used it).
If we already have a server to communicate with bintray, why not have one to register git based templates like bower? It will be a lot more work I suppose, but will definitely add to its cool factor and adoption.
This affects how ask
works. If there is a default / cli value, that will be used without any interaction. If a value is required but there is no default value, an error will be thrown indicating that either a cli property must be provided or non-interactive
mode is not supported.
The non-interactive
flag should also be accessible in the script. Obviously, by default, non-interactive
is set to false
Some project structures require a little more than just downloading files (maven, grails, etc.). If there was a root level script (maybe called lazybones.groovy?), post processing could adjust the files appropriately. Maybe it could even receive arguments for further customization.
I think AntBuilder
is only used for file filtering. We will have to replicate ant pattern matching to get rid of it.
Using ~/.groovy
for lazybones stuff is not really expected behaviour, and as @scottfrederick points out, Groovy is just an implementation detail.
Steps:
lazybones list
Error:
Available templates:
Exception in thread "main" wslite.rest.RESTClientException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
at org.codehau s.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite. java:102)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:202)
at wslite.rest.RESTClient.executeMethod(RESTClient.groovy:81)
at wslite.rest.RESTClient.this$2$executeMethod(RESTClient.groovy)
at wslite.rest.RESTClient$this$2$executeMethod$0.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
at wslite.rest.RESTClient.executeMethod(RESTClient.groovy:61)
at wslite.rest.RESTClient.this$2$executeMethod(RESTClient.groovy)
at wslite.rest.RESTClient$this$2$executeMethod.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:145)
at wslite.rest.RESTClient.get(RESTClient.groovy:45)
at wslite.rest.RESTClient$get.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at uk.co.cacoethes.lazybones.BintrayPackageSource.listPackageNames(BintrayPackageSource.groovy:34)
at uk.co.cacoethes.lazybones.LazybonesMain.listCommand(LazybonesMain.groovy:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1085)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:952)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
at groovy.lang.Closure.call(Closure.java:411)
at groovy.lang.Closure.call(Closure.java:427)
at uk.co.cacoethes.lazybones.LazybonesMain.main(LazybonesMain.groovy:36)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun. security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1491)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1485)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.MethodMetaProperty$GetBeanMethodMetaProperty.getProperty(MethodMetaProperty. java:73)
at org.codehaus.groovy.runtime.callsite.GetEffectivePojoPropertySite.getProperty(GetEffectivePojoPropertySite.java:61)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
at wslite.http.HTTPClient.buildResponse(HTTPClient.groovy:152)
at wslite.http.HTTPClient.this$2$buildResponse(HTTPClient.groovy)
at wslite.http.HTTPClient$this$2$buildResponse.callCurrent(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:145)
at wslite.http.HTTPClient.execute(HTTPClient.groovy:60)
at wslite.http.HTTPClient$execute.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at wslite.rest.RESTClient.executeMethod(RESTClient.groovy:77)
... 30 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun. security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1764)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:958)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1203)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1230)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1214)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.MethodMetaProperty$GetBeanMethodMetaProperty.getProperty(MethodMetaProperty. java:73)
at org.codehaus.groovy.runtime.callsite.GetEffectivePojoPropertySite.getProperty(GetEffectivePojoPropertySite.java:61)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227)
at wslite.http.HTTPClient.execute(HTTPClient.groovy:55)
... 35 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath. SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
... 56 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 62 more
The same works fine on my mac.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.